Conversation
Signed-off-by: ChethanUK <chethanuk@outlook.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: NVIDIA-NeMo/Switchyard/.coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (10)
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review. WalkthroughCustom classifiers now support JSON Object response formatting as an alternative to JSON Schema mode. The configured schema is appended to the prompt in JSON Object mode, and returned verdicts are validated against it. The setting is available through runtime configuration and Python bindings. ChangesCustom classifier response mode
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This change adds an opt-in JSON Object response mode for custom classifiers and leaves JSON Schema as the default. The supplied context shows no merge-blocking risk. The author notes the Python tests have not yet run on the fork's CI. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 54.05% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 37 functions across 8 files. (2 skipped: 2 unsupported.)
A rabbit checks the schema in the moonlit glow Comment |
What
Custom-mode
llm_classifierroutes can now setresponse_format_type = "json_object". Onmainthe runner rejects that combination at config load. Capability and escalation routes already support it.It works the same way as for the packaged classifiers. Switchyard appends the configured
response_schemato the judge prompt, sends{"type": "json_object"}, and checks the verdict against the schema locally. A verdict that fails the check falls back todefault_target. JSON Schema stays the default, so existing routes don't change.ClassifierContract::from_inner_schematakes the response format.from_configand the custom path share one helper,schema_in_prompt.response_schemawhose roottypedoesn't allowobject(a string other than"object", or an array without it) is rejected at load. The provider only returns objects, so such a schema would send every turn todefault_target. A schema with notypeat all is not checked.CustomClassifierConfiggets aresponse_format_typefield (defaultJsonSchema). The runner passes it for the top-level route inbuild_algorithmand for the nestedsubagentsclassifier inbuild_subagent_router_config.CustomClassifierConfigtakesresponse_format_type="json_schema", parsed the same way as the other classifier configs. Theswitchyard_rust/libsy.pystub is updated.response_format_typerow intoml_schema.mdand the custom section ofllm_classifier_routing.md.Why
Closes #429. Some providers support JSON Object mode but not JSON Schema, and custom classifiers couldn't use them. The contract follows the issue's conservative option:
response_schemais still required in both modes and is the source of truth, so a prompt never needs its own copy. Provider wrappers such as{"json_schema": {...}}are still rejected as an inner schema.Before / After
Same config and request against a stub OpenAI upstream. The config (
custom-json-object.toml) and stub (mock.py) are in pr-evidence/6. Both binaries were built withcargo build --locked -p switchyard-server --bin switchyard-server, the stub was started withpython3 mock.py 18431, and every output line below is copied verbatim from that run.Before, base
a601a9a3f9db149a1ad430fa43b1463a170c8a82(forkmain, before it was synced to upstream). The server exits with status 1:After, PR head
d9c819f599322108d8debd0df16608a7e7cb3547(re-run at this head):Notes for reviewers
Start with
crates/libsy/src/algorithms/util/classifier_contract.rs. Both constructors runvalidate_prompton the template, never on the prompt with the schema appended. The appended text is never empty, and a schema may itself contain the literal{{RESPONSE_SCHEMA}}.This adds a public field to
CustomClassifierConfig, so Rust callers that build it with a struct literal instead ofnew()must addresponse_format_type. It follows how other public config fields were added before 1.0.build_subagent_router_configis easy to miss. Without the field there, a nested custom classifier would quietly stay on JSON Schema;subagent_custom_classifier_can_request_json_object_outputcovers it.The server test mock used to recognize custom judge calls only by
response_format.json_schema. It now also recognizes ajson_objectrequest whose prompt contains the custom schema.Verification, at the head of this PR rebased on
fbabf51c(upstreammain):The new runner and server tests fail on
mainwith the old config error. The Python tests (tests/test_libsy_minimal_bindings.py) pass locally against an extension built withmaturin develop(22 passed, including the two new custom-classifier tests). They have not run on the fork's CI.Summary by CodeRabbit
response_format_typevalues ofjson_schemaorjson_object.