Skip to content

feat(python): expose decision call steps - #913

Merged
ayushag-nv merged 1 commit into
mainfrom
nachiketb/switch-1695-python-decision-calls
Oct 6, 2026
Merged

ayushag-nv merged 1 commit into
mainfrom
nachiketb/switch-1695-python-decision-calls

Conversation

@nachiketb-nvidia

@nachiketb-nvidia nachiketb-nvidia commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Python hosts currently raise NotImplementedError when an algorithm requests a decision. This exposes Step.CallDecision so a host can read the request and target, then return a response or client error.

Closes SWITCH-1695.

How

  • Add DecisionCall with algorithm, request, model, respond, and fail. Requests and responses use the existing dictionary conversion helpers and the neutral Decision Model protocol.
  • Preserve single completion, provider-error fallback, and Rust drop/cancellation behavior. Invalid response dictionaries leave the call available for a corrected response.
  • Add TaskClassifierConfig.decision(...) to select the existing relative-advantage judge from Python, using Rust's default routing and fallback settings.
  • Update public exports and the run_stream return type.

Independent of #907; this uses the protocol, driver, and classifier already on main.

Validation

  • Built the Python extension; all 20 existing tests in tests/test_libsy_minimal_bindings.py passed.
  • Manual Python checks passed for both routing outcomes, provider failure, malformed-response recovery, duplicate replies, dropped calls, and cancellation.
  • Focused Clippy, Ruff, mypy, formatting, and diff checks passed.
  • No test files added or changed. No live provider calls.

Summary by CodeRabbit

  • New Features
    • Added decision-based classification configuration, with support for setting a cutoff, candidate models, required evidence, and optional instructions.
    • Streaming workflows can now receive decision calls and respond to or fail them using Python.
    • Decision calls expose their algorithm, request, and selected model.

Signed-off-by: nachiketb <nachiketb@nvidia.com>
@nachiketb-nvidia
nachiketb-nvidia requested a review from a team as a code owner October 5, 2026 20:40
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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 configuration
  • Configuration used: Repository: NVIDIA-NeMo/Switchyard/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 0d373063-cd52-40dd-868a-5f5a862697a2
📥 Commits

Reviewing files that changed from the base of the PR and between 1aebea4 and 14ed0b6.

📒 Files selected for processing (3)
  • crates/switchyard-py/src/libsy_bindings.rs
  • switchyard/libsy/__init__.py
  • switchyard_rust/libsy.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.


Walkthrough

The Python API now supports decision-classifier configuration and exposes Rust decision calls as Python stream steps. Python code can inspect each call and submit a response or failure.

Changes

Python decision-call support

Layer / File(s) Summary
Decision configuration and API
crates/switchyard-py/src/libsy_bindings.rs, switchyard_rust/libsy.py
TaskClassifierConfig.decision constructs a decision judge from a cutoff, candidate models, evidence, and optional instructions. The Python declarations add DecisionCall methods and include Step.CallDecision in the stream types.
Runtime bridge and package exports
crates/switchyard-py/src/libsy_bindings.rs, switchyard_rust/libsy.py, switchyard/libsy/__init__.py
The bindings convert Rust decision calls into Python DecisionCall objects. The package exports the class, and respond and fail forward completions to the waiting Rust call.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 14ed0

The decision-call API is mergeable after normal checks; no actionable issue is established by the supplied evidence.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: exposing decision-call steps to Python hosts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks the stream at dawn,
A decision call hops safely on.
It sends a response, or reports a fail,
Then shares its model along the trail.
The Python burrow welcomes all.

Comment @coderabbitai help to get the list of available commands.

@ayushag-nv ayushag-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ayushag-nv
ayushag-nv merged commit db0a6bc into main Oct 6, 2026
16 checks passed
@ayushag-nv
ayushag-nv deleted the nachiketb/switch-1695-python-decision-calls branch October 6, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants