chore(routing): remove public noop and passthrough route types - #148
Conversation
|
WalkthroughThe change removes ChangesLegacy route removal
Estimated code review effort: 4 (Complex) | ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
tests/readme/conftest.py (1)
40-86: 📐 Maintainability & Code Quality | 🔵 TrivialDuplicate of
tests/getting_started/conftest.py's_MockOpenAIServer.Identical implementation to
tests/getting_started/conftest.pylines 39-92.See consolidated comment for the full cross-file fix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/readme/conftest.py` around lines 40 - 86, Remove the duplicate _MockOpenAIServer implementation from tests/readme/conftest.py and reuse the existing fixture or shared definition from tests/getting_started/conftest.py, preserving the README tests’ current server behavior and base_url interface.tests/getting_started/test_getting_started.py (1)
161-180: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPrefer a real type hint over
object+# type: ignore.Import
_MockOpenAIServerunderTYPE_CHECKINGand type the fixture param directly instead ofobject/# type: ignore[attr-defined].As per coding guidelines: "Use Python 3.12 syntax and conventions, including `X | Y` union types, type hints throughout, sorted imports, and `TYPE_CHECKING` guards for circular imports."♻️ Proposed fix
+from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from tests.getting_started.conftest import _MockOpenAIServer + -def model_routes_yaml(tmp_path: Path, local_mock_openai_server: object) -> Path: +def model_routes_yaml(tmp_path: Path, local_mock_openai_server: "_MockOpenAIServer") -> Path: # Same shape as the guide's Step 3 YAML (defaults + a single named route), # but a `type: model` route pointed at a local in-process mock OpenAI # server so the lifecycle test serves a real chain fully offline. - base_url = local_mock_openai_server.base_url # type: ignore[attr-defined] + base_url = local_mock_openai_server.base_url🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/getting_started/test_getting_started.py` around lines 161 - 180, Update model_routes_yaml to type local_mock_openai_server as _MockOpenAIServer, importing that symbol under a TYPE_CHECKING guard with the existing imports kept sorted. Remove the object annotation and the # type: ignore[attr-defined] comment.Source: Coding guidelines
tests/getting_started/conftest.py (2)
39-92: 📐 Maintainability & Code Quality | 🔵 TrivialMock OpenAI server implementation duplicated verbatim in
tests/readme/conftest.py.
_MockOpenAIServerand_CANNED_COMPLETIONhere are byte-for-byte identical to the ones intests/readme/conftest.py(lines 40-86). Consider extracting to a shared test helper module.See consolidated comment for the full cross-file fix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/getting_started/conftest.py` around lines 39 - 92, Extract the duplicated _MockOpenAIServer and _CANNED_COMPLETION definitions from tests/getting_started/conftest.py and tests/readme/conftest.py into a shared test helper module. Update both conftest files to import and reuse those shared symbols, preserving the existing local_mock_openai_server fixture behavior.
39-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the duplicated hermetic mock-upstream fixture into a shared helper.
tests/getting_started/conftest.pyandtests/readme/conftest.pyimplement byte-for-byte identical_MockOpenAIServer/_CANNED_COMPLETIONclasses and an identical_hermetic_buildmonkeypatch pattern. The shared_hermetic_buildalso reconstructsPassthroughProfileConfig(api_key="test-key", base_url=upstream.base_url)from scratch rather than overriding fields on the real_selfinstance, silently dropping any other fields (e.g.model) the guide/README snippet may set on its passthrough config.
tests/getting_started/conftest.py#L39-L131: move_MockOpenAIServer/_CANNED_COMPLETIONto a shared test helper module (mirroringtests/_chain_test_helpers.py's pattern) and, in_hermetic_build, override fields on_self(e.g. viadataclasses.replaceifPassthroughProfileConfigis a dataclass) instead of constructing a brand-new instance.tests/readme/conftest.py#L40-L120: import the same shared helper and apply the same_self-preserving fix to_hermetic_build.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/getting_started/conftest.py` around lines 39 - 131, Extract the duplicated _CANNED_COMPLETION and _MockOpenAIServer from tests/getting_started/conftest.py#L39-131 and tests/readme/conftest.py#L40-120 into a shared test helper, then import and reuse them in both fixtures. Update _hermetic_build at both sites to preserve each _self PassthroughProfileConfig while overriding only api_key and base_url, using dataclasses.replace or the appropriate equivalent; do not reconstruct the config so fields such as model remain intact.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_route_bundle.py`:
- Around line 173-176: Update test_empty_route_mapping_is_rejected to assert
that build_route_bundle_table raises RouteBundleConfigError with match="missing
'type'", preserving the existing input and documenting the required diagnostic
rather than accepting any configuration error.
---
Nitpick comments:
In `@tests/getting_started/conftest.py`:
- Around line 39-92: Extract the duplicated _MockOpenAIServer and
_CANNED_COMPLETION definitions from tests/getting_started/conftest.py and
tests/readme/conftest.py into a shared test helper module. Update both conftest
files to import and reuse those shared symbols, preserving the existing
local_mock_openai_server fixture behavior.
- Around line 39-131: Extract the duplicated _CANNED_COMPLETION and
_MockOpenAIServer from tests/getting_started/conftest.py#L39-131 and
tests/readme/conftest.py#L40-120 into a shared test helper, then import and
reuse them in both fixtures. Update _hermetic_build at both sites to preserve
each _self PassthroughProfileConfig while overriding only api_key and base_url,
using dataclasses.replace or the appropriate equivalent; do not reconstruct the
config so fields such as model remain intact.
In `@tests/getting_started/test_getting_started.py`:
- Around line 161-180: Update model_routes_yaml to type local_mock_openai_server
as _MockOpenAIServer, importing that symbol under a TYPE_CHECKING guard with the
existing imports kept sorted. Remove the object annotation and the # type:
ignore[attr-defined] comment.
In `@tests/readme/conftest.py`:
- Around line 40-86: Remove the duplicate _MockOpenAIServer implementation from
tests/readme/conftest.py and reuse the existing fixture or shared definition
from tests/getting_started/conftest.py, preserving the README tests’ current
server behavior and base_url interface.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 882520ba-3771-4faf-8930-1d1991960fb9
📒 Files selected for processing (30)
.agents/skills/switchyard-coding-agent-launchers/SKILL.md.github/workflows/getting-started.yml.github/workflows/perf.yml.github/workflows/readme.ymlCHANGELOG.mddocs/cli_reference.mddocs/core_concepts.mddocs/internal/latency_service_routing.mddocs/operations/context_window.mddocs/routing_algorithms/overview.mddocs/routing_algorithms/stage_router_routing.mdexamples/route.yamlswitchyard/__init__.pyswitchyard/cli/launchers/launcher_runtime.pyswitchyard/cli/route_bundle.pyswitchyard/cli/switchyard_cli.pyswitchyard/lib/profiles/__init__.pyswitchyard/lib/profiles/noop.pytests/getting_started/conftest.pytests/getting_started/test_getting_started.pytests/readme/conftest.pytests/readme/test_readme.pytests/test_launch_claude.pytests/test_launch_openclaw_deterministic.pytests/test_noop_llm_backend.pytests/test_resolve_classifier_prompts.pytests/test_route_bundle.pytests/test_routing_banner.pytests/test_run_manifest.pytests/test_user_config.py
💤 Files with no reviewable changes (5)
- examples/route.yaml
- switchyard/lib/profiles/init.py
- tests/test_noop_llm_backend.py
- switchyard/lib/profiles/noop.py
- switchyard/init.py
a22f2cf to
d8bff54
Compare
6ef82eb to
3b81f4f
Compare
|
Rebased onto latest
Validation on the rebased branch: |
|
Follow-up commit
Re-validated: |
Signed-off-by: Elyas Mehtabuddin <emehtabuddin@nvidia.com>
Signed-off-by: Elyas Mehtabuddin <emehtabuddin@nvidia.com>
…g-target test Signed-off-by: Elyas Mehtabuddin <emehtabuddin@nvidia.com>
a729bf7 to
8e1de47
Compare
Background
This change removes
type: noopandtype: passthrough, leavingtype: modelas the only way to route to one upstream.type: noopwas originally an internal tool for measuring proxy overhead. It is a route that returns a fixed response with no upstream LLM call, so you can measure Switchyard's own request-handling cost, separate from backend latency.type: passthroughwas a route that forwarded to a single upstream and could also auto-discover the upstream's catalog by listing itsGET /v1/models. All three —type: model,type: passthrough, andtype: noop— did the same thing: call exactly one target.noopandpassthroughwere only ever configured for tests and CI, never to serve real requests.That redundancy makes the router harder to read: every reader has to reason about two route types the server never serves, and an empty
{}route silently became anoopinstead of raising an error.We can remove them because
type: modelalready forwards to exactly one upstream, and the only two callers ofnoop— the self-contained doc tests and the perf CI job — now use a local mock OpenAI upstream plus atype: modelroute (see "Rebuilt" below). Nothing depends onnooporpassthroughafter that.Breaking change
type: passthroughortype: noopnow fails to load withunsupported route type.{}now raisesroute '<id>': missing 'type'(it used to default tonoop).passthroughroute (no target, list the upstream's wholeGET /v1/models) is gone.type: modelneeds an explicittarget.Migrate
type: passthroughtotype: modeland name the target:Kept unchanged
build_passthrough_table,build_tier_passthrough_switchyard,_passthrough_target.random_routing,stage_router,deterministic, and the launchers still register their tier targets as direct passthroughs.PassthroughProfileConfigandOpenAiPassthroughBackend(the library single-upstream config and backend).--modelsingle-model launcher label, the--inboundno-op flag, and translation passthrough.switchyard-servertype = "noop"config and the libsyNoopalgorithm (separate subsystems).Rebuilt the two callers that depended on noop
.github/workflows/perf.yml): the "proxy overhead" job served anooproute. It now starts a local zero-latency mock OpenAI stub and serves atype: modelroute at it. The loopback hop adds a small constant overhead, noted in the workflow.tests/getting_started,tests/readme): they usednoopto run guide snippets with no backend. They now start an in-process mock OpenAI server and pointPassthroughProfileConfigat it. Both fixtures sharetests/_mock_openai_server.py— the mock server plus oneredirect_passthrough_to_local_mockhelper.Validation
ruffandmypy(strict) clean.pytest -m "not integration": 1720 passed, 9 skipped, 28 deselected (isolatedHOME). The count is lower than earlier runs becausemainremoved the latency-aware router and its tests (refactor(routing)!: remove latency-aware router #162). One machine-specific test,test_verify.py::test_secrets_file_wins_when_no_cli_or_env, fails only when a real~/.config/switchyard/secretsfile is present; it passes with an isolatedHOMEand is unrelated to this change.--markdown-docs, 15 passed).mainafter the latency-aware router removal (refactor(routing)!: remove latency-aware router #162): the CHANGELOG keeps bothRemovednotes andimport switchyardsucceeds (no deleted latency modules resurrected).type: noop/type: passthrough/ empty{}are rejected; atype: modelroute registers and serves.