feat(libsy): stateful FallThrough routing algorithm + composable building blocks for libsy#101
feat(libsy): stateful FallThrough routing algorithm + composable building blocks for libsy#101messiaen wants to merge 1 commit into
Conversation
WalkthroughChangesRouting core
Protocol metadata default
Estimated code review effort: 4 (Complex) | ~45 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
crates/libsy/src/core/processor.rs (1)
17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
BoxErralias duplicated identically across three files. Same root cause: no single shared definition of the crate's boxed error type, so each new module redefines it.
crates/libsy/src/core/processor.rs#L17: keep as the canonical definition (or move tocore.rs) and have the other twouseit.crates/libsy/src/core/classifier.rs#L17: replace this local alias with an import of the shared one.crates/libsy/src/algorithms/fall_through.rs#L13: replace this local alias with an import of the shared one.🤖 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 `@crates/libsy/src/core/processor.rs` at line 17, The boxed error alias is duplicated across three modules instead of being shared. Keep type alias BoxErr in crates/libsy/src/core/processor.rs as the canonical definition, then remove the local aliases and import BoxErr in crates/libsy/src/core/classifier.rs and crates/libsy/src/algorithms/fall_through.rs; update visibility as needed so both modules can access it.
🤖 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 `@crates/libsy/src/algorithms/fall_through.rs`:
- Around line 35-44: Add a module-level `//!` documentation comment in the
`fall_through` module explaining its purpose and design, including the processor
chain, classifier cascade, routed model call, and session state lifecycle, so
the existing `module docs` references from `FallThrough` resolve correctly. Keep
the documentation focused on what the module does rather than build or
temporary-status details.
- Around line 71-126: Prevent create_run_task from holding the session state
mutex across external driver calls: keep the lock for processor/classifier state
mutation and decision replay, then release it before driver.info and
driver.call_llm_target. Preserve serialized state updates while ensuring
network-bound driver operations cannot block subsequent session turns
indefinitely.
In `@crates/libsy/src/core/classifier.rs`:
- Around line 19-37: Add concise Rust `///` documentation to the public
`Classification` enum and its `argmax` method. Document the distinction between
`Scores` and `Ambiguous`, and specify that `ignore_ambiguous` controls whether
`argmax` returns the best score or `None` for ambiguous classifications.
- Around line 41-49: Update argmax to rank confidence values without unwrapping
partial_cmp, using total_cmp (or otherwise explicitly rejecting non-finite
values) so NaN confidences cannot panic. Preserve the existing reverse iteration
and tie-breaking behavior where the earliest-listed target wins.
In `@crates/libsy/src/core/state.rs`:
- Around line 15-38: The public methods get, get_mut, insert, and
entry_or_insert_with need concise Rust documentation. Add /// comments
describing type-keyed lookup and mutable lookup, insert’s overwrite behavior,
and entry_or_insert_with’s lazy initialization and returned mutable reference,
while preserving their existing behavior.
---
Nitpick comments:
In `@crates/libsy/src/core/processor.rs`:
- Line 17: The boxed error alias is duplicated across three modules instead of
being shared. Keep type alias BoxErr in crates/libsy/src/core/processor.rs as
the canonical definition, then remove the local aliases and import BoxErr in
crates/libsy/src/core/classifier.rs and
crates/libsy/src/algorithms/fall_through.rs; update visibility as needed so both
modules can access it.
🪄 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: 1663c88a-f48e-49b2-baec-7074cd9f48fb
📒 Files selected for processing (7)
crates/libsy/src/algorithms.rscrates/libsy/src/algorithms/fall_through.rscrates/libsy/src/core.rscrates/libsy/src/core/classifier.rscrates/libsy/src/core/processor.rscrates/libsy/src/core/state.rscrates/protocol/src/envelope.rs
e89081e to
7dce16b
Compare
Signed-off-by: Greg Clark <grclark@nvidia.com> chore(libsy): acrros turn persistent state test for fallthrough Signed-off-by: Greg Clark <grclark@nvidia.com> docs(libsy): add doc strings Signed-off-by: Greg Clark <grclark@nvidia.com> chore(libsy): review feedback Signed-off-by: Greg Clark <grclark@nvidia.com> fix(libsy): default response timeout 10min for fulfill_request Signed-off-by: Greg Clark <grclark@nvidia.com> fix(libsy): add stream started guard Signed-off-by: Greg Clark <grclark@nvidia.com>
4ce6031 to
6bd0402
Compare
54d6700 to
6bd0402
Compare
Summary
Introduces a session-stateful routing algorithm to libsy along with the reusable
primitives it's built from.
FallThroughruns a processor chain → classifiercascade → routed model call, carrying
Stateacross turns so routing can dependon accumulated session history rather than the current request alone.
What's added
core::State— a type-keyed bag (get/get_mut/insert/entry_or_insert_with)that holds per-session facts and persists across turns.
core::Processor+Event— an async trait that folds observed events(
Request,Decision,ModelRequest/ModelResponse,Signal) intoState.core::Classifier— an async trait returning aClassification(
Scores/Ambiguous) ofScores;argmaxpicks the highest confidence withcascade order as the tie-break (first-listed target wins).
algorithms::FallThrough— holds sessionStateunder a lock; each turnaccumulates request-side facts through its processors, falls through classifiers
until one decides, publishes the
Decision, and replays it to the processors sostateful ones can bind it.
Signalsrelocated intoprotocol::envelope.Testing
Unit tests cover each primitive in isolation (
Statekeying,Processoreventtallying,
Classifierargmax/tie-break/ambiguity) and theFallThroughcascadeend-to-end: highest-confidence selection, fall-through on abstain, first-decider-wins,
all-abstain error, per-request driver hand-off, request→decision replay ordering, and
cross-turn state persistence (routing flips once an accumulated turn counter
crosses a threshold — proving
Statesurvives between turns).Checklist
snake_caseof the primary class.switchyard/__init__.py.__all__if intended for downstream use.--helpupdated if customer-facing surface changed.Signed-off-by: Your Name <email>) per the DCO.Notes for reviewers
Anything reviewers should pay extra attention to — risky paths, follow-up tickets, intentional trade-offs.
Summary by CodeRabbit