Report an unroutable classifier cell as no_route - #11
Merged
Merged
Conversation
/classify returned invalid_request when none of the offered models appeared in the classifier routing cell. That condition is not a caller mistake. The request is well formed and the router simply has nothing it can serve, which is what no_route means. /route already reports the same condition that way, and routing_table.route documents the rule the service follows, RoutingError for invalid requests and NoRouteError when no supported candidate remains. Classification was the one path that drifted from it. The asymmetry forced callers to branch on the endpoint to recognise a routine outcome. A client that handled no_route correctly for /route would misreport the identical situation from /classify as a contract violation, pointing operators at a bug that does not exist. Raise NoRouteError for the empty intersection so both endpoints share one taxonomy. Malformed input keeps invalid_request, including a missing authored user message and an omitted effort for a model that requires one. The CLI now exits 3 rather than 2 for this case, matching route. Add a contract case covering a non-empty pool whose models are all unrecognised. The existing case offered no models at all, so the ordinary production shape of this failure went unrecorded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
/classifyreturnedinvalid_requestwhen none of the offered models appeared in the classifier routing cell. That is not a caller mistake. The request is well formed and the router simply has nothing it can serve, which is exactly whatno_routemeans./routealready reports the same condition asno_route, andRoutingTable.routedocuments the rule the service follows:Classification was the one path that had drifted from that rule.
Why it matters
The asymmetry forced callers to branch on the endpoint to recognise a routine outcome. A client that handled
no_routecorrectly for/routewould misreport the identical situation from/classifyas a contract violation, sending operators to look for a bug that does not exist.This was found from the consuming side. A caller offering a model pool with no overlap against the router's tables saw "the router rejected the classify request" when the honest answer was "nothing here fits". Fixing it here means callers need no local mirror of the router's catalogue to produce a correct diagnosis, and the router stays the single authority on what it can serve.
Change
create_classification_planraisesNoRouteErrorinstead ofClassificationErrorfor an empty intersection.Malformed input is unchanged and still
invalid_request, covering a missing authored user message and an omitted effort for a model that requires one. Those are genuine caller errors with something to fix.The CLI exits 3 rather than 2 for this case, which matches
routeand required no CLI change sinceNoRouteErroris already handled ahead of theValueErrorcatch.Contract coverage
The existing
classify-no-supported-choicecase offeredmodels: []. The ordinary production shape of this failure is a non-empty pool whose entries are all unrecognised, and that went unrecorded, which is how the inconsistency survived. Addedclassify-unrecognised-choicesto cover it.openapi.yamlnow documents theno_routeoutcome on/classify, mirroring the wording already used for/route.Version
Bumped to 0.1.1 across
pyproject.toml,__init__.py,openapi.yamland theDockerfileARG, with the recorded discovery fixture updated to match. This is a behaviour change to a published HTTP contract, so it should not ship under the released 0.1.0.Validation
pytestexcluding docker: 409 passedruff format --check,ruff check,ty check: cleanno_route. A pool with partial overlap still returns 200 and ranks only the recognised entries.Docker and release-marked suites are left to CI. They could not run in my sandbox because
uvcannot reach PyPI from here.