Skip to content

fix: enforce strict clippy linting across entire workspace - #489

Merged
slin1237 merged 3 commits into
mainfrom
slin/oai-3
Feb 21, 2026
Merged

slin1237 merged 3 commits into
mainfrom
slin/oai-3

Conversation

@slin1237

@slin1237 slin1237 commented Feb 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Introduce clippy.toml and workspace-level [lints.clippy] configuration to enforce production-grade code quality standards across all 26 crates. Every clippy warning is now denied via -D warnings. This is a comprehensive audit and fix of 320 files with ~4,400 lines of changes.

This codebase serves billions of tokens per minute. The previous lint configuration was permissive, allowing unwrap/expect/panic in production code paths without justification. This change enforces that every potential panic point is either eliminated (proper error propagation) or explicitly justified with a reason string explaining why it is safe.

What changed

New configuration files

  • clippy.toml: Configures disallowed methods (tokio::spawn requires justification), allow-expect-in-tests, and allow-unwrap-in-tests for test/bench ergonomics.
  • Cargo.toml: Workspace-level [lints.clippy] denying unwrap_used, expect_used, panic, print_stdout/stderr, dbg_macro, todo/unimplemented, and other unsafe patterns. Enables pedantic and nursery lint groups with targeted exceptions.

Real bugs found and fixed

Bug File(s) Severity Fix
CRDT timestamp data corruption: unwrap_or_default() on SystemTime silently produced timestamp=0, causing LWW data loss during merge (timestamp 0 always loses to any other write) mesh/src/crdt.rs, incremental.rs, ping_server.rs HIGH Changed to .expect() — a clock before UNIX epoch is a fatal misconfiguration that must crash, not silently corrupt data
DashMap TOCTOU race condition: Second .get().expect() after or_insert_with() could panic if another thread called remove() between the two operations model_gateway/src/observability/gauge_histogram.rs HIGH Restructured to use .downgrade() on the entry ref directly, eliminating the race window
HealthChecker task leak: tokio::spawn reason claimed "abort() is called on drop" but no Drop impl existed. shutdown() was dead code. Spawned health-check tasks would leak on shutdown. model_gateway/src/core/worker.rs HIGH Added Drop impl that calls handle.abort(). Changed handle to Option<JoinHandle> so graceful shutdown() and Drop coexist correctly.
Dead Result wrappers hiding infallible code: 5 trtllm builder methods and 2 WASM constructors returned Result but never returned Err, adding dead error paths and unnecessary ? operators grpc_client/src/trtllm_service.rs, wasm/src/runtime.rs, wasm/src/module_manager.rs MEDIUM Removed Result wrappers entirely
Postgres constructor panics: Three .expect() calls in storage constructors would crash the process on DB schema initialization failure data_connector/src/postgres.rs MEDIUM Replaced with ? error propagation

Production code quality improvements

Lock migration (bucket.rs, memory.rs):

  • Migrated std::sync::Mutex/RwLock to parking_lot equivalents
  • Removed ~50 lines of dead lock-poisoning error handling (parking_lot never poisons)
  • Behavioral improvement: previously a panic while holding a lock would cause all subsequent lock attempts to also panic; now the lock is released and the next caller succeeds

Unnecessary async removal (19 functions):

  • Removed async from functions that contained no .await calls (flagged by unused_async lint)
  • Key functions: TokenBucket::try_acquire/return_tokens/available_tokens (used parking_lot::Mutex, never truly async), create_grpc_router, prepare_chat, prepare_responses, execute_tool_loop_streaming, handle_streaming_with_tool_interception, execute_mcp_streaming, merge_state, create_snapshot_chunks, start_rotation_monitor
  • All callers updated to remove .await — verified by 6-agent audit that zero callers were missed

API signature improvements:

  • Worker::api_key(): &Option<String> → Option<&String> (idiomatic Rust). All callers updated (.clone() → .cloned(), removed .as_ref())
  • WorkerRegistry::get_by_type/get_by_connection: Changed to take owned Copy types instead of references
  • protocols/src/common.rs: &Option<ToolChoice> → Option<&ToolChoice>

Panic elimination in production code:

  • protocols/src/chat.rs, responses.rs: Replaced unsafe .unwrap() on optional tool arrays with if-let/else-return patterns
  • kv_index/src/string_tree.rs: Replaced .chars().next().unwrap() in while loops with while-let patterns
  • mcp/src/core/pool.rs: Added .max(1) guard before NonZeroUsize::new() to prevent panic on user-provided 0

tokio::spawn documentation:

  • Every tokio::spawn call site now has #[expect(clippy::disallowed_methods)] with a reason string documenting: who stores the handle, how it's aborted, and what coordinates shutdown

Mechanical fixes (all 320 files)

  • Format string inlining: format!("{}", x) → format!("{x}") (Rust 2021 syntax)
  • Raw string hash reduction: r#"..."# → r"..." where content has no double-quotes
  • #[allow] → #[expect] migration: #[expect] fails if the lint never fires, catching stale suppressions
  • clone_from() for efficiency: x = y.clone() → x.clone_from(&y) (avoids reallocation when capacity suffices)
  • Wildcard → explicit match arms: _ => panic! → SpecificVariant => panic! for compile-time exhaustiveness safety
  • Copy type pass-by-value: &self → self for methods on Copy types like enums, Ipv4Addr, bitflags
  • unused_self cleanup: Private methods that don't use self changed from self.method() to Self::method() in callers. Public methods keep &self with #[expect(clippy::unused_self)] for API stability.
  • Unnecessary Result removal: Functions that never return Err had their Result wrappers removed

Test and benchmark changes

  • Test common infrastructure: create_app() changed from async fn to fn (was never truly async). All ~90 callers updated.
  • Benchmark files: File-level #![expect(clippy::unwrap_used, ...)] for ergonomic benchmark code
  • Test files: #[expect(clippy::expect_used)] on test helpers, #[expect(clippy::disallowed_methods)] on test tokio::spawn calls
  • No test assertions were changed — all modifications are mechanical lint fixes verified by audit

Crates affected

Crate Files Key changes
model_gateway 165 Core production code, all routers (grpc, openai, anthropic, http), policies, observability, tests, benches
protocols 14 API signature improvements, panic elimination, Copy pass-by-value
mesh 18 CRDT timestamp fix, async removal, parking_lot migration considerations
mcp 14 Orchestrator static method cleanup, tokio::spawn documentation
tool_parser 24 Parser method self→Self cleanup, test raw string reduction
tokenizer 16 Format strings, test annotations, cache cleanup
grpc_client 3 Dead Result removal, unused_self annotations for cross-backend API consistency
multimodal 12 Vision processor method cleanup, test simplification
data_connector 6 Postgres panic→error propagation, parking_lot migration
kv_index 2 While-let panic elimination, dead code cleanup
auth 4 JWKS async removal, JWT role extraction simplification
wasm 5 Infallible constructor cleanup
workflow 3 tokio::spawn documentation
bindings/golang 10 API signature cascade, format strings
bindings/python 1 PyO3 unnecessary_wraps annotations
reasoning_parser 9 Factory pooling cleanup

How verified

  • cargo check --all-targets — passes cleanly
  • cargo clippy --all-targets -- -D warnings — zero errors across all 26 crates
  • cargo fmt --all -- --check — zero formatting diffs
  • 6-agent comprehensive audit covering:
    • All 19 async→sync conversions verified (no .await in body, all callers updated)
    • All API signature changes verified (zero missed callers across entire workspace)
    • All error handling reviewed (3 HIGH bugs fixed, 25+ LOW patterns verified safe)
    • All dead code annotations verified (justified or flagged for future cleanup)
    • All test changes verified (mechanical only, no broken assertions)
    • All non-gateway crate changes verified (correct and safe)

Test plan

  • cargo check --all-targets passes
  • cargo clippy --all-targets -- -D warnings produces zero errors
  • cargo fmt --all -- --check produces zero diffs
  • Existing test suite passes (no test logic was changed, only mechanical lint fixes)
  • Benchmark compilation succeeds
  • Integration tests pass (API signatures changed but all callers updated)

Summary by CodeRabbit

  • New Features

    • Multimodal: richer model-specific image output type and safer image-dimension accessors.
  • Refactor

    • Several constructors and streaming/token-bucket APIs converted from async to synchronous for simpler call patterns.
  • Improvements

    • More consistent, clearer error and log messages; streaming (SSE) and tool-call flows hardened for robustness and fewer edge-case failures.
  • Chores

    • Workspace lint and build hygiene updated (tooling/config only).

@github-actions github-actions Bot added tokenizer Tokenizer related changes python-bindings Python bindings changes dependencies Dependency updates grpc gRPC client and router changes mcp MCP related changes wasm WebAssembly related changes benchmarks Benchmark changes tests Test changes tool-parser Tool/function call parser changes reasoning-parser Reasoning parser changes auth Authentication crate changes data-connector Data connector crate changes multimodal Multimodal crate changes protocols Protocols crate changes workflow Workflow crate changes model-gateway Model gateway crate changes openai OpenAI router changes anthropic Anthropic router changes labels Feb 21, 2026
@coderabbitai

coderabbitai Bot commented Feb 21, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds a workspace Clippy lint configuration and applies widespread mechanical changes: formatting interpolation, lint attribute shifts (#[allow] → #[expect]), parking_lot locks, clone_from optimizations, many async→sync conversions, and numerous signature/receiver adjustments across core, router, worker, protocols, multimodal, and tests. No new runtime features.

Changes

Cohort / File(s) Summary
Workspace lint & config
Cargo.toml, clippy.toml
Add workspace lints and new clippy.toml; many crates adopt workspace.lints.clippy and new lint expectations.
Formatting sweep
**/*.rs, **/*/tests/*
Mass migration from positional "{}" to named "{var}" formatting and many test literal updates.
Lint attribute updates
many files under model_gateway/, mesh/, model_gateway/tests/*, protocols/*
Widespread #[allow(...)] → #[expect(...)] and added clippy expectations on functions/tests.
Auth / JWT / JWKS
auth/src/config.rs, auth/src/jwt.rs, auth/src/jwks.rs, auth/src/middleware.rs
Signature receiver change (Role::is_admin), extract_role now returns Role (not Result), formatting + attribute adjustments, call-site updates.
Model gateway — routers & streaming
model_gateway/src/**
Large refactor: many helpers and stages converted from async → sync, streaming/MCP flows adjusted, SSE utilities added, many helper signatures changed and call sites updated.
Worker surface & registry
model_gateway/src/core/{worker.rs,worker_registry.rs,worker_service.rs,worker_manager.rs}
parking_lot adoption, Worker::api_key now returns Option<&String>, get_by_type/get_by_connection take values, parse_worker_id → associated fn, and client/registry call-site changes.
gRPC client & schedulers
grpc_client/src/...
Multiple instance methods converted to associated functions (removed &self), sampling/generation builders signature updates, and lint attributes added.
Bindings (Go/Python)
bindings/golang/src/*, bindings/python/src/lib.rs
FFI comments, Option/&T API adjustments (as_ref/cloned), CString default usage, error-format changes, and added lint annotations.
Data layer & indexing
data_connector/src/*, kv_index/src/*
Key-formatting to named placeholders, iteration/borrow tweaks, clone_from optimizations, added defaults, lint edits.
Mesh / CRDT / topology
mesh/src/*
Many as_str/to_int receivers now take self, several async methods → sync, clone_from usage, iteration/borrrow adjustments, lint expectations.
Multimodal / vision
multimodal/src/**
New ModelSpecificValue enum; PreprocessedImages accessors now return Result; several processor methods changed return types (Result ↔ plain) with call-site updates.
Protocols / public APIs
protocols/src/{event_types,model_type,common,responses,...}
Many public helper receivers changed to take self by value; ModelType capability APIs changed; ToolChoice serialize signature changed; generate_id formatting adjusted — review public callers.
Reasoning parser factory
reasoning_parser/src/factory.rs
Switch to parking_lot locks, create() now returns parser directly (no Result), add PooledParser alias and registry getter — public API signature changes.
Policies & bucket/consistent hashing
model_gateway/src/policies/*
parking_lot adoption, clone_from updates, Branch/ExecutionBranch as_str receiver edits, and tests adjusted.
Token bucket & middleware
model_gateway/src/core/{token_bucket.rs,middleware.rs}
TokenBucket API changed from async → sync (try_acquire/return_tokens/available_tokens) and middleware adjusted to sync calls.
Tests & helpers
**/tests/**, model_gateway/tests/**
Many tests: create_app made synchronous, abundant #[expect(...)] annotations, assertion formatting changes; run full test suite recommended.
Misc small modules
assorted (observability, utils, builders)
Numerous small edits: clone_from, unwrap→expect/unwrap_or_default, iteration tweaks, SSE/send_error_sse addition, and attribute updates.

Sequence Diagram(s)

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • CatherineSue
  • tonyluj
  • whybeyoung

Poem

"I’m a tidy rabbit, hopping through the tree,
I swapped each fmt! and chased lint warnings free.
I made clones smarter, turned awaits into springs,
Guarded tests with expects and polished many strings.
Hop—run the build, may CI smile at me!" 🐇✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title succinctly and accurately summarizes the main change: enforcing strict Clippy linting across the workspace.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch slin/oai-3

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

@mergify

mergify Bot commented Feb 21, 2026

Copy link
Copy Markdown
Contributor

Hi @slin1237, this PR has merge conflicts that must be resolved before it can be merged. Please rebase your branch:

git fetch origin main
git rebase origin/main
# resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts that need to be resolved label Feb 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 156e4eab55

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread model_gateway/src/server.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (16)
model_gateway/src/routers/parse/handlers.rs (2)

57-62: 🧹 Nitpick | 🔵 Trivial

Inconsistent format string style within function.

Line 61 now uses inlined format args {e}, but lines 42 and 58 in this same function still use the positional "{}", var style. Consider updating all format strings for consistency.

♻️ Suggested fix to align format string style
         return error_response(
             StatusCode::BAD_REQUEST,
-            &format!("Unknown tool parser: {}", req.tool_call_parser),
+            &format!("Unknown tool parser: {}", req.tool_call_parser), // line 42: consider {req.tool_call_parser} if clippy permits
         );
     };
 
     let parser = pooled_parser.lock().await;
     match parser.parse_complete(&req.text).await {
         // ...
         Err(e) => {
-            error!("Failed to parse function calls: {}", e);
+            error!("Failed to parse function calls: {e}");
             error_response(
                 StatusCode::BAD_REQUEST,
                 &format!("Failed to parse function calls: {e}"),
             )
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/parse/handlers.rs` around lines 57 - 62, The error
logging and error_response calls in this handler use mixed format styles (some
use "{}", var and one uses "{e}"); make them consistent by switching all format
strings in this function to the inline named-argument style (e.g.,
error!("Failed to parse function calls: {e}") and
error_response(StatusCode::BAD_REQUEST, &format!("Failed to parse function
calls: {e}")), and update the other error! and format! calls in the same
function (the ones using "{}", var) to the {name} form so all uses (error!,
format!, error_response) consistently use named inline placeholders.

94-99: 🧹 Nitpick | 🔵 Trivial

Same inconsistency as above.

Line 98 uses inlined {e}, but lines 79 and 95 still use positional args. For consistency, consider updating these as well.

♻️ Suggested fix
         return error_response(
             StatusCode::BAD_REQUEST,
-            &format!("Unknown reasoning parser: {}", req.reasoning_parser),
+            &format!("Unknown reasoning parser: {}", req.reasoning_parser), // consider inlining if clippy permits
         );
     };
 
     let mut parser = pooled_parser.lock().await;
     match parser.detect_and_parse_reasoning(&req.text) {
         // ...
         Err(e) => {
-            error!("Failed to separate reasoning: {}", e);
+            error!("Failed to separate reasoning: {e}");
             error_response(
                 StatusCode::BAD_REQUEST,
                 &format!("Failed to separate reasoning: {e}"),
             )
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/parse/handlers.rs` around lines 94 - 99, The log
and response formatting in the Err(e) arm are inconsistent: the error! macro
uses positional "{}" while the error_response uses inline "{e}"; update both
places to the same style (pick one convention—e.g., use "{}" for both) so the
error message for "Failed to separate reasoning" is formatted consistently
across error! and error_response calls in handlers.rs (identify the error!
invocation and the error_response(... format!(...)) call and make them use the
same formatter).
mcp/src/approval/manager.rs (1)

261-270: ⚠️ Potential issue | 🟡 Minor

Unreachable match arm with misleading fallback.

When approved is false (line 264 branch), decision is always ApprovalDecision::Denied (set at lines 255-258). The Approved arm at line 267 is unreachable, and its "User denied" text is semantically incorrect for an approved decision.

If this arm was added for exhaustiveness, consider making the invariant explicit with unreachable!():

Proposed fix
         reason: match &decision {
             ApprovalDecision::Denied { reason } => reason.clone(),
-            ApprovalDecision::Approved => "User denied".to_string(),
+            ApprovalDecision::Approved => unreachable!("decision is Denied when !approved"),
         },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/src/approval/manager.rs` around lines 261 - 270, The match on decision
when building result contains an unreachable ApprovalDecision::Approved arm and
a misleading "User denied" message; update the match in the Denied branch of
result (where approved is false) to handle only the expected
ApprovalDecision::Denied case and replace the Approved arm with an explicit
unreachable!() (or other assertion) to make the invariant clear — locate the
creation of result and the match over ApprovalDecision to remove the incorrect
fallback and use unreachable!() (or panic/assert) for the Approved variant so
the code documents the invariant and avoids the misleading string.
model_gateway/build.rs (1)

13-20: ⚠️ Potential issue | 🟠 Major

Avoid silent fallback on build metadata failures.

read_cargo_version() and get_rustc_host() failures now quietly default to 0.0.0 / empty target, which can ship incorrect metadata without any signal. At minimum, emit a cargo:warning when falling back (or consider failing the build if version/target is required).

💡 Suggested fix (warn on fallback)
-    let version = read_cargo_version().unwrap_or_else(|_| DEFAULT_VERSION.to_string());
-    let target = std::env::var("TARGET").unwrap_or_else(|_| get_rustc_host().unwrap_or_default());
+    let version = read_cargo_version().unwrap_or_else(|e| {
+        println!("cargo:warning=failed to read Cargo.toml version: {e}");
+        DEFAULT_VERSION.to_string()
+    });
+    let target = std::env::var("TARGET").unwrap_or_else(|e| {
+        println!("cargo:warning=missing TARGET env var: {e}");
+        get_rustc_host().unwrap_or_else(|| {
+            println!("cargo:warning=failed to determine rustc host triple");
+            String::new()
+        })
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/build.rs` around lines 13 - 20, The current build script
silently falls back to DEFAULT_VERSION and an empty host when
read_cargo_version() or get_rustc_host() fail; update the logic around
read_cargo_version()/DEFAULT_VERSION and get_rustc_host()/TARGET to emit a
visible warning (e.g., println!("cargo:warning=...")) when those functions
return Err or when you use DEFAULT_VERSION/get_rustc_host defaulting, or
optionally return a non-zero exit (panic!) if version/target must be required;
specifically, wrap the calls to read_cargo_version() and get_rustc_host() so
failures produce a cargo:warning with context (including the error) before
applying DEFAULT_VERSION or empty target, referencing the read_cargo_version,
get_rustc_host, DEFAULT_VERSION, and the TARGET/PROFILE env var logic so the
warning appears during cargo build.
model_gateway/src/policies/cache_aware.rs (1)

155-160: 🧹 Nitpick | 🔵 Trivial

Consider avoiding the clone entirely by restructuring.

Since mesh_sync is passed by value and only used afterward for the is_some() check, you can eliminate the clone by checking first, then moving:

♻️ Proposed refactor to avoid clone
     pub fn set_mesh_sync(&mut self, mesh_sync: OptionalMeshSyncManager) {
-        self.mesh_sync.clone_from(&mesh_sync);
-        if mesh_sync.is_some() {
+        let should_restore = mesh_sync.is_some();
+        self.mesh_sync = mesh_sync;
+        if should_restore {
             self.restore_tree_state_from_mesh();
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/policies/cache_aware.rs` around lines 155 - 160, In
set_mesh_sync, avoid the unnecessary clone of mesh_sync by checking
mesh_sync.is_some() first and then moving mesh_sync into the struct field only
when needed; specifically, use the OptionalMeshSyncManager parameter directly
(move it into self.mesh_sync) instead of calling
self.mesh_sync.clone_from(&mesh_sync), and call restore_tree_state_from_mesh()
after the move when mesh_sync was Some; reference: function set_mesh_sync,
parameter mesh_sync, field self.mesh_sync, and method
restore_tree_state_from_mesh.
model_gateway/src/policies/consistent_hashing.rs (1)

163-177: ⚠️ Potential issue | 🟠 Major

Avoid TOCTOU between health counting and selection (can yield None with healthy workers).

On Line 164–175, a health change between the count and nth can produce None even when at least one worker remains healthy, and the branch is still marked RandomFallback. This can surface as false “no worker” results and misleading metrics.

✅ Suggested fix (single pass over healthy workers)
-        let healthy_count = workers.iter().filter(|w| w.is_healthy()).count();
-        if healthy_count == 0 {
-            return (None, Branch::NoHealthyWorkers);
-        }
-
-        let random_healthy_idx = rand::rng().random_range(0..healthy_count);
-        let idx = workers
-            .iter()
-            .enumerate()
-            .filter(|(_, w)| w.is_healthy())
-            .nth(random_healthy_idx)
-            .map(|(i, _)| i);
-
-        (idx, Branch::RandomFallback)
+        let healthy_indices: Vec<usize> = workers
+            .iter()
+            .enumerate()
+            .filter(|(_, w)| w.is_healthy())
+            .map(|(i, _)| i)
+            .collect();
+        if healthy_indices.is_empty() {
+            return (None, Branch::NoHealthyWorkers);
+        }
+
+        let random_healthy_idx = rand::rng().random_range(0..healthy_indices.len());
+        let idx = Some(healthy_indices[random_healthy_idx]);
+
+        (idx, Branch::RandomFallback)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/policies/consistent_hashing.rs` around lines 163 - 177, The
current two-pass logic over workers risks TOCTOU: between counting healthy
workers and selecting the nth healthy, health can change and idx become None
while healthy_count > 0; fix by performing a single pass to collect the indices
of healthy workers (use workers.iter().enumerate().filter(|(_, w)|
w.is_healthy()).map(|(i, _)| i).collect::<Vec<_>>()), then if the collected Vec
is empty return (None, Branch::NoHealthyWorkers), otherwise choose a random
index within that Vec (replace random_healthy_idx with
rand::rng().random_range(0..healthy_indices.len())) and return
(Some(healthy_indices[random_idx]), Branch::RandomFallback) so selection cannot
race with the count.
grpc_client/src/sglang_scheduler.rs (2)

520-528: ⚠️ Potential issue | 🟡 Minor

Missing "grammar" alias for constraint type.

SGLang only matches "ebnf" while TRT-LLM matches "ebnf" | "grammar" and vLLM matches "grammar" | "ebnf". This inconsistency means if "grammar" is passed as the constraint type, it will succeed on TRT-LLM and vLLM but return "Unknown constraint type" on SGLang.

🐛 Proposed fix to add grammar alias
                 "structural_tag" => {
                     proto::sampling_params::Constraint::StructuralTag(constraint_value)
                 }
                 "json_schema" => proto::sampling_params::Constraint::JsonSchema(constraint_value),
-                "ebnf" => proto::sampling_params::Constraint::EbnfGrammar(constraint_value),
+                "ebnf" | "grammar" => proto::sampling_params::Constraint::EbnfGrammar(constraint_value),
                 "regex" => proto::sampling_params::Constraint::Regex(constraint_value),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@grpc_client/src/sglang_scheduler.rs` around lines 520 - 528, The match on
constraint_type (creating tool_constraint) misses the "grammar" alias and
currently only handles "ebnf", causing "grammar" inputs to hit the default
Unknown constraint error; update the match in the block that builds
tool_constraint (the match over constraint_type.as_str() that produces
proto::sampling_params::Constraint variants) to accept "grammar" as an
additional arm mapping to
proto::sampling_params::Constraint::EbnfGrammar(constraint_value) (e.g., add a
"grammar" => proto::...::EbnfGrammar(constraint_value) branch or combine it with
the "ebnf" arm).

580-588: ⚠️ Potential issue | 🟡 Minor

Same missing "grammar" alias in build_constraint_for_responses.

This function has the same inconsistency as build_constraint_for_chat.

🐛 Proposed fix
                 "json_schema" => proto::sampling_params::Constraint::JsonSchema(constraint_value),
-                "ebnf" => proto::sampling_params::Constraint::EbnfGrammar(constraint_value),
+                "ebnf" | "grammar" => proto::sampling_params::Constraint::EbnfGrammar(constraint_value),
                 "regex" => proto::sampling_params::Constraint::Regex(constraint_value),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@grpc_client/src/sglang_scheduler.rs` around lines 580 - 588, The match in
build_constraint_for_responses is missing the "grammar" alias (same
inconsistency as build_constraint_for_chat); update the match on constraint_type
in build_constraint_for_responses to treat "grammar" the same as "ebnf" (e.g.,
match "ebnf" | "grammar" =>
proto::sampling_params::Constraint::EbnfGrammar(constraint_value)) so both
aliases produce an EbnfGrammar constraint.
data_connector/src/memory.rs (1)

237-258: ⚠️ Potential issue | 🔴 Critical

Fix lock-order inversion to prevent deadlocks.

delete_item acquires rev_index then links, while link_item acquires links then rev_index. Concurrent calls can deadlock. Enforce a single lock order everywhere (e.g., links → rev_index).

🔒 Proposed fix (consistent lock order)
-        let key_to_remove = {
-            let mut rev = self.rev_index.write();
-            if let Some(conv_idx) = rev.get_mut(conversation_id) {
-                conv_idx.remove(&item_id.0)
-            } else {
-                None
-            }
-        };
-
-        // If the item was in rev_index, remove it from links as well
-        if let Some(key) = key_to_remove {
-            let mut links = self.links.write();
-            if let Some(conv_links) = links.get_mut(conversation_id) {
-                conv_links.remove(&key);
-            }
-        }
+        let mut links = self.links.write();
+        let mut rev = self.rev_index.write();
+        if let Some(conv_idx) = rev.get_mut(conversation_id) {
+            if let Some(key) = conv_idx.remove(&item_id.0) {
+                if let Some(conv_links) = links.get_mut(conversation_id) {
+                    conv_links.remove(&key);
+                }
+            }
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data_connector/src/memory.rs` around lines 237 - 258, delete_item currently
acquires rev_index then links, which can deadlock with link_item that acquires
links then rev_index; change delete_item to acquire locks in the same order as
link_item (links then rev_index) by first taking a write lock on self.links to
remove any entry for conversation_id and capture the key to remove, then taking
a write lock on self.rev_index to remove the corresponding rev_index entry (or
vice‑versa if you prefer the canonical order links → rev_index used across the
codebase); update the logic in delete_item to use that single consistent
ordering and ensure you still only hold each lock for the minimal time while
preserving the same behavior.
model_gateway/src/routers/grpc/utils.rs (2)

932-941: 🧹 Nitpick | 🔵 Trivial

Log tokenizer decode failures before falling back.
Now that logprob conversion is infallible, decode errors are silently masked; add a warn to preserve observability.

Suggested fix
     convert_proto_logprobs(proto_logprobs, |token_id| {
-        tokenizer
-            .decode(&[token_id], false)
-            .unwrap_or_else(|_| format!("<token_{token_id}>"))
+        tokenizer.decode(&[token_id], false).unwrap_or_else(|e| {
+            warn!(token_id, error = %e, "Failed to decode token id for logprobs");
+            format!("<token_{token_id}>")
+        })
     })
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/utils.rs` around lines 932 - 941, The
conversion currently swallows tokenizer.decode errors in
convert_proto_to_openai_logprobs; update the closure passed to
convert_proto_logprobs so that when tokenizer.decode(&[token_id], false) returns
Err(e) you log a warning (e.g., tracing::warn! or log::warn!) including the
token_id and the error, then return the same fallback
format!("<token_{token_id}>"). Keep the call target symbols:
convert_proto_to_openai_logprobs, convert_proto_logprobs, and tokenizer.decode.

452-468: ⚠️ Potential issue | 🟡 Minor

Avoid dropping the last assistant message when content isn’t a string.
In continue_final_message mode the last assistant message is always popped, but if its content isn’t a string (e.g., tool_calls or multimodal), the message is lost. Only pop after confirming a string prefix.

Suggested fix
-        let assistant_prefix = if request.continue_final_message
-            && !transformed_messages.is_empty()
-            && transformed_messages
-                .last()
-                .and_then(|msg| msg.get("role"))
-                .and_then(|v| v.as_str())
-                == Some("assistant")
-        {
-            // Pop the last message to handle it separately — guarded by !is_empty() check above
-            let Some(last_msg) = transformed_messages.pop() else {
-                return Ok(ProcessedMessages {
-                    text: String::new(),
-                    multimodal_inputs: None,
-                    stop_sequences: request.stop.clone(),
-                });
-            };
-            last_msg
-                .get("content")
-                .and_then(|v| v.as_str())
-                .map(|s| s.to_string())
-        } else {
-            None
-        };
+        let assistant_prefix = if request.continue_final_message
+            && !transformed_messages.is_empty()
+            && transformed_messages
+                .last()
+                .and_then(|msg| msg.get("role"))
+                .and_then(|v| v.as_str())
+                == Some("assistant")
+        {
+            if let Some(prefix) = transformed_messages
+                .last()
+                .and_then(|msg| msg.get("content"))
+                .and_then(|v| v.as_str())
+            {
+                transformed_messages.pop();
+                Some(prefix.to_string())
+            } else {
+                None
+            }
+        } else {
+            None
+        };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/utils.rs` around lines 452 - 468, The code
currently unconditionally pops the last assistant message when
request.continue_final_message is true, which discards messages whose "content"
is non-string; change the logic in the block that uses continue_final_message
and transformed_messages so you inspect transformed_messages.last() (check its
"role" == "assistant" and its "content".as_str() is Some) before calling pop;
only call transformed_messages.pop() after confirming the content is a string
and bind that to last_msg, otherwise leave the message in place and proceed to
build ProcessedMessages without removing it (refer to continue_final_message,
transformed_messages, last_msg, and the ProcessedMessages return).
model_gateway/tests/common/mock_worker.rs (1)

592-1099: ⚠️ Potential issue | 🟡 Minor

Store generated background response IDs for later lookup.
When background=true and no request_id is supplied, you generate a rid but never insert it into RESP_STORE, so subsequent GET/cancel returns 404. Store the generated id in the background branch.

🔧 Proposed fix
-    // Background storage simulation
-    let is_background = payload
+    // Background storage simulation
+    let is_background = payload
         .get("background")
         .and_then(|v| v.as_bool())
         .unwrap_or(false);
     let req_id = payload
         .get("request_id")
         .and_then(|v| v.as_str())
         .map(|s| s.to_string());
-    if is_background {
-        if let Some(id) = &req_id {
-            store_response_for_port(config.port, id);
-        }
-    }
@@
-    } else if is_background {
-        let rid = req_id.unwrap_or_else(|| format!("resp-{}", Uuid::new_v4()));
+    } else if is_background {
+        let rid = req_id.unwrap_or_else(|| format!("resp-{}", Uuid::new_v4()));
+        store_response_for_port(config.port, &rid);
         Json(json!({
             "id": rid,
             "object": "response",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/tests/common/mock_worker.rs` around lines 592 - 1099, In
responses_handler, when handling the is_background branch you generate a rid via
req_id.unwrap_or_else(|| format!("resp-{}", Uuid::new_v4())) but never insert it
into RESP_STORE, causing later GET/cancel to 404; fix by calling the existing
helper store_response_for_port (or otherwise inserting into RESP_STORE) with
config.port and the generated rid immediately after you create rid (i.e., in the
is_background branch where rid is set) so the background-generated id is
recorded for lookup; reference symbols: responses_handler, is_background,
req_id, rid, RESP_STORE, store_response_for_port.
model_gateway/src/core/steps/worker/local/discover_metadata.rs (1)

18-27: ⚠️ Potential issue | 🟡 Minor

Handle HTTP client initialization failures gracefully instead of panicking.

reqwest::Client::builder().build() can fail for multiple reasons per the official documentation: TLS backend initialization, DNS resolver configuration issues, invalid TLS version/certificate settings, or unrecognized TLS backends. While some are infrastructure-level issues, the current expect() will crash the process on first HTTP use. Since this codebase has a gRPC fallback path (via ConnectionMode), HTTP client build failures should be propagated as errors rather than causing a panic.

Wrap the HTTP_CLIENT initialization in a Lazy<Result<Client, _>> and propagate the error from HTTP-only call sites:

Suggested pattern
-static HTTP_CLIENT: Lazy<Client> = Lazy::new(|| {
-    Client::builder()
-        .timeout(Duration::from_secs(10))
-        .build()
-        .expect("Failed to create HTTP client")
-});
+static HTTP_CLIENT: Lazy<Result<Client, reqwest::Error>> = Lazy::new(|| {
+    Client::builder()
+        .timeout(Duration::from_secs(10))
+        .build()
+});

Then in get_json_with_fallback and http_get_json:

-    let mut req = HTTP_CLIENT.get(&url);
+    let client = HTTP_CLIENT
+        .as_ref()
+        .map_err(|e| format!("Failed to create HTTP client: {e}"))?;
+    let mut req = client.get(&url);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/core/steps/worker/local/discover_metadata.rs` around lines
18 - 27, The static HTTP_CLIENT currently panics on build failure; change its
type to Lazy<Result<Client, reqwest::Error>> and return the build error instead
of calling expect, then update call sites (get_json_with_fallback and
http_get_json) to handle the Result by propagating an Err when HTTP_CLIENT is
Err and only use the Client when Ok(client), falling back to the existing gRPC
path via ConnectionMode; ensure error types are converted/mapped to the
function's error return so callers receive a propagated error instead of the
process panicking.
model_gateway/src/routers/grpc/regular/streaming.rs (1)

1200-1214: 🧹 Nitpick | 🔵 Trivial

Consider context struct pattern for argument reduction.

This function has 13 parameters. The PR introduces GenerateStreamContext (lines 46-53) to reduce arguments for generate streaming. A similar ChatStreamContext struct could bundle common parameters (request_id, model, created, system_fingerprint, history_tool_calls_count) for cleaner signatures in chat streaming helpers.

Not blocking, as the #[expect(clippy::too_many_arguments)] is appropriate for now.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/regular/streaming.rs` around lines 1200 -
1214, The function process_tool_calls_stream currently accepts 13 parameters;
create a ChatStreamContext struct (similar to GenerateStreamContext) that
bundles common chat-streaming fields (request_id, model, created,
system_fingerprint, history_tool_calls_count and any other repeated metadata)
and replace those individual parameters in process_tool_calls_stream with a
single &ChatStreamContext argument; update any helper calls and signatures that
pass those same fields to accept &ChatStreamContext, and ensure tool_parsers,
has_tool_calls, tools, delta, index, and use_json_parser remain as explicit
params so callers and semantics are unchanged aside from the reduced argument
list.
bindings/golang/src/tool_parser.rs (1)

223-234: ⚠️ Potential issue | 🟡 Minor

Silent JSON parsing failure may hide tool configuration errors.

When tools_json is non-null but contains invalid JSON, unwrap_or_default() at line 233 silently returns an empty Vec<Tool>. This could mask configuration errors from callers who provided malformed tool definitions.

Consider returning an error to the caller instead of silently falling back to an empty vector, similar to how UTF-8 errors are handled on lines 228-231.

Proposed fix
     let tools: Vec<Tool> = if tools_json.is_null() {
         vec![]
     } else {
         let tools_str = match CStr::from_ptr(tools_json).to_str() {
             Ok(s) => s,
             Err(_) => {
                 set_error_message(error_out, "Invalid UTF-8 in tools_json");
                 return SglErrorCode::InvalidArgument;
             }
         };
-        serde_json::from_str::<Vec<Tool>>(tools_str).unwrap_or_default()
+        match serde_json::from_str::<Vec<Tool>>(tools_str) {
+            Ok(t) => t,
+            Err(e) => {
+                set_error_message(error_out, &format!("Failed to parse tools JSON: {e}"));
+                return SglErrorCode::ParsingError;
+            }
+        }
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/golang/src/tool_parser.rs` around lines 223 - 234, The JSON parsing
currently uses serde_json::from_str(...).unwrap_or_default(), which silently
drops malformed JSON; change this to handle the Result from serde_json::from_str
for Vec<Tool> and on Err call set_error_message(error_out, "<descriptive
message>") with the serde_json error text and return
SglErrorCode::InvalidArgument (mirroring the UTF-8 error path). Specifically,
replace the unwrap_or_default branch that produces tools with a match on
serde_json::from_str::<Vec<Tool>>(tools_str) so that Ok(v) sets tools = v and
Err(e) sets an error message (include e.to_string()) and returns
SglErrorCode::InvalidArgument.
model_gateway/src/routers/http/router.rs (1)

134-145: ⚠️ Potential issue | 🟠 Major

Model routing ignores model_id in non-IGW mode, causing incorrect worker selection.

When enable_igw=false, effective_model_id is set to None (line 140), causing get_workers_filtered() to return all workers regardless of the provided model_id. The hash ring then falls back to UNKNOWN_MODEL_ID. This contradicts RouterManager's behavior, which preserves model_id in non-IGW mode using .or(model_id). If workers are registered with specific models, requests will route to the wrong pool. Either model-aware routing should be consistently applied in non-IGW mode, or this behavior needs explicit justification if single-model deployment is required.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/http/router.rs` around lines 134 - 145,
select_worker_for_model currently forces effective_model_id to None when
enable_igw is false, causing get_workers_filtered to ignore the provided
model_id and fallback to UNKNOWN_MODEL_ID; change the logic to preserve the
incoming model_id in non-IGW mode (match RouterManager behavior) so
get_workers_filtered receives either the IGW-resolved id or the original
model_id: adjust the computation of effective_model_id in
select_worker_for_model (and any related callers) to use the IGW-resolved id
when enable_igw is true, otherwise pass through the provided model_id, ensuring
get_workers_filtered and the hash ring get the correct model identifier
(reference: select_worker_for_model, effective_model_id, get_workers_filtered,
RouterManager, UNKNOWN_MODEL_ID).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@kv_index/src/string_tree.rs`:
- Around line 481-484: The code currently silently returns when
contracted_text.first_char() is None, dropping the insert on an invariant
violation; replace this silent early-return with a fail-fast assertion (e.g.,
use unreachable! or panic!) so corruption is surfaced. Specifically, in the
block that checks let Some(first_new_char) = contracted_text.first_char() else {
... }, remove the return and instead call unreachable! or panic! with a message
that includes context (e.g., mention split_at_char, shared_count < char_count,
and include contracted_text or its length) so the invariant failure is explicit
and debuggable.

In `@mcp/src/core/oauth.rs`:
- Around line 149-155: The background OAuth callback server spawned in the
tokio::spawn block currently moves the listener into the task and never shuts
down, so replace the fire-and-forget axum::serve(listener, app).await with a
graceful shutdown: create a oneshot shutdown signal (sender/receiver) in the
scope where the auth flow completes, move the receiver into the spawned task and
call axum::Server::from_tcp(listener)?.with_graceful_shutdown(async {
receiver.await.ok(); }).serve(app.into_make_service()).await (i.e., use
with_graceful_shutdown), and send the shutdown signal (sender.send(())) right
after the authorization code is received so the listener is closed and the port
is released; update any error handling around tokio::spawn and
axum::serve(listener, app) accordingly.

In `@model_gateway/src/core/token_bucket.rs`:
- Around line 58-63: Validate token inputs at the public API boundaries: in
try_acquire (and its call to try_acquire_sync), acquire, and return_tokens check
that the provided tokens value is finite (not NaN/inf), not negative, and does
not exceed the bucket capacity; for invalid values return a failure immediately
(e.g., Err(()) for try_acquire) instead of proceeding, and keep the existing
behavior for valid inputs by delegating to try_acquire_sync or the existing
implementation after the guard.

In `@model_gateway/src/middleware.rs`:
- Around line 425-428: The #[expect(..., reason = "...")] attached to the
clippy::disallowed_methods attribute has an inaccurate reason string; update the
reason to state that the spawned, fire-and-forget task is bounded by
remaining_timeout (used with acquire_timeout) rather than the request lifetime,
and note that dropping the oneshot receiver does not cancel the spawned task—it
only notifies the sender while the task continues until acquire_timeout
completes or the runtime shuts down; change the reason text accordingly on the
#[expect(...)] for clarity.

In `@model_gateway/src/policies/bucket.rs`:
- Around line 147-169: The bucket state isn't fully reset when the last URL is
removed—stale entries remain in boundary and chars_per_url causing invalid
selections; after computing updated_len and updated_urls (from
bucket_guard.prefill_worker_urls and bucket_guard.chars_per_url), set
bucket_guard.bucket_cnt and always call
bucket_guard.init_prefill_worker_urls(updated_urls) (do not only call it when
updated_len>0), and when updated_len == 0 explicitly clear/reset remaining
state: clear bucket_guard.boundary and clear the chars_per_url map (via the
chars_per_url lock) so the bucket has no leftover entries.
- Around line 116-137: The code always reinitializes bucket state even when the
worker_url already exists; change add_prefill_url so you detect whether the push
actually inserted a new URL (by checking prefill_worker_urls.contains before
mutation) and only when it's newly inserted perform
chars_per_url.entry(worker_url.clone()).or_insert(0) and call
bucket_guard.init_prefill_worker_urls(cloned); otherwise skip the init and skip
zeroing per-URL state to preserve balancing history, and adjust the info! log to
only report "Added worker ..." when insertion occurred (log a different message
or skip logging for duplicates).

In `@model_gateway/src/routers/grpc/client.rs`:
- Around line 189-194: Replace the panic in the fallback match arm that
currently calls panic!("Mismatched client and request types") with returning a
proper Err value so callers can handle the mismatch; locate the match containing
the arm `_ => panic!("Mismatched client and request types")` in client.rs and
change it to return an error (e.g., Err("Mismatched client and request
types".into()) or a typed crate error) consistent with the surrounding
function's Result return type (adjust the function signature to return Result if
needed), and preserve the `#[expect(...)]` comment if you want to keep the
invariant noted.
- Around line 206-211: The catch-all match arm currently panics ("Mismatched
client and request types or unsupported embedding backend"); change it to return
a gRPC error for unsupported backends instead of panicking: in the match inside
the client implementation in client.rs, replace the `_ => panic!(...)` arm with
logic that detects unsupported embedding backends and returns an appropriate
tonic::Status (e.g., Status::unimplemented or Status::invalid_argument with a
clear message like "unsupported embedding backend"), while keeping any explicit
panic/expect for true invariant violations (mismatched client/request types) if
you must; reference the existing match and the `_ =>` arm to locate where to
return Err(Status::...) so callers receive a proper error instead of a panic.

In `@model_gateway/src/routers/grpc/regular/streaming.rs`:
- Around line 372-417: The code currently discards normal content when tool
parsing fails because process_tool_calls_stream returns an empty Vec and the
surrounding code unconditionally continues; change process_tool_calls_stream
(and/or process_specific_function_stream) to surface parse failures (e.g.,
return Result<Vec<Chunk>, ParseError> or include a parse_failed flag), then in
the caller check that result: on Ok(chunks) behave as today, but on Err(_) (or
parse_failed) log the error (include request_id/model) and do NOT execute the
continue so the delta falls through to regular content emission; alternatively,
if you prefer to keep the current signature, make it return a tuple (chunks,
parse_failed:bool) and only continue when parse_failed == false and chunks are
non-empty—also consider referencing get_unstreamed_tool_args if you opt to
implement buffering instead of falling through.

In `@model_gateway/tests/metrics_aggregator_test.rs`:
- Around line 260-261: The call to assert_eq_sorted(result.trim(),
expected.trim()) uses redundant .trim() calls because assert_eq_sorted already
trims both inputs; remove the .trim() invocations and pass result and expected
directly to assert_eq_sorted to match the other test usage and avoid
double-trimming.

In `@model_gateway/tests/otel_tracing_test.rs`:
- Around line 249-254: The assertion currently uses exact equality on span_count
and an inconsistent error message; change the check in the test (reference
span_count) to assert that span_count >= 2 if the intent is "at least 2 spans",
update the assertion message to read "Expected to receive at least 2 spans, but
got {}." and use proper formatting placeholder with span_count as an argument,
and likewise update the println to "Test passed! Collector received {} spans"
with span_count passed to the formatter so pluralization and interpolation are
correct.

In `@multimodal/src/tracker.rs`:
- Around line 166-169: The reason string on the
#[expect(clippy::disallowed_methods, reason = "...")] attribute incorrectly
references resolve(); update that explanatory text to reference finalize() (the
actual method that awaits pending tasks) so the attribute accurately describes
why the disallowed method is allowed for the spawn handle stored in
self.pending; locate the expect attribute applied to the spawn/fire-and-forget
block in tracker.rs and change "resolve()" to "finalize()".

In `@protocols/src/responses.rs`:
- Around line 930-933: The inline comment above the guard uses the `// SAFETY:`
prefix which is reserved for explanations around unsafe blocks; rename it to `//
INVARIANT:` (or `// Note:`) to indicate this documents a safe code invariant and
avoid confusion—update the comment immediately above the `let Some(tools) =
request.tools.as_ref() else { return Ok(()); };` guard in the `responses.rs`
code so it reads `// INVARIANT:` (or `// Note:`) and leave the rest of the
explanatory text unchanged.

In `@protocols/src/worker.rs`:
- Around line 338-343: The match arm handling the single-element case is overly
defensive: after checking models.len() == 1, calling models.into_iter().next()
cannot return None, yet the code falls back to Self::Wildcard; replace the
fallback with a direct unwrap/expect so the invariant is explicit — i.e., in the
branch that uses models.into_iter().next() for construction of
Self::Single(Box::new(...)), swap the conditional Some(...) else { return
Self::Wildcard } for models.into_iter().next().expect("expected one model when
models.len() == 1") and construct Self::Single from that value, removing the
unreachable Wildcard fallback.

---

Outside diff comments:
In `@bindings/golang/src/tool_parser.rs`:
- Around line 223-234: The JSON parsing currently uses
serde_json::from_str(...).unwrap_or_default(), which silently drops malformed
JSON; change this to handle the Result from serde_json::from_str for Vec<Tool>
and on Err call set_error_message(error_out, "<descriptive message>") with the
serde_json error text and return SglErrorCode::InvalidArgument (mirroring the
UTF-8 error path). Specifically, replace the unwrap_or_default branch that
produces tools with a match on serde_json::from_str::<Vec<Tool>>(tools_str) so
that Ok(v) sets tools = v and Err(e) sets an error message (include
e.to_string()) and returns SglErrorCode::InvalidArgument.

In `@data_connector/src/memory.rs`:
- Around line 237-258: delete_item currently acquires rev_index then links,
which can deadlock with link_item that acquires links then rev_index; change
delete_item to acquire locks in the same order as link_item (links then
rev_index) by first taking a write lock on self.links to remove any entry for
conversation_id and capture the key to remove, then taking a write lock on
self.rev_index to remove the corresponding rev_index entry (or vice‑versa if you
prefer the canonical order links → rev_index used across the codebase); update
the logic in delete_item to use that single consistent ordering and ensure you
still only hold each lock for the minimal time while preserving the same
behavior.

In `@grpc_client/src/sglang_scheduler.rs`:
- Around line 520-528: The match on constraint_type (creating tool_constraint)
misses the "grammar" alias and currently only handles "ebnf", causing "grammar"
inputs to hit the default Unknown constraint error; update the match in the
block that builds tool_constraint (the match over constraint_type.as_str() that
produces proto::sampling_params::Constraint variants) to accept "grammar" as an
additional arm mapping to
proto::sampling_params::Constraint::EbnfGrammar(constraint_value) (e.g., add a
"grammar" => proto::...::EbnfGrammar(constraint_value) branch or combine it with
the "ebnf" arm).
- Around line 580-588: The match in build_constraint_for_responses is missing
the "grammar" alias (same inconsistency as build_constraint_for_chat); update
the match on constraint_type in build_constraint_for_responses to treat
"grammar" the same as "ebnf" (e.g., match "ebnf" | "grammar" =>
proto::sampling_params::Constraint::EbnfGrammar(constraint_value)) so both
aliases produce an EbnfGrammar constraint.

In `@mcp/src/approval/manager.rs`:
- Around line 261-270: The match on decision when building result contains an
unreachable ApprovalDecision::Approved arm and a misleading "User denied"
message; update the match in the Denied branch of result (where approved is
false) to handle only the expected ApprovalDecision::Denied case and replace the
Approved arm with an explicit unreachable!() (or other assertion) to make the
invariant clear — locate the creation of result and the match over
ApprovalDecision to remove the incorrect fallback and use unreachable!() (or
panic/assert) for the Approved variant so the code documents the invariant and
avoids the misleading string.

In `@model_gateway/build.rs`:
- Around line 13-20: The current build script silently falls back to
DEFAULT_VERSION and an empty host when read_cargo_version() or get_rustc_host()
fail; update the logic around read_cargo_version()/DEFAULT_VERSION and
get_rustc_host()/TARGET to emit a visible warning (e.g.,
println!("cargo:warning=...")) when those functions return Err or when you use
DEFAULT_VERSION/get_rustc_host defaulting, or optionally return a non-zero exit
(panic!) if version/target must be required; specifically, wrap the calls to
read_cargo_version() and get_rustc_host() so failures produce a cargo:warning
with context (including the error) before applying DEFAULT_VERSION or empty
target, referencing the read_cargo_version, get_rustc_host, DEFAULT_VERSION, and
the TARGET/PROFILE env var logic so the warning appears during cargo build.

In `@model_gateway/src/core/steps/worker/local/discover_metadata.rs`:
- Around line 18-27: The static HTTP_CLIENT currently panics on build failure;
change its type to Lazy<Result<Client, reqwest::Error>> and return the build
error instead of calling expect, then update call sites (get_json_with_fallback
and http_get_json) to handle the Result by propagating an Err when HTTP_CLIENT
is Err and only use the Client when Ok(client), falling back to the existing
gRPC path via ConnectionMode; ensure error types are converted/mapped to the
function's error return so callers receive a propagated error instead of the
process panicking.

In `@model_gateway/src/policies/cache_aware.rs`:
- Around line 155-160: In set_mesh_sync, avoid the unnecessary clone of
mesh_sync by checking mesh_sync.is_some() first and then moving mesh_sync into
the struct field only when needed; specifically, use the OptionalMeshSyncManager
parameter directly (move it into self.mesh_sync) instead of calling
self.mesh_sync.clone_from(&mesh_sync), and call restore_tree_state_from_mesh()
after the move when mesh_sync was Some; reference: function set_mesh_sync,
parameter mesh_sync, field self.mesh_sync, and method
restore_tree_state_from_mesh.

In `@model_gateway/src/policies/consistent_hashing.rs`:
- Around line 163-177: The current two-pass logic over workers risks TOCTOU:
between counting healthy workers and selecting the nth healthy, health can
change and idx become None while healthy_count > 0; fix by performing a single
pass to collect the indices of healthy workers (use
workers.iter().enumerate().filter(|(_, w)| w.is_healthy()).map(|(i, _)|
i).collect::<Vec<_>>()), then if the collected Vec is empty return (None,
Branch::NoHealthyWorkers), otherwise choose a random index within that Vec
(replace random_healthy_idx with
rand::rng().random_range(0..healthy_indices.len())) and return
(Some(healthy_indices[random_idx]), Branch::RandomFallback) so selection cannot
race with the count.

In `@model_gateway/src/routers/grpc/regular/streaming.rs`:
- Around line 1200-1214: The function process_tool_calls_stream currently
accepts 13 parameters; create a ChatStreamContext struct (similar to
GenerateStreamContext) that bundles common chat-streaming fields (request_id,
model, created, system_fingerprint, history_tool_calls_count and any other
repeated metadata) and replace those individual parameters in
process_tool_calls_stream with a single &ChatStreamContext argument; update any
helper calls and signatures that pass those same fields to accept
&ChatStreamContext, and ensure tool_parsers, has_tool_calls, tools, delta,
index, and use_json_parser remain as explicit params so callers and semantics
are unchanged aside from the reduced argument list.

In `@model_gateway/src/routers/grpc/utils.rs`:
- Around line 932-941: The conversion currently swallows tokenizer.decode errors
in convert_proto_to_openai_logprobs; update the closure passed to
convert_proto_logprobs so that when tokenizer.decode(&[token_id], false) returns
Err(e) you log a warning (e.g., tracing::warn! or log::warn!) including the
token_id and the error, then return the same fallback
format!("<token_{token_id}>"). Keep the call target symbols:
convert_proto_to_openai_logprobs, convert_proto_logprobs, and tokenizer.decode.
- Around line 452-468: The code currently unconditionally pops the last
assistant message when request.continue_final_message is true, which discards
messages whose "content" is non-string; change the logic in the block that uses
continue_final_message and transformed_messages so you inspect
transformed_messages.last() (check its "role" == "assistant" and its
"content".as_str() is Some) before calling pop; only call
transformed_messages.pop() after confirming the content is a string and bind
that to last_msg, otherwise leave the message in place and proceed to build
ProcessedMessages without removing it (refer to continue_final_message,
transformed_messages, last_msg, and the ProcessedMessages return).

In `@model_gateway/src/routers/http/router.rs`:
- Around line 134-145: select_worker_for_model currently forces
effective_model_id to None when enable_igw is false, causing
get_workers_filtered to ignore the provided model_id and fallback to
UNKNOWN_MODEL_ID; change the logic to preserve the incoming model_id in non-IGW
mode (match RouterManager behavior) so get_workers_filtered receives either the
IGW-resolved id or the original model_id: adjust the computation of
effective_model_id in select_worker_for_model (and any related callers) to use
the IGW-resolved id when enable_igw is true, otherwise pass through the provided
model_id, ensuring get_workers_filtered and the hash ring get the correct model
identifier (reference: select_worker_for_model, effective_model_id,
get_workers_filtered, RouterManager, UNKNOWN_MODEL_ID).

In `@model_gateway/src/routers/parse/handlers.rs`:
- Around line 57-62: The error logging and error_response calls in this handler
use mixed format styles (some use "{}", var and one uses "{e}"); make them
consistent by switching all format strings in this function to the inline
named-argument style (e.g., error!("Failed to parse function calls: {e}") and
error_response(StatusCode::BAD_REQUEST, &format!("Failed to parse function
calls: {e}")), and update the other error! and format! calls in the same
function (the ones using "{}", var) to the {name} form so all uses (error!,
format!, error_response) consistently use named inline placeholders.
- Around line 94-99: The log and response formatting in the Err(e) arm are
inconsistent: the error! macro uses positional "{}" while the error_response
uses inline "{e}"; update both places to the same style (pick one
convention—e.g., use "{}" for both) so the error message for "Failed to separate
reasoning" is formatted consistently across error! and error_response calls in
handlers.rs (identify the error! invocation and the error_response(...
format!(...)) call and make them use the same formatter).

In `@model_gateway/tests/common/mock_worker.rs`:
- Around line 592-1099: In responses_handler, when handling the is_background
branch you generate a rid via req_id.unwrap_or_else(|| format!("resp-{}",
Uuid::new_v4())) but never insert it into RESP_STORE, causing later GET/cancel
to 404; fix by calling the existing helper store_response_for_port (or otherwise
inserting into RESP_STORE) with config.port and the generated rid immediately
after you create rid (i.e., in the is_background branch where rid is set) so the
background-generated id is recorded for lookup; reference symbols:
responses_handler, is_background, req_id, rid, RESP_STORE,
store_response_for_port.

---

Duplicate comments:
In `@model_gateway/src/routers/grpc/proto_wrapper.rs`:
- Around line 483-528: The typed accessors as_sglang, as_sglang_mut, as_vllm,
and as_trtllm currently panic on a variant mismatch; update all call sites that
use these functions to first check the corresponding predicate (is_sglang,
is_vllm, is_trtllm) before calling the accessor, or replace usage with a safe
non-panicking alternative by adding
try_as_sglang/try_as_sglang_mut/try_as_vllm/try_as_trtllm that return
Option<&...>/Option<&mut ...> (or Result) and refactor callers to handle the
None/Error case. Ensure changes reference the methods as_sglang, as_sglang_mut,
as_vllm, as_trtllm and their predicate helpers is_sglang/is_vllm/is_trtllm so no
panics occur unexpectedly.
- Around line 345-378: The typed accessors as_sglang, as_vllm, and as_trtllm
currently panic on mismatches; add non-panicking alternatives (e.g.
try_as_sglang -> Option<&sglang::GenerateStreamChunk>, try_as_vllm ->
Option<&vllm::GenerateStreamChunk>, try_as_trtllm ->
Option<&trtllm::GenerateStreamChunk>) and update call sites to use these safe
helpers or explicitly check is_sglang()/is_vllm()/is_trtllm() before calling the
panicking as_* methods; keep the existing as_* for hot paths if you still want
panics but prefer callers to use try_as_* for correctness.

Comment on lines +481 to +484
let Some(first_new_char) = contracted_text.first_char() else {
// split_at_char with shared_count < char_count guarantees non-empty suffix
return;
};

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Avoid silent early-return on an invariant break.
This branch should be unreachable; returning will silently drop the insert if the invariant is violated. Prefer a fail-fast expectation so corruption is surfaced.

Proposed change
-                        let Some(first_new_char) = contracted_text.first_char() else {
-                            // split_at_char with shared_count < char_count guarantees non-empty suffix
-                            return;
-                        };
+                        let first_new_char = contracted_text
+                            .first_char()
+                            .expect("split_at_char with shared_count < char_count must yield non-empty suffix");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let Some(first_new_char) = contracted_text.first_char() else {
// split_at_char with shared_count < char_count guarantees non-empty suffix
return;
};
let first_new_char = contracted_text
.first_char()
.expect("split_at_char with shared_count < char_count must yield non-empty suffix");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@kv_index/src/string_tree.rs` around lines 481 - 484, The code currently
silently returns when contracted_text.first_char() is None, dropping the insert
on an invariant violation; replace this silent early-return with a fail-fast
assertion (e.g., use unreachable! or panic!) so corruption is surfaced.
Specifically, in the block that checks let Some(first_new_char) =
contracted_text.first_char() else { ... }, remove the return and instead call
unreachable! or panic! with a message that includes context (e.g., mention
split_at_char, shared_count < char_count, and include contracted_text or its
length) so the invariant failure is explicit and debuggable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid observation about invariant enforcement. However, changing error-handling behavior from a defensive return to a panic is a behavioral change beyond the scope of this clippy-focused PR. The defensive return avoids panics in production — a corrupted index is preferable to a crashed server. Will consider converting to debug_assert\! in a follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Totally fair—agree we shouldn’t change runtime behavior in this Clippy PR. Let’s keep the defensive early-return.

If helpful, I can open a follow-up issue to:

  • replace the early-return with a debug_assert!(...) so it’s caught in debug/tests but remains non-panicking in release
  • add a short comment explaining the invariant and why we choose a defensive return in release
  • optionally add a tracing::warn! behind cfg(debug_assertions) for extra visibility during dev

Want me to file that issue and link back to this discussion?


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: kv_index/src/string_tree.rs:481-484
Timestamp: 2026-02-21T02:30:52.128Z
Learning: Preference noted: In kv_index/src/string_tree.rs (Rust radix tree), production code should avoid panics on invariant breaches; prefer a defensive non-panicking path (e.g., early return) and use debug_assert! for debug/test builds. Consider documenting the invariant with a comment, and optionally log under cfg(debug_assertions).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread mcp/src/core/oauth.rs
Comment on lines +149 to 155
#[expect(
clippy::disallowed_methods,
reason = "fire-and-forget OAuth callback server; runs until listener drops when auth flow completes"
)]
tokio::spawn(async move {
let _ = axum::serve(listener, app).await;
});

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the oauth.rs file
fd "oauth.rs" --type f

Repository: lightseekorg/smg

Length of output: 81


🏁 Script executed:

# Read the oauth.rs file to understand the context
wc -l mcp/src/core/oauth.rs

Repository: lightseekorg/smg

Length of output: 85


🏁 Script executed:

# Get the specific lines mentioned in the review and surrounding context
sed -n '130,170p' mcp/src/core/oauth.rs | cat -n

Repository: lightseekorg/smg

Length of output: 1673


🏁 Script executed:

# Search for the entire function containing this code to understand the full context
ast-grep --pattern $'fn $FUNC($$$) {
  $$$
  tokio::spawn(async move {
    let _ = axum::serve(listener, app).await;
  });
  $$$
}'

Repository: lightseekorg/smg

Length of output: 42


🏁 Script executed:

# Let's look at a larger section to see the full function
sed -n '100,170p' mcp/src/core/oauth.rs | cat -n

Repository: lightseekorg/smg

Length of output: 3004


🏁 Script executed:

# Also search for where this function is defined to see the full signature
rg "fn.*auth.*\{" mcp/src/core/oauth.rs -A 30

Repository: lightseekorg/smg

Length of output: 42


🏁 Script executed:

# Check if there's any cleanup or shutdown logic elsewhere
rg "shutdown|drop|cancel" mcp/src/core/oauth.rs

Repository: lightseekorg/smg

Length of output: 172


🏁 Script executed:

# Search for all calls to start_callback_server to see if it's called multiple times
rg "start_callback_server" mcp/src/core/oauth.rs

Repository: lightseekorg/smg

Length of output: 185


🏁 Script executed:

# Look at the callback handler to see if code_sender is consumed and what happens when callback is received
sed -n '70,100p' mcp/src/core/oauth.rs | cat -n

Repository: lightseekorg/smg

Length of output: 1187


🏁 Script executed:

# Check if there are any tests that show multiple auth attempts
fd "test" --type f | xargs rg "start_callback_server|OAuth" | head -20

Repository: lightseekorg/smg

Length of output: 42


🏁 Script executed:

# Get the callback_handler implementation to see when code_sender is called
sed -n '69,130p' mcp/src/core/oauth.rs | cat -n

Repository: lightseekorg/smg

Length of output: 2546


🏁 Script executed:

# Search for where OAuthHelper::authenticate is called to see if it's called multiple times
rg "authenticate\(" mcp/src/core --type rust -B 2 -A 2

Repository: lightseekorg/smg

Length of output: 700


🏁 Script executed:

# Get the full callback handler implementation
sed -n '69,120p' mcp/src/core/oauth.rs | cat -n

Repository: lightseekorg/smg

Length of output: 2074


🏁 Script executed:

# Check if OAuthHelper is reused or created fresh each time
rg "OAuthHelper::new|OAuthHelper {" mcp/src --type rust -B 2 -A 2

Repository: lightseekorg/smg

Length of output: 183


🏁 Script executed:

# Get callback_handler to see the full implementation
rg "callback_handler" mcp/src/core/oauth.rs -A 15

Repository: lightseekorg/smg

Length of output: 1145


🏁 Script executed:

# Check usage of OAuthHelper
rg "OAuthHelper::new" mcp/src --type rust -B 2 -A 5

Repository: lightseekorg/smg

Length of output: 576


🏁 Script executed:

# See if authenticate is called in a loop or multiple times
rg "\.authenticate\(" mcp/src --type rust -B 5 -A 5

Repository: lightseekorg/smg

Length of output: 694


🏁 Script executed:

# Verify the comment's claim about listener dropping - check the full function signature
head -70 mcp/src/core/oauth.rs | tail -40

Repository: lightseekorg/smg

Length of output: 1093


Implement graceful shutdown of the OAuth callback server.

The spawned background server keeps the port bound indefinitely after the auth code is received, preventing subsequent authentication attempts from binding to the same port. The misleading comment suggests the listener drops when auth completes, but the listener is moved into the spawned task and never released until process exit.

Implement graceful shutdown using with_graceful_shutdown() to close the server once the authorization code is received:

🔧 Suggested graceful shutdown
-        let (code_sender, code_receiver) = oneshot::channel::<String>();
+        let (code_sender, code_receiver) = oneshot::channel::<String>();
+        let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();
@@
-        tokio::spawn(async move {
-            let _ = axum::serve(listener, app).await;
-        });
+        tokio::spawn(async move {
+            let _ = axum::serve(listener, app)
+                .with_graceful_shutdown(async move {
+                    let _ = shutdown_rx.await;
+                })
+                .await;
+        });
@@
-        code_receiver
-            .await
-            .map_err(|_| McpError::Auth("Failed to receive authorization code".to_string()))
+        let code = code_receiver
+            .await
+            .map_err(|_| McpError::Auth("Failed to receive authorization code".to_string()))?;
+        let _ = shutdown_tx.send(());
+        Ok(code)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/src/core/oauth.rs` around lines 149 - 155, The background OAuth callback
server spawned in the tokio::spawn block currently moves the listener into the
task and never shuts down, so replace the fire-and-forget axum::serve(listener,
app).await with a graceful shutdown: create a oneshot shutdown signal
(sender/receiver) in the scope where the auth flow completes, move the receiver
into the spawned task and call
axum::Server::from_tcp(listener)?.with_graceful_shutdown(async {
receiver.await.ok(); }).serve(app.into_make_service()).await (i.e., use
with_graceful_shutdown), and send the shutdown signal (sender.send(())) right
after the authorization code is received so the listener is closed and the port
is released; update any error handling around tokio::spawn and
axum::serve(listener, app) accordingly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid observation about resource cleanup. Adding graceful shutdown logic is a behavioral change beyond the scope of this clippy-focused PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Thanks—agreed to keep the graceful-shutdown change out of this clippy-focused PR.

Non-behavioral tweak (optional for this PR)

  • To avoid a misleading note in the lint expectation, we can update the reason string without touching runtime behavior:
#[expect(
    clippy::disallowed_methods,
    reason = "fire-and-forget OAuth callback server; temporary: listener remains bound for the session; graceful shutdown will be added in a follow-up"
)]
tokio::spawn(async move {
    let _ = axum::serve(listener, app).await;
});

Would you like me to open a follow-up issue?
Proposed details:

  • Title: OAuth callback server should shut down after code receipt (release port)
  • Summary: start_callback_server spawns axum::serve and never stops; subsequent auth attempts can’t bind the same port.
  • Acceptance criteria:
    • Use with_graceful_shutdown driven by a oneshot triggered when the auth code is received.
    • Ensure the port is released and a second authentication flow in the same process can rebind.
    • Keep the clippy #[expect] with an updated reason that reflects the new behavior.
  • I can file it and assign it to you.

If you prefer, I can just land the tiny reason-string tweak here and leave the issue creation for later.

(=^・^=)兔 Thoughtful: noted the scope preference and queued a clean follow-up path.

Comment on lines +58 to 63
#[expect(
clippy::result_unit_err,
reason = "Try-acquire pattern: callers only need success/failure, a custom error type adds no information"
)]
pub fn try_acquire(&self, tokens: f64) -> Result<(), ()> {
self.try_acquire_sync(tokens)

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate token amounts to preserve bucket invariants.

Allowing negative/non‑finite or >capacity values can increase the bucket or lead to requests that can never be satisfied (e.g., refill_rate == 0 waits forever). Add validation at the public entry points (try_acquire/return_tokens/acquire) to reject invalid token values.

🛡️ Proposed guard at the API boundary
pub fn try_acquire(&self, tokens: f64) -> Result<(), ()> {
+    if !tokens.is_finite() || tokens < 0.0 || tokens > self.capacity {
+        return Err(());
+    }
     self.try_acquire_sync(tokens)
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[expect(
clippy::result_unit_err,
reason = "Try-acquire pattern: callers only need success/failure, a custom error type adds no information"
)]
pub fn try_acquire(&self, tokens: f64) -> Result<(), ()> {
self.try_acquire_sync(tokens)
#[expect(
clippy::result_unit_err,
reason = "Try-acquire pattern: callers only need success/failure, a custom error type adds no information"
)]
pub fn try_acquire(&self, tokens: f64) -> Result<(), ()> {
if !tokens.is_finite() || tokens < 0.0 || tokens > self.capacity {
return Err(());
}
self.try_acquire_sync(tokens)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/core/token_bucket.rs` around lines 58 - 63, Validate token
inputs at the public API boundaries: in try_acquire (and its call to
try_acquire_sync), acquire, and return_tokens check that the provided tokens
value is finite (not NaN/inf), not negative, and does not exceed the bucket
capacity; for invalid values return a failure immediately (e.g., Err(()) for
try_acquire) instead of proceeding, and keep the existing behavior for valid
inputs by delegating to try_acquire_sync or the existing implementation after
the guard.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid hardening suggestion. Adding new input validation logic is a behavioral change out of scope for this clippy lint PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Thanks — agreed. Let’s keep this PR strictly to lint/mechanical changes.

If helpful, I can open a follow-up issue to track the hardening. Proposed scope:

  • Validate inputs in TokenBucket:
    • try_acquire: return Err(()) for non-finite, negative, or >capacity requests.
    • return_tokens: ignore/reject non-finite or negative amounts; continue capping at capacity for large returns.
  • Add brief rustdoc on valid token ranges and invariants.
  • Add unit tests for the above.

Would you like me to file that issue and reference this PR?


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread model_gateway/src/middleware.rs
Comment on lines +116 to +137
let mut bucket_guard = bucket.write();
let worker_url = worker.url().to_string();

let prefill_worker_urls_clone = {
let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock().unwrap();
if !prefill_worker_urls.contains(&worker_url) {
prefill_worker_urls.push(worker_url.clone());
}
let cloned = prefill_worker_urls.clone();
let prefill_worker_urls_clone = {
let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock();
if !prefill_worker_urls.contains(&worker_url) {
prefill_worker_urls.push(worker_url.clone());
}
let cloned = prefill_worker_urls.clone();

let mut chars_per_url = bucket_guard.chars_per_url.lock().unwrap();
chars_per_url.entry(worker_url.clone()).or_insert(0);
let mut chars_per_url = bucket_guard.chars_per_url.lock();
chars_per_url.entry(worker_url.clone()).or_insert(0);

cloned
};
cloned
};

bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);

info!(
"Added worker {} to bucket for model {}",
worker_url, model_key
);
} else {
error!(
"Failed to acquire write lock for bucket of model {}",
model_key
);
}
info!(
"Added worker {} to bucket for model {}",
worker_url, model_key
);

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid reinitializing bucket state on duplicate add.

If add_prefill_url is called for a URL that’s already present, the current flow still reinitializes boundaries and zeroes per‑URL load state. That can wipe balancing history on duplicate registration/health events. Consider reinitializing only when a URL is newly inserted (and log accordingly).

🛠️ Suggested adjustment
-        let prefill_worker_urls_clone = {
-            let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock();
-            if !prefill_worker_urls.contains(&worker_url) {
-                prefill_worker_urls.push(worker_url.clone());
-            }
-            let cloned = prefill_worker_urls.clone();
+        let (inserted, prefill_worker_urls_clone) = {
+            let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock();
+            if prefill_worker_urls.contains(&worker_url) {
+                (false, prefill_worker_urls.clone())
+            } else {
+                prefill_worker_urls.push(worker_url.clone());
+                (true, prefill_worker_urls.clone())
+            }
+        };
-
-            let mut chars_per_url = bucket_guard.chars_per_url.lock();
-            chars_per_url.entry(worker_url.clone()).or_insert(0);
-
-            cloned
-        };
-
-        bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
-
-        info!(
-            "Added worker {} to bucket for model {}",
-            worker_url, model_key
-        );
+        if inserted {
+            bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
+            info!(
+                "Added worker {} to bucket for model {}",
+                worker_url, model_key
+            );
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut bucket_guard = bucket.write();
let worker_url = worker.url().to_string();
let prefill_worker_urls_clone = {
let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock().unwrap();
if !prefill_worker_urls.contains(&worker_url) {
prefill_worker_urls.push(worker_url.clone());
}
let cloned = prefill_worker_urls.clone();
let prefill_worker_urls_clone = {
let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock();
if !prefill_worker_urls.contains(&worker_url) {
prefill_worker_urls.push(worker_url.clone());
}
let cloned = prefill_worker_urls.clone();
let mut chars_per_url = bucket_guard.chars_per_url.lock().unwrap();
chars_per_url.entry(worker_url.clone()).or_insert(0);
let mut chars_per_url = bucket_guard.chars_per_url.lock();
chars_per_url.entry(worker_url.clone()).or_insert(0);
cloned
};
cloned
};
bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
info!(
"Added worker {} to bucket for model {}",
worker_url, model_key
);
} else {
error!(
"Failed to acquire write lock for bucket of model {}",
model_key
);
}
info!(
"Added worker {} to bucket for model {}",
worker_url, model_key
);
let (inserted, prefill_worker_urls_clone) = {
let mut prefill_worker_urls = bucket_guard.prefill_worker_urls.lock();
if prefill_worker_urls.contains(&worker_url) {
(false, prefill_worker_urls.clone())
} else {
prefill_worker_urls.push(worker_url.clone());
(true, prefill_worker_urls.clone())
}
};
if inserted {
let mut chars_per_url = bucket_guard.chars_per_url.lock();
chars_per_url.entry(worker_url.clone()).or_insert(0);
bucket_guard.init_prefill_worker_urls(prefill_worker_urls_clone);
info!(
"Added worker {} to bucket for model {}",
worker_url, model_key
);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/policies/bucket.rs` around lines 116 - 137, The code always
reinitializes bucket state even when the worker_url already exists; change
add_prefill_url so you detect whether the push actually inserted a new URL (by
checking prefill_worker_urls.contains before mutation) and only when it's newly
inserted perform chars_per_url.entry(worker_url.clone()).or_insert(0) and call
bucket_guard.init_prefill_worker_urls(cloned); otherwise skip the init and skip
zeroing per-URL state to preserve balancing history, and adjust the info! log to
only report "Added worker ..." when insertion occurred (log a different message
or skip logging for duplicates).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid optimization suggestion. Changing load-balancing reinitialization behavior is out of scope for this clippy-focused PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Understood—let’s keep this PR strictly lint-focused.

Would you like me to open a follow-up GitHub issue to track the optimization? Here’s what I’d file:

  • Title: BucketPolicy: avoid reinitializing boundaries/zeroing per-URL loads on duplicate add_prefill_url
  • Scope:
    • File: model_gateway/src/policies/bucket.rs
    • Function: BucketPolicy::add_prefill_url
  • Problem: On duplicate registration, we still call init_prefill_worker_urls(...), which clears chars_per_url and rebuilds boundaries, wiping recent balancing history.
  • Proposed fix:
    • Only reinitialize when the URL is newly inserted.
    • On duplicates, skip reinit and keep existing per-URL load; optionally log at debug level.
  • Acceptance criteria:
    • Duplicate add does not change Bucket.boundary or reset chars_per_url for existing URLs.
    • Unit test proving loads and boundaries remain stable after duplicate add.
  • Backlinks: PR #489 and this discussion.

If you give the go-ahead, I’ll open the issue and assign it to you with those details.


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread model_gateway/tests/metrics_aggregator_test.rs Outdated
Comment thread model_gateway/tests/otel_tracing_test.rs
Comment thread multimodal/src/tracker.rs
Comment thread protocols/src/responses.rs Outdated
Comment thread protocols/src/worker.rs
Comment on lines +338 to +343
1 => {
let Some(model) = models.into_iter().next() else {
return Self::Wildcard;
};
Self::Single(Box::new(model))
}

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Defensive but overly cautious handling for single-element case.

After matching models.len() == 1, the into_iter().next() call is guaranteed to return Some. The fallback to Self::Wildcard is logically unreachable. While this aligns with the PR's panic elimination objective, a more precise approach would use expect() with a clear message since this condition is invariant-guaranteed.

That said, the current code is safe and doesn't introduce bugs—Wildcard is a valid fallback that won't cause issues.

💡 Alternative: Use expect with invariant message
 1 => {
-    let Some(model) = models.into_iter().next() else {
-        return Self::Wildcard;
-    };
+    let model = models
+        .into_iter()
+        .next()
+        .expect("len==1 guarantees next() returns Some");
     Self::Single(Box::new(model))
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1 => {
let Some(model) = models.into_iter().next() else {
return Self::Wildcard;
};
Self::Single(Box::new(model))
}
1 => {
let model = models
.into_iter()
.next()
.expect("len==1 guarantees next() returns Some");
Self::Single(Box::new(model))
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@protocols/src/worker.rs` around lines 338 - 343, The match arm handling the
single-element case is overly defensive: after checking models.len() == 1,
calling models.into_iter().next() cannot return None, yet the code falls back to
Self::Wildcard; replace the fallback with a direct unwrap/expect so the
invariant is explicit — i.e., in the branch that uses models.into_iter().next()
for construction of Self::Single(Box::new(...)), swap the conditional Some(...)
else { return Self::Wildcard } for models.into_iter().next().expect("expected
one model when models.len() == 1") and construct Self::Single from that value,
removing the unreachable Wildcard fallback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The defensive fallback to Self::Wildcard is intentional — consistent with this PR's philosophy of replacing unwrap()/expect() with non-panicking alternatives. Using expect() would reintroduce a panic path.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Acknowledged. Leaving the non-panicking fallback to WorkerModels::Wildcard as-is in the single-element branch is consistent with this PR’s “avoid panics/expect” philosophy. No change needed. If helpful for future readers, we could add a brief comment documenting the “len() == 1 invariant; prefer non-panicking path” rationale, but I won’t push for it in this lint-focused PR.


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: protocols/src/worker.rs:338-343
Timestamp: 2026-02-21T02:36:00.013Z
Learning: Repo: lightseekorg/smg PR: 489
File: protocols/src/worker.rs (impl From<Vec<ModelCard>> for WorkerModels)
Learning: For the single-element case (models.len() == 1), keep the defensive Option guard with a non-panicking fallback to WorkerModels::Wildcard instead of using expect()/unwrap(). This is intentional to avoid introducing panic paths in production code for PR `#489` and similar clippy/lint-only efforts.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs:189-194
Timestamp: 2026-02-21T02:32:04.647Z
Learning: Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs
Context: GrpcClient::generate fallback match arm
Learning: The catch-all panic for mismatched client/request types in GrpcClient::generate is intentional to enforce pipeline invariants; do not convert this to a returned error in PR `#489` or similar lint-only changes.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs:206-211
Timestamp: 2026-02-21T02:31:14.142Z
Learning: Repo: lightseekorg/smg
File: model_gateway/src/routers/grpc/client.rs
Context: GrpcClient::embed match arm
Learning: The catch-all panic in GrpcClient::embed for mismatched client/request types or unsupported embedding backends is intentional to catch invariant violations and unsupported configurations at development time. Converting this path to a returned error is out of scope for PR `#489`.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: kv_index/src/string_tree.rs:481-484
Timestamp: 2026-02-21T02:30:52.128Z
Learning: Preference noted: In kv_index/src/string_tree.rs (Rust radix tree), production code should avoid panics on invariant breaches; prefer a defensive non-panicking path (e.g., early return) and use debug_assert! for debug/test builds. Consider documenting the invariant with a comment, and optionally log under cfg(debug_assertions).

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Introduce clippy.toml and workspace-level lint configuration to enforce
production-grade code quality standards across all 26 crates (320 files,
~4400 lines changed). Every warning is now denied via `-D warnings`.

What changed:

  Cargo.toml: Add workspace-level [lints.clippy] configuration denying
  unwrap_used, expect_used, panic, print_stdout/stderr, dbg_macro,
  todo/unimplemented, and other unsafe patterns. Enable pedantic and
  nursery lint groups with targeted exceptions.

  clippy.toml: New file configuring disallowed-methods (tokio::spawn
  requires justification), allow-expect-in-tests, and
  allow-unwrap-in-tests for test/bench ergonomics.

  model_gateway/src/policies/bucket.rs: Migrate from std::sync::Mutex
  to parking_lot::Mutex. Removes ~50 lines of dead lock-poisoning error
  handling since parking_lot never poisons. This is a behavioral
  improvement: previously a panic while holding a lock would cause all
  subsequent lock attempts to also panic; now the lock is released and
  the next caller succeeds.

  data_connector/src/memory.rs: Same std::sync::RwLock to parking_lot
  migration for MemoryConversationItemStorage.

  data_connector/src/postgres.rs: Replace three .expect() calls in
  storage constructors with ? propagation. Previously, database schema
  initialization failure would panic the process; now it returns a proper
  error to the caller.

  model_gateway/src/core/token_bucket.rs: Remove unnecessary async from
  try_acquire(), return_tokens(), available_tokens(). These used
  parking_lot::Mutex (sync) but were wrapped in async fn, creating
  pointless Future overhead on every rate-limit check. The genuinely
  async methods (acquire, acquire_timeout) that use tokio::Notify and
  tokio::select! remain async.

  model_gateway/src/core/worker.rs: Change Worker::api_key() trait
  method from &Option<String> to Option<&String> (idiomatic Rust).
  All callers updated (.clone() to .cloned(), removed .as_ref()).
  Add Drop implementation for HealthChecker to abort the spawned
  health-check task on drop, preventing task leaks on shutdown.

  model_gateway/src/observability/gauge_histogram.rs: Fix TOCTOU race
  condition in CachedGaugeHistogram::get_or_register() where a second
  .get().expect() after or_insert_with() could panic if another thread
  called remove() between the two operations. Restructured to use
  .downgrade() on the entry ref directly.

  mesh/src/crdt.rs, incremental.rs, ping_server.rs: Replace
  SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default()
  with .expect(). In CRDT code, timestamp=0 causes silent data loss
  during LWW merge; a system clock before UNIX epoch is a fatal
  misconfiguration that must crash, not silently corrupt.

  grpc_client/src/trtllm_service.rs: Remove Result wrappers from 5
  builder methods that never returned Err. Eliminates dead error paths
  and unnecessary ? operators at call sites.

  wasm/src/runtime.rs, module_manager.rs: Remove Result from infallible
  constructors (WasmRuntime::new, WasmModuleManager::new). These never
  failed; the Result wrapper was dead code.

  model_gateway/src/routers/factory.rs and grpc router constructors:
  Remove async from 19 functions that contained no .await (flagged by
  unused_async lint). Includes create_grpc_router, prepare_chat,
  prepare_responses, execute_tool_loop_streaming, and various streaming
  handlers that use spawn-and-return patterns. All callers updated.

  protocols/src/chat.rs, responses.rs: Replace unsafe .unwrap() on
  optional tool arrays with if-let/else-return patterns.

  kv_index/src/string_tree.rs: Replace .chars().next().unwrap() in
  while loops with while-let patterns, eliminating theoretical panics.

  All tokio::spawn call sites: Add #[expect(clippy::disallowed_methods)]
  with reason strings documenting task lifecycle (who stores the handle,
  how it's aborted, what coordinates shutdown).

  All 320 files: Mechanical fixes for format string inlining (Rust 2021
  format!("{x}") syntax), raw string hash reduction (r#"..."# to r"..."
  where safe), #[allow] to #[expect] migration (expect fails if the
  lint never fires, catching stale suppressions), clone_from() for
  efficiency, wildcard matches to explicit enum variants for
  exhaustiveness safety, and Copy type pass-by-value.

Why:

  This codebase serves billions of tokens per minute. The previous lint
  configuration was permissive, allowing unwrap/expect/panic in
  production code paths without justification. This change enforces that
  every potential panic point is either eliminated (proper error
  propagation) or explicitly justified with a reason string explaining
  why it's safe.

  The audit also uncovered real bugs:
  - CRDT timestamp corruption (unwrap_or_default producing timestamp=0)
  - DashMap race condition in gauge histogram (TOCTOU between insert
    and get)
  - HealthChecker task leak (no Drop impl despite documented contract)
  - Dead Result wrappers hiding the fact that errors were impossible

  These are fixed in this commit, not just suppressed.

How verified:

  cargo check --all-targets passes cleanly.
  cargo clippy --all-targets -- -D warnings produces zero errors.
  cargo fmt --all -- --check produces zero diffs.
  Full 6-agent audit reviewed all 319 changed files across:
  - async-to-sync conversions (19 verified, all callers updated)
  - API signature changes (all callers updated, zero missed)
  - Error handling quality (3 HIGH issues fixed, 7 MEDIUM reviewed)
  - Dead code annotations (all justified or flagged for future removal)
  - Test code changes (all mechanical, no broken assertions)
  - Non-gateway crate changes (all verified correct)

Signed-off-by: Simon Lin <simon@simon.dev>
Signed-off-by: Simo Lin <simo.lin@oracle.com>
@github-actions github-actions Bot added the realtime-api Realtime API related changes label Feb 21, 2026
@mergify mergify Bot removed the needs-rebase PR has merge conflicts that need to be resolved label Feb 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (16)
model_gateway/src/routers/parse/handlers.rs (1)

57-63: 🧹 Nitpick | 🔵 Trivial

Format string inlining is incomplete in this file.

The changes on lines 61 and 98 correctly inline the format arguments, but adjacent lines using the same variables were not updated:

  • Line 58: error!("Failed to parse function calls: {}", e) → should use {e}
  • Line 95: error!("Failed to separate reasoning: {}", e) → should use {e}

Additionally, lines 42 and 79 also use positional format arguments that could be inlined for consistency with the PR's lint enforcement goal.

♻️ Proposed fix for consistency
@@ -39,7 +39,7 @@
     let Some(pooled_parser) = factory.registry().get_pooled_parser(&req.tool_call_parser) else {
         return error_response(
             StatusCode::BAD_REQUEST,
-            &format!("Unknown tool parser: {}", req.tool_call_parser),
+            &format!("Unknown tool parser: {}", req.tool_call_parser),  // req.tool_call_parser is a field, cannot inline
         );
     };
 
@@ -55,7 +55,7 @@
         )
             .into_response(),
         Err(e) => {
-            error!("Failed to parse function calls: {}", e);
+            error!("Failed to parse function calls: {e}");
             error_response(
                 StatusCode::BAD_REQUEST,
                 &format!("Failed to parse function calls: {e}"),
@@ -76,7 +76,7 @@
     let Some(pooled_parser) = factory.registry().get_pooled_parser(&req.reasoning_parser) else {
         return error_response(
             StatusCode::BAD_REQUEST,
-            &format!("Unknown reasoning parser: {}", req.reasoning_parser),
+            &format!("Unknown reasoning parser: {}", req.reasoning_parser),  // req.reasoning_parser is a field, cannot inline
         );
     };
 
@@ -92,7 +92,7 @@
         )
             .into_response(),
         Err(e) => {
-            error!("Failed to separate reasoning: {}", e);
+            error!("Failed to separate reasoning: {e}");
             error_response(
                 StatusCode::BAD_REQUEST,
                 &format!("Failed to separate reasoning: {e}"),

Note: Lines 42 and 79 cannot use inline interpolation because req.tool_call_parser and req.reasoning_parser are field accesses, which Rust format strings don't support for inlining. Only the error! macros on lines 58 and 95 should be updated.

Also applies to: 94-100

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/parse/handlers.rs` around lines 57 - 63, Update the
error! macro format strings to use named interpolation for the error variable
instead of positional placeholders: replace occurrences like error!("Failed to
parse function calls: {}", e) and error!("Failed to separate reasoning: {}", e)
with error!("Failed to parse function calls: {e}") and error!("Failed to
separate reasoning: {e}") respectively in the parse handler in handlers.rs;
leave the logs that reference struct field accesses (e.g., req.tool_call_parser
and req.reasoning_parser) as-is since Rust's format inlining does not support
field access in the same way.
model_gateway/src/routers/grpc/proto_wrapper.rs (1)

483-528: 🧹 Nitpick | 🔵 Trivial

LGTM!

Consistent #[expect] application for ProtoGenerateComplete accessors with correct reason strings.

As a future enhancement, you might consider adding try_as_*() -> Option<&T> methods alongside these panicking accessors. This would give callers a choice between:

  • is_sglang() + as_sglang() (current pattern)
  • try_as_sglang() with direct Option handling

This is entirely optional and the current design with documented panics is valid.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/proto_wrapper.rs` around lines 483 - 528, Add
non-panicking "try" accessors alongside the existing panicking ones: implement
try_as_sglang(&self) -> Option<&sglang::GenerateComplete>,
try_as_sglang_mut(&mut self) -> Option<&mut sglang::GenerateComplete>,
try_as_vllm(&self) -> Option<&vllm::GenerateComplete>, and try_as_trtllm(&self)
-> Option<&trtllm::GenerateComplete> in the same impl that contains
as_sglang/as_sglang_mut/as_vllm/as_trtllm; each should match self and return
Some(complete) for the corresponding variant (Self::Sglang, Self::Vllm,
Self::Trtllm) or None for other variants, so callers can choose Option-based
handling instead of relying on is_* + panicking accessors.
multimodal/src/vision/image_processor.rs (1)

79-84: ⚠️ Potential issue | 🟡 Minor

Missing validation: data length should match declared shape.

uint_2d does not verify that data.len() == rows * cols. If a caller passes mismatched values, downstream code trusting the shape could panic or produce incorrect results.

🛡️ Proposed fix to add validation
 /// Create a 2D uint tensor.
-pub fn uint_2d(data: Vec<u32>, rows: usize, cols: usize) -> Self {
+pub fn uint_2d(data: Vec<u32>, rows: usize, cols: usize) -> Result<Self, TransformError> {
+    let expected_len = rows * cols;
+    if data.len() != expected_len {
+        return Err(TransformError::InvalidShape {
+            expected: format!("{rows}x{cols} = {expected_len} elements"),
+            actual: vec![data.len()],
+        });
+    }
-    Self::UintTensor {
+    Ok(Self::UintTensor {
         data,
         shape: vec![rows, cols],
-    }
+    })
 }

Alternatively, if you want to keep the infallible signature, add a debug assertion:

 pub fn uint_2d(data: Vec<u32>, rows: usize, cols: usize) -> Self {
+    debug_assert_eq!(
+        data.len(),
+        rows * cols,
+        "data length {} does not match shape {}x{}",
+        data.len(),
+        rows,
+        cols
+    );
     Self::UintTensor {
         data,
         shape: vec![rows, cols],
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@multimodal/src/vision/image_processor.rs` around lines 79 - 84, The uint_2d
constructor (uint_2d) currently constructs Self::UintTensor without validating
that data.len() matches rows * cols; add a check that data.len() ==
rows.checked_mul(cols).unwrap_or(usize::MAX) (or equivalent safe multiply) and
handle mismatches: either change uint_2d to return a Result<Self, Error> and
return Err when lengths differ, or keep the infallible API but add a
debug_assert!(data.len() == rows * cols, "mismatched data length") and document
the precondition; update any callers/tests accordingly.
model_gateway/benches/tool_parser_benchmark.rs (1)

698-748: 🧹 Nitpick | 🔵 Trivial

Verify the returned duration accuracy for criterion.

The inverted control flow makes the first iteration collect detailed latency statistics (warmup + 1000 samples) while returning p50 * iters as u32 as the estimated duration. Subsequent iterations perform regular benchmarking.

The concern: when iters differs significantly from the 1000 samples collected, or when the actual time spent (100 warmup + 1000 measurements) doesn't match p50 * iters, criterion may report inconsistent timing data for this benchmark group compared to others.

Since the primary goal is the custom latency statistics printed to stdout (P50/P95/P99/Max), this may be acceptable. However, if criterion's built-in statistics matter for CI/comparison purposes, consider aligning the returned duration with actual time spent or documenting this behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/benches/tool_parser_benchmark.rs` around lines 698 - 748, The
current branch that computes latency stats returns p50 * iters as u32 which can
misreport the benchmark duration; instead compute and return a Duration that
reflects the measured work: after warmup and the 1000-sample loop, sum or
average the collected latencies (latencies.iter().sum() or average p50) and
scale that to the requested iters to produce a Duration (or compute the actual
elapsed time across the warmup+measurement loops with Instant and return that);
update the total_duration assignment (the variable total_duration and the branch
using printed_clone) to use that Duration so Criterion sees a consistent timing,
and ensure types convert correctly between Duration and the iters scaling when
replacing p50 * iters as u32.
model_gateway/src/policies/bucket.rs (1)

33-39: ⚠️ Potential issue | 🟠 Major

Drop impl does not actually stop the background thread.

The drop(handle) call merely drops the JoinHandle, but the spawned thread (line 54) runs an infinite loop and continues executing after the BucketPolicy is dropped. This results in a thread leak where the background adjustment thread keeps running with a dangling Arc<DashMap> reference.

Consider using an AtomicBool or a channel to signal the thread to exit, then optionally join it:

🛠️ Suggested fix pattern
 pub struct BucketPolicy {
     config: BucketConfig,
     buckets: Arc<DashMap<String, Arc<RwLock<Bucket>>>>,
+    shutdown: Arc<AtomicBool>,
     adjustment_handle: Option<thread::JoinHandle<()>>,
 }

 impl Drop for BucketPolicy {
     fn drop(&mut self) {
+        self.shutdown.store(true, Ordering::Relaxed);
         if let Some(handle) = self.adjustment_handle.take() {
-            drop(handle);
+            let _ = handle.join();
         }
     }
 }

Then in the spawned thread loop, check shutdown.load(Ordering::Relaxed) to break out.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/policies/bucket.rs` around lines 33 - 39, The Drop
implementation for BucketPolicy only drops the JoinHandle (adjustment_handle)
but doesn't signal the spawned adjustment thread to exit, causing a leak; modify
BucketPolicy to include a shutdown signal (e.g., an Arc<AtomicBool> named
shutdown or a channel receiver) that the spawned thread checks in its loop
(check shutdown.load(Ordering::Relaxed) or recv timeout) and breaks out when
signaled, set that signal in BucketPolicy::drop prior to taking/joining
adjustment_handle, and then join the handle (call join on the taken JoinHandle)
to ensure the background thread terminates cleanly.
model_gateway/src/core/job_queue.rs (1)

785-791: ⚠️ Potential issue | 🟡 Minor

Potential integer underflow with unwrap_or_default().

If duration_since(UNIX_EPOCH) fails (system clock before 1970), now becomes 0. The subtraction now - value.timestamp on line 791 would underflow when value.timestamp > 0, causing a panic in debug mode or wraparound in release mode (breaking cleanup by retaining all statuses).

While this edge case is extremely rare, consider using saturating_sub for consistent defensive handling:

Suggested fix
-            status_map.retain(|_key, value| now - value.timestamp < STATUS_TTL);
+            status_map.retain(|_key, value| now.saturating_sub(value.timestamp) < STATUS_TTL);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/core/job_queue.rs` around lines 785 - 791, The computation
of now from
SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs() can
yield 0 on error and cause underflow when doing now - value.timestamp inside
status_map.retain; update the retain predicate to use a saturating subtraction
(e.g., now.saturating_sub(value.timestamp) < STATUS_TTL) so the subtraction
cannot underflow, referencing the now variable, status_map.retain call,
value.timestamp field and STATUS_TTL constant.
model_gateway/src/core/worker_manager.rs (1)

369-381: ⚠️ Potential issue | 🟡 Minor

Update policies/watchers even when loads are empty.

On Line 369, skipping updates when loads is empty can leave stale load data in PowerOfTwo policies and subscribers if all workers are removed or temporarily unavailable. Consider sending the empty map (clears state) while still warning.

💡 Suggested change
-            if loads.is_empty() {
-                warn!("No loads fetched from workers");
-            } else {
-                debug!(
-                    "Fetched loads from {} workers, updating {} PowerOfTwo policies",
-                    loads.len(),
-                    power_of_two_policies.len()
-                );
-                for policy in &power_of_two_policies {
-                    policy.update_loads(&loads);
-                }
-                let _ = tx.send(loads);
-            }
+            if loads.is_empty() {
+                warn!("No loads fetched from workers");
+            } else {
+                debug!(
+                    "Fetched loads from {} workers, updating {} PowerOfTwo policies",
+                    loads.len(),
+                    power_of_two_policies.len()
+                );
+            }
+            for policy in &power_of_two_policies {
+                policy.update_loads(&loads);
+            }
+            let _ = tx.send(loads);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/core/worker_manager.rs` around lines 369 - 381, The current
branch skips updating when loads.is_empty(), which leaves stale state in
PowerOfTwo policies and subscribers; change the logic to always iterate over
power_of_two_policies and call policy.update_loads(&loads) even when
loads.is_empty(), and still send the (empty) loads via let _ = tx.send(loads) so
watchers are notified/cleared; keep the warn!("No loads fetched from workers")
but do not return early—always perform the update_loads loop and tx.send call
using the existing variables (loads, power_of_two_policies, policy.update_loads,
tx.send).
protocols/src/interactions.rs (1)

1076-1109: 🧹 Nitpick | 🔵 Trivial

Add/confirm tests + doc for the new agent/background constraints.
These rules are critical; please add or confirm unit coverage for (agent ⇒ background=true, background ⇒ agent, background ∧ stream conflict) and note the requirement in docs/comments to prevent regressions. Based on learnings: Enforce background=true for all Gemini Interactions API agent calls in Rust code under protocols/src. If an agent is used, ensure the request includes background: true; add validation tests and document the requirement for future contributors.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@protocols/src/interactions.rs` around lines 1076 - 1109, Update
validate_interactions_request to enforce and document the agent/background
constraints and add unit tests: ensure that validate_interactions_request
(operating on InteractionsRequest) requires background == true whenever agent is
set, rejects requests that set background == true without an agent, and rejects
requests where background and stream are both true (these checks already exist
but confirm behavior for Gemini agent by adding a comment above
validate_interactions_request documenting "Agent interactions must set
background = true (Gemini requirement)"); add unit tests exercising (1) agent
present with background=false fails, (2) background=true without agent fails,
and (3) background=true and stream=true fails, using the existing
ValidationError variants ("agent_requires_background",
"background_requires_agent", "background_conflicts_with_stream") to assert
correct errors so future changes are caught.
reasoning_parser/src/factory.rs (3)

600-606: ⚠️ Potential issue | 🟡 Minor

Throughput assertion may cause CI flakiness.

The assertion throughput > 1000.0 could fail on slower CI runners, resource-constrained containers, or when the system is under load from parallel jobs. Consider lowering the threshold or making it configurable via environment variable.

💡 Optional: Make threshold configurable or lower it
         // Performance check: should handle at least 1000 req/sec
         let throughput = (total_requests as f64) / duration.as_secs_f64();
+        let min_throughput = std::env::var("MIN_PARSER_THROUGHPUT")
+            .ok()
+            .and_then(|s| s.parse().ok())
+            .unwrap_or(500.0); // Conservative default for CI
         assert!(
-            throughput > 1000.0,
+            throughput > min_throughput,
             "Throughput too low: {throughput:.0} req/sec",
         );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reasoning_parser/src/factory.rs` around lines 600 - 606, The hardcoded
throughput assertion using the computed variable throughput (from total_requests
and duration) can cause CI flakiness; replace the literal 1000.0 with a
configurable threshold read from an environment variable (e.g.
THROUGHPUT_THRESHOLD) parsed into an f64 with a safe default (or lower default
if you prefer), validate/handle parse errors by falling back to the default, and
then assert throughput > threshold using the parsed value so tests can run
reliably on slower CI runners; update the assertion message to include the
actual threshold variable for clarity.

63-85: ⚠️ Potential issue | 🟠 Major

TOCTOU race in parser pooling logic.

The check-then-act pattern between reading the pool (line 66) and inserting (lines 78-79) allows a race where two threads both find the parser missing, both create instances, and the second overwrites the first. This leaves the first caller holding an Arc to an orphaned parser that differs from what's in the pool, violating pooling semantics.

The PR objectives mention fixing a similar "DashMap TOCTOU race ... by restructuring entry handling" elsewhere—the same fix should apply here.

🔧 Proposed fix using double-checked locking
     pub fn get_pooled_parser(&self, name: &str) -> Option<PooledParser> {
         // First check if we have a pooled instance
         {
             let pool = self.pool.read();
             if let Some(parser) = pool.get(name) {
                 return Some(Arc::clone(parser));
             }
         }

         // If not in pool, create one and add to pool
-        let creators = self.creators.read();
-        if let Some(creator) = creators.get(name) {
-            let parser = Arc::new(Mutex::new(creator()));
-
-            // Add to pool for future use
-            let mut pool = self.pool.write();
-            pool.insert(name.to_string(), Arc::clone(&parser));
-
-            Some(parser)
-        } else {
-            None
-        }
+        // Clone the creator while holding read lock, then release before creating parser
+        let creator = {
+            let creators = self.creators.read();
+            creators.get(name).map(Arc::clone)
+        }?;
+
+        // Acquire write lock and double-check before inserting
+        let mut pool = self.pool.write();
+        if let Some(existing) = pool.get(name) {
+            return Some(Arc::clone(existing));
+        }
+
+        let parser = Arc::new(Mutex::new(creator()));
+        pool.insert(name.to_string(), Arc::clone(&parser));
+        Some(parser)
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reasoning_parser/src/factory.rs` around lines 63 - 85, The get_pooled_parser
function has a TOCTOU race: two threads can both miss the pool read and create
distinct parser instances, with one overwriting the other. Fix by using
double-checked locking: first read self.pool to see if the parser exists (keep
that early fast path), then if missing read self.creators to get the creator,
then acquire a write lock on self.pool and check again if the entry exists; if
it exists return that Arc, otherwise call the creator to build the parser,
insert it into the pool (pool.insert(name.to_string(), Arc::clone(&parser))) and
return the newly created Arc. Ensure you reference get_pooled_parser, self.pool,
self.creators, and the creator() call when making the change.

608-643: 🧹 Nitpick | 🔵 Trivial

Note: This test may not reliably catch the TOCTOU race.

This test exercises concurrent pool access and clearing, which is the scenario affected by the race condition in get_pooled_parser. However, the test only verifies no deadlock/panic occurs—it doesn't assert that pooled parsers maintain referential integrity. Consider adding an assertion that validates Arc pointer equality after concurrent operations if the race fix is applied.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reasoning_parser/src/factory.rs` around lines 608 - 643, The test currently
only checks for absence of panic but not that pooled parsers preserve
referential integrity; update the test_concurrent_pool_modifications to capture
a baseline Arc from ParserFactory::get_pooled (use
ParserFactory::get_pooled("deepseek-r1") or other model), run the concurrent
tasks, then retrieve the parser again and assert Arc::ptr_eq(&baseline_arc,
&new_arc) (or use pointer equality checks for multiple model keys) to ensure the
TOCTOU race is fixed; if needed, use a synchronization primitive (Barrier) to
ensure the baseline is taken before concurrent clears begin and the final fetch
happens after operations complete.
model_gateway/src/policies/consistent_hashing.rs (1)

163-177: ⚠️ Potential issue | 🟠 Major

Random fallback can return None even when healthy workers remain.
Line 169-175 counts healthy workers, then re-iterates; if health changes between passes, nth(random_healthy_idx) can return None, producing (None, Branch::RandomFallback) and dropping the request. Build the healthy index list once to keep the selection consistent.

🔧 Suggested fix (single pass, consistent selection)
-        let healthy_count = workers.iter().filter(|w| w.is_healthy()).count();
-        if healthy_count == 0 {
+        let healthy_indices: Vec<usize> = workers
+            .iter()
+            .enumerate()
+            .filter(|(_, w)| w.is_healthy())
+            .map(|(i, _)| i)
+            .collect();
+        if healthy_indices.is_empty() {
             return (None, Branch::NoHealthyWorkers);
         }
 
-        let random_healthy_idx = rand::rng().random_range(0..healthy_count);
-        let idx = workers
-            .iter()
-            .enumerate()
-            .filter(|(_, w)| w.is_healthy())
-            .nth(random_healthy_idx)
-            .map(|(i, _)| i);
-
-        (idx, Branch::RandomFallback)
+        let random_healthy_idx = rand::rng().random_range(0..healthy_indices.len());
+        let idx = healthy_indices[random_healthy_idx];
+        (Some(idx), Branch::RandomFallback)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/policies/consistent_hashing.rs` around lines 163 - 177, The
fallback selection currently counts healthy workers then re-iterates workers to
pick the Nth healthy, which can return None if health changes between
iterations; instead collect the healthy worker indices in a single pass (e.g.,
build a Vec<usize> of indices from workers.iter().enumerate().filter(|(_, w)|
w.is_healthy()).map(|(i,_)| i).collect()), check if that Vec is empty, then pick
a random index from that Vec (use rand rng to choose within 0..vec.len()) and
return Some(chosen_index) with Branch::RandomFallback; update the code
references around healthy_count, random_healthy_idx, and the .nth(...) logic
accordingly so selection is consistent.
data_connector/src/config.rs (1)

135-149: ⚠️ Potential issue | 🟡 Minor

Update the retention_days comment to reflect the serde default behavior.

The current comment "If None, data persists indefinitely" is now misleading. With #[serde(default = "default_redis_retention_days")], configs that omit retention_days will deserialize to Some(30), not None. The 30-day TTL will be applied in redis expiration calls (lines 117, 311, 618 in redis.rs).

Update the comment to clarify:

-    // Data retention in days. If None, data persists indefinitely.
+    // Data retention in days. Defaults to 30 days if omitted; if explicitly set to null, data persists indefinitely.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data_connector/src/config.rs` around lines 135 - 149, The comment for the
struct field retention_days is incorrect given the serde default; update the
comment on the retention_days field to state that when omitted it defaults to
Some(30) via the #[serde(default = "default_redis_retention_days")] function and
that a 30-day TTL will be applied in Redis expiration calls (see
default_redis_retention_days and usages in redis.rs where expiration is
applied). Keep the comment concise and mention that explicitly setting None
still means data persists indefinitely, while omitting the field results in a
30-day retention.
model_gateway/benches/wasm_middleware_latency.rs (1)

42-55: ⚠️ Potential issue | 🟡 Minor

Avoid accumulating sleeping tasks between iterations.

The spawned task sleeps for 500ms even after the receiver is dropped. With the benchmark's 10 iterations, up to 10 sleeping tasks can accumulate concurrently, distorting latency measurements. Exit early when the receiver is dropped using tx.closed().

Suggested fix
     tokio::spawn(async move {
         // Send first chunk immediately
         let _ = tx
             .send(Ok::<_, std::io::Error>(bytes::Bytes::from("chunk 1 ")))
             .await;
-        // Simulate generation delay
-        tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
+        // Simulate generation delay, but abort if the receiver is gone
+        tokio::select! {
+            _ = tokio::time::sleep(tokio::time::Duration::from_millis(500)) => {}
+            _ = tx.closed() => return,
+        }
         // Send final chunk
         let _ = tx
             .send(Ok::<_, std::io::Error>(bytes::Bytes::from("chunk 2")))
             .await;
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/benches/wasm_middleware_latency.rs` around lines 42 - 55, The
spawned task in mock_next_streaming currently sleeps for 500ms even if the
receiver is dropped, causing accumulating sleeping tasks across iterations;
modify the task to detect receiver closure (use tx.closed().await or check
tx.is_closed()/tx.closed() before/after the sleep and before sending the final
chunk) and return early if the receiver is dropped so the task doesn't continue
sleeping and skew benchmark latency. Ensure checks are placed after the first
send and before the sleep/send of the final chunk to bail out promptly when the
receiver is gone.
model_gateway/tests/common/mock_worker.rs (1)

1235-1259: ⚠️ Potential issue | 🟡 Minor

Clear the per-port RESP_STORE entry on worker shutdown to avoid cross-test leakage.

RESP_STORE persists for the process lifetime; if ports/IDs are reused, GET/CANCEL could succeed unexpectedly. Consider clearing per-port entries when a worker stops.

🧹 Suggested cleanup hook
+fn clear_responses_for_port(port: u16) {
+    let mut map = get_store().lock().unwrap();
+    map.remove(&port);
+}
+
 pub async fn stop(&mut self) {
     if let Some(shutdown_tx) = self.shutdown_tx.take() {
         let _ = shutdown_tx.send(());
     }
 
     if let Some(handle) = self.shutdown_handle.take() {
         // Wait for the server to shut down
         let _ = tokio::time::timeout(tokio::time::Duration::from_secs(5), handle).await;
     }
+
+    let port = self.config.read().await.port;
+    clear_responses_for_port(port);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/tests/common/mock_worker.rs` around lines 1235 - 1259,
RESP_STORE currently retains responses for the process lifetime causing
cross-test leakage; add a cleanup function (e.g., remove_responses_for_port or
clear_responses_for_port) that locks get_store(), removes the HashMap entry for
the given port (map.remove(&port)), and call this cleanup from the worker
shutdown/stop path so per-port entries are cleared when a worker stops;
reference RESP_STORE, get_store(), store_response_for_port, and
response_exists_for_port to locate where to add and invoke the cleanup.
auth/src/jwt.rs (1)

397-452: ⚠️ Potential issue | 🟠 Major

Avoid silently defaulting to Role::User when role mappings are configured.

With extract_role now returning Role directly, unmapped roles no longer fail validation and will be treated as User. If role_mapping is meant to be strict, this can weaken authorization. Consider restoring an error path (or making the fallback configurable) so missing mappings don’t implicitly grant access.

🔧 Suggested fix (restore strict mapping semantics)
-    fn extract_role(&self, claims: &StandardClaims) -> Role {
+    fn extract_role(&self, claims: &StandardClaims) -> Result<Role, JwtValidatorError> {
         // Try to get the role claim value
         let role_value = claims.extra.get(&self.config.role_claim);
@@
-                if let Ok(role) = role_str.parse::<Role>() {
-                    return role;
-                }
+                if let Ok(role) = role_str.parse::<Role>() {
+                    return Ok(role);
+                }
             }
             // Default to User if no explicit role found
             warn!("No role found in JWT claims, defaulting to User");
-            return Role::User;
+            return Ok(Role::User);
         }
@@
-            if let Some(role) = self.config.role_mapping.get(role_str) {
-                return *role;
-            }
+            if let Some(role) = self.config.role_mapping.get(role_str) {
+                return Ok(*role);
+            }
         }
@@
-        Role::User
+        Err(JwtValidatorError::NoRoleMapping(role_strings.join(",")))
     }
🔧 Update call site
-        let role = self.extract_role(&claims);
+        let role = self.extract_role(&claims)?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@auth/src/jwt.rs` around lines 397 - 452, The extract_role function currently
defaults to Role::User even when self.config.role_mapping is non-empty, which
silently grants access for unmapped roles; change extract_role to return
Result<Role, JwtError> (or Option<Role>) instead of Role, return Err(...) when
role_mapping is configured but no mapping or direct parse matches (replace the
final warn+Role::User with an error), and update all callers of extract_role to
propagate or handle the error so missing mappings cause
authentication/authorization failure rather than implicit User access; keep the
direct-parse/default behavior only when role_mapping.is_empty() if you want to
preserve backward compatibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mesh/src/crdt.rs`:
- Around line 296-299: Add a short documentation comment above the contains_key
method explaining its purpose and why it exists despite being unused internally
(e.g., provided for API completeness or future external use), so the
#[expect(dead_code)] attribute isn’t the only signal; update the doc to
reference the method name contains_key and mention that it checks membership via
self.inner.read().contains_key(key) for clarity to future readers.

In `@mesh/src/sync.rs`:
- Line 83: The key formatting is inconsistent: several places construct the
policy key with named interpolation using format!("policy:{model_id}") (e.g.,
SKey::new calls that use that pattern), but apply_remote_policy_state still uses
positional interpolation format!("policy:{}", state.model_id); update the call
inside apply_remote_policy_state to use the same named-interpolation style
(format!("policy:{model_id}") referencing state.model_id) so all
SKey::new(policy...) usages are consistent with the rest of the file.

In `@model_gateway/benches/wasm_middleware_latency.rs`:
- Line 1: The file-level #[expect(clippy::unwrap_used,
clippy::disallowed_methods)] is too broad—narrow the scope by removing the
module-level attribute and applying #[expect(...)] only to the specific
functions that call unwrap or spawn (e.g., the benchmark functions, setup
helpers, or a main/run_benchmark function that actually use unwrap/spawn);
update each annotated function with the scoped attribute and include a short
reason if your lint config requires it.
- Around line 88-91: The closure passed into tower::service_fn currently uses an
unnecessary async block to call the now-sync mock_next_streaming; replace the
async closure with a ready future by returning future::ready(Ok::<_,
std::convert::Infallible>(mock_next_streaming(req))) so the
middleware::from_fn_with_state(app_state.clone(), wasm_middleware).layer(...)
uses a synchronous-ready service instead of creating an extra task; update the
service_fn closure accordingly and ensure future::ready is imported or fully
qualified.

In `@model_gateway/src/core/steps/worker/local/update_worker_properties.rs`:
- Around line 89-93: The code silently skips DP configuration when
worker.is_dp_aware() is true but worker.dp_rank() or worker.dp_size() is None;
add an observable warning there: inside the branch that checks is_dp_aware() but
before/after the existing if let (Some(rank), Some(size)) = (worker.dp_rank(),
worker.dp_size()) { builder = builder.dp_config(rank, size); }, insert a warning
log (using the local logger/context) that includes the worker identifier and
which DP metadata is missing when either dp_rank() or dp_size() is None so the
inconsistent DP-aware state is visible for debugging.

In `@model_gateway/src/routers/grpc/regular/streaming.rs`:
- Around line 671-673: The code builds an error JSON by interpolating the error
string (error_chunk = format!("data: {{\"error\": \"{e}\"}}\n\n")), which can
produce invalid JSON when the error contains quotes/newlines; change this to
serialize the error via serde_json (e.g., let payload = serde_json::json!({
"error": e.to_string() }); let json = serde_json::to_string(&payload)? or handle
the to_string error with a fallback) and then build the chunk as format!("data:
{}\n\n", json); apply the same change to the other occurrence (the block using
tx.send(Ok(Bytes::from(error_chunk))) at the second location) so tx.send always
gets a properly escaped JSON string wrapped with "data: ...\n\n".

In `@multimodal/src/vision/image_processor.rs`:
- Around line 411-413: Add a test that exercises invalid tensor dimensionality
for PreprocessedImages by creating a mismatched-rank ArrayD (e.g., 3D or 6D) and
asserting that PreprocessedImages::new_dynamic yields an instance where calling
channels(), height(), and width() returns Err(TransformError::InvalidShape);
locate the APIs by referencing PreprocessedImages::new_dynamic and the methods
channels(), height(), width() and assert the error variant
TransformError::InvalidShape for each call.

In `@multimodal/src/vision/processors/phi4_vision.rs`:
- Around line 486-490: Replace the defensive ok_or(TransformError::EmptyBatch)?
on the max_crops computation with an expect that documents the proven invariant
(e.g., change the call on all_outputs.iter().map(|o| o.shape()[0]).max() to
.expect("images non-empty; all_outputs populated from images") so the code
reflects the checked precondition), updating the variable max_crops accordingly
and leaving TransformError usage untouched elsewhere.

In `@multimodal/tests/vision_golden_tests.rs`:
- Around line 576-578: Replace the .unwrap() call on
processor.reshape_to_patches(&tensor_3d, grid_t, grid_h, grid_w) with an
.expect(...) to provide a clearer diagnostic; update the call that produces
rust_patches (currently: let rust_patches =
processor.reshape_to_patches(&tensor_3d, grid_t, grid_h, grid_w).unwrap();) to
use .expect("reshape_to_patches failed") so failures in reshape_to_patches are
reported consistently and with a helpful message.
- Around line 402-404: Replace the call that uses .unwrap() on
processor.reshape_to_patches(&tensor_3d, grid_t, grid_h, grid_w) with
.expect(...) to provide actionable failure context; specifically update the
expression that assigns rust_patches (the result of
processor.reshape_to_patches) to use .expect("reshape_to_patches failed for
qwen2_vl") so test failures identify the reshape operation and model.

---

Outside diff comments:
In `@auth/src/jwt.rs`:
- Around line 397-452: The extract_role function currently defaults to
Role::User even when self.config.role_mapping is non-empty, which silently
grants access for unmapped roles; change extract_role to return Result<Role,
JwtError> (or Option<Role>) instead of Role, return Err(...) when role_mapping
is configured but no mapping or direct parse matches (replace the final
warn+Role::User with an error), and update all callers of extract_role to
propagate or handle the error so missing mappings cause
authentication/authorization failure rather than implicit User access; keep the
direct-parse/default behavior only when role_mapping.is_empty() if you want to
preserve backward compatibility.

In `@data_connector/src/config.rs`:
- Around line 135-149: The comment for the struct field retention_days is
incorrect given the serde default; update the comment on the retention_days
field to state that when omitted it defaults to Some(30) via the #[serde(default
= "default_redis_retention_days")] function and that a 30-day TTL will be
applied in Redis expiration calls (see default_redis_retention_days and usages
in redis.rs where expiration is applied). Keep the comment concise and mention
that explicitly setting None still means data persists indefinitely, while
omitting the field results in a 30-day retention.

In `@model_gateway/benches/tool_parser_benchmark.rs`:
- Around line 698-748: The current branch that computes latency stats returns
p50 * iters as u32 which can misreport the benchmark duration; instead compute
and return a Duration that reflects the measured work: after warmup and the
1000-sample loop, sum or average the collected latencies (latencies.iter().sum()
or average p50) and scale that to the requested iters to produce a Duration (or
compute the actual elapsed time across the warmup+measurement loops with Instant
and return that); update the total_duration assignment (the variable
total_duration and the branch using printed_clone) to use that Duration so
Criterion sees a consistent timing, and ensure types convert correctly between
Duration and the iters scaling when replacing p50 * iters as u32.

In `@model_gateway/benches/wasm_middleware_latency.rs`:
- Around line 42-55: The spawned task in mock_next_streaming currently sleeps
for 500ms even if the receiver is dropped, causing accumulating sleeping tasks
across iterations; modify the task to detect receiver closure (use
tx.closed().await or check tx.is_closed()/tx.closed() before/after the sleep and
before sending the final chunk) and return early if the receiver is dropped so
the task doesn't continue sleeping and skew benchmark latency. Ensure checks are
placed after the first send and before the sleep/send of the final chunk to bail
out promptly when the receiver is gone.

In `@model_gateway/src/core/job_queue.rs`:
- Around line 785-791: The computation of now from
SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs() can
yield 0 on error and cause underflow when doing now - value.timestamp inside
status_map.retain; update the retain predicate to use a saturating subtraction
(e.g., now.saturating_sub(value.timestamp) < STATUS_TTL) so the subtraction
cannot underflow, referencing the now variable, status_map.retain call,
value.timestamp field and STATUS_TTL constant.

In `@model_gateway/src/core/worker_manager.rs`:
- Around line 369-381: The current branch skips updating when loads.is_empty(),
which leaves stale state in PowerOfTwo policies and subscribers; change the
logic to always iterate over power_of_two_policies and call
policy.update_loads(&loads) even when loads.is_empty(), and still send the
(empty) loads via let _ = tx.send(loads) so watchers are notified/cleared; keep
the warn!("No loads fetched from workers") but do not return early—always
perform the update_loads loop and tx.send call using the existing variables
(loads, power_of_two_policies, policy.update_loads, tx.send).

In `@model_gateway/src/policies/bucket.rs`:
- Around line 33-39: The Drop implementation for BucketPolicy only drops the
JoinHandle (adjustment_handle) but doesn't signal the spawned adjustment thread
to exit, causing a leak; modify BucketPolicy to include a shutdown signal (e.g.,
an Arc<AtomicBool> named shutdown or a channel receiver) that the spawned thread
checks in its loop (check shutdown.load(Ordering::Relaxed) or recv timeout) and
breaks out when signaled, set that signal in BucketPolicy::drop prior to
taking/joining adjustment_handle, and then join the handle (call join on the
taken JoinHandle) to ensure the background thread terminates cleanly.

In `@model_gateway/src/policies/consistent_hashing.rs`:
- Around line 163-177: The fallback selection currently counts healthy workers
then re-iterates workers to pick the Nth healthy, which can return None if
health changes between iterations; instead collect the healthy worker indices in
a single pass (e.g., build a Vec<usize> of indices from
workers.iter().enumerate().filter(|(_, w)| w.is_healthy()).map(|(i,_)|
i).collect()), check if that Vec is empty, then pick a random index from that
Vec (use rand rng to choose within 0..vec.len()) and return Some(chosen_index)
with Branch::RandomFallback; update the code references around healthy_count,
random_healthy_idx, and the .nth(...) logic accordingly so selection is
consistent.

In `@model_gateway/src/routers/grpc/proto_wrapper.rs`:
- Around line 483-528: Add non-panicking "try" accessors alongside the existing
panicking ones: implement try_as_sglang(&self) ->
Option<&sglang::GenerateComplete>, try_as_sglang_mut(&mut self) -> Option<&mut
sglang::GenerateComplete>, try_as_vllm(&self) ->
Option<&vllm::GenerateComplete>, and try_as_trtllm(&self) ->
Option<&trtllm::GenerateComplete> in the same impl that contains
as_sglang/as_sglang_mut/as_vllm/as_trtllm; each should match self and return
Some(complete) for the corresponding variant (Self::Sglang, Self::Vllm,
Self::Trtllm) or None for other variants, so callers can choose Option-based
handling instead of relying on is_* + panicking accessors.

In `@model_gateway/src/routers/parse/handlers.rs`:
- Around line 57-63: Update the error! macro format strings to use named
interpolation for the error variable instead of positional placeholders: replace
occurrences like error!("Failed to parse function calls: {}", e) and
error!("Failed to separate reasoning: {}", e) with error!("Failed to parse
function calls: {e}") and error!("Failed to separate reasoning: {e}")
respectively in the parse handler in handlers.rs; leave the logs that reference
struct field accesses (e.g., req.tool_call_parser and req.reasoning_parser)
as-is since Rust's format inlining does not support field access in the same
way.

In `@model_gateway/tests/common/mock_worker.rs`:
- Around line 1235-1259: RESP_STORE currently retains responses for the process
lifetime causing cross-test leakage; add a cleanup function (e.g.,
remove_responses_for_port or clear_responses_for_port) that locks get_store(),
removes the HashMap entry for the given port (map.remove(&port)), and call this
cleanup from the worker shutdown/stop path so per-port entries are cleared when
a worker stops; reference RESP_STORE, get_store(), store_response_for_port, and
response_exists_for_port to locate where to add and invoke the cleanup.

In `@multimodal/src/vision/image_processor.rs`:
- Around line 79-84: The uint_2d constructor (uint_2d) currently constructs
Self::UintTensor without validating that data.len() matches rows * cols; add a
check that data.len() == rows.checked_mul(cols).unwrap_or(usize::MAX) (or
equivalent safe multiply) and handle mismatches: either change uint_2d to return
a Result<Self, Error> and return Err when lengths differ, or keep the infallible
API but add a debug_assert!(data.len() == rows * cols, "mismatched data length")
and document the precondition; update any callers/tests accordingly.

In `@protocols/src/interactions.rs`:
- Around line 1076-1109: Update validate_interactions_request to enforce and
document the agent/background constraints and add unit tests: ensure that
validate_interactions_request (operating on InteractionsRequest) requires
background == true whenever agent is set, rejects requests that set background
== true without an agent, and rejects requests where background and stream are
both true (these checks already exist but confirm behavior for Gemini agent by
adding a comment above validate_interactions_request documenting "Agent
interactions must set background = true (Gemini requirement)"); add unit tests
exercising (1) agent present with background=false fails, (2) background=true
without agent fails, and (3) background=true and stream=true fails, using the
existing ValidationError variants ("agent_requires_background",
"background_requires_agent", "background_conflicts_with_stream") to assert
correct errors so future changes are caught.

In `@reasoning_parser/src/factory.rs`:
- Around line 600-606: The hardcoded throughput assertion using the computed
variable throughput (from total_requests and duration) can cause CI flakiness;
replace the literal 1000.0 with a configurable threshold read from an
environment variable (e.g. THROUGHPUT_THRESHOLD) parsed into an f64 with a safe
default (or lower default if you prefer), validate/handle parse errors by
falling back to the default, and then assert throughput > threshold using the
parsed value so tests can run reliably on slower CI runners; update the
assertion message to include the actual threshold variable for clarity.
- Around line 63-85: The get_pooled_parser function has a TOCTOU race: two
threads can both miss the pool read and create distinct parser instances, with
one overwriting the other. Fix by using double-checked locking: first read
self.pool to see if the parser exists (keep that early fast path), then if
missing read self.creators to get the creator, then acquire a write lock on
self.pool and check again if the entry exists; if it exists return that Arc,
otherwise call the creator to build the parser, insert it into the pool
(pool.insert(name.to_string(), Arc::clone(&parser))) and return the newly
created Arc. Ensure you reference get_pooled_parser, self.pool, self.creators,
and the creator() call when making the change.
- Around line 608-643: The test currently only checks for absence of panic but
not that pooled parsers preserve referential integrity; update the
test_concurrent_pool_modifications to capture a baseline Arc from
ParserFactory::get_pooled (use ParserFactory::get_pooled("deepseek-r1") or other
model), run the concurrent tasks, then retrieve the parser again and assert
Arc::ptr_eq(&baseline_arc, &new_arc) (or use pointer equality checks for
multiple model keys) to ensure the TOCTOU race is fixed; if needed, use a
synchronization primitive (Barrier) to ensure the baseline is taken before
concurrent clears begin and the final fetch happens after operations complete.

---

Duplicate comments:
In `@kv_index/src/string_tree.rs`:
- Around line 481-484: The code silently returns when let Some(first_new_char) =
contracted_text.first_char() else { ... } finds no char, which hides invariant
violations; replace the silent return with a fail-fast assertion (e.g.,
unreachable! or panic!/debug_assert!) including context (contracted_text and the
invariant "split_at_char with shared_count < char_count guarantees non-empty
suffix") so corruption is surfaced; update the branch in string_tree.rs where
contracted_text.first_char() is matched (the split_at_char / shared_count <
char_count path) to assert/unreachable with a clear error message instead of
returning.

In `@mcp/src/core/oauth.rs`:
- Around line 149-155: The spawned callback server currently runs indefinitely;
replace the fire-and-forget tokio::spawn of axum::serve(listener, app) with a
graceful shutdown tied to the OAuth callback: create a oneshot::channel (or
similar) before spawning, pass the Receiver into
axum::Server::bind(listener).serve(...).with_graceful_shutdown(receiver), and
have the OAuth callback handler send on the Sender when it receives the
authorization code so the server shuts down; update the code around
tokio::spawn, listener, and app to wire the sender into the handler and remove
the misleading reason in the clippy expect if desired.

In `@model_gateway/src/core/token_bucket.rs`:
- Around line 58-63: Add input validation at the public API boundary: in
try_acquire (before delegating to try_acquire_sync) check that tokens is finite
(tokens.is_finite()), non‑negative (tokens >= 0.0) and does not exceed the
bucket capacity (tokens <= self.capacity); if any check fails return the error
variant (Err(())) immediately. Mirror the same validations at the start of
acquire and return_tokens so callers cannot pass
non‑finite/negative/over‑capacity values and thus preserve bucket invariants.
Ensure you reference the same error return convention used by try_acquire (and
consistently for acquire/return_tokens) and do not alter internal helpers like
try_acquire_sync beyond relying on the validated input.

In `@model_gateway/src/middleware.rs`:
- Around line 425-428: The expect attribute's reason text misstates the task
lifetime; update the reason string on the #[expect(...)] attribute (the one
guarding clippy::disallowed_methods) to say that dropping the oneshot receiver
does not cancel the spawned task and that the spawned task can outlive the
request until remaining_timeout completes or the runtime shuts down (mentioning
"remaining_timeout" and "oneshot receiver" in the text for clarity).

In `@model_gateway/src/policies/bucket.rs`:
- Around line 147-169: The removal path leaves stale boundary state when the
last URL is removed because init_prefill_worker_urls is only called when
updated_len > 0; update the logic so that after removing the worker and updating
chars_per_url and bucket_cnt you always reset the bucket boundary state—call
bucket_guard.init_prefill_worker_urls with an empty list (or otherwise clear the
internal boundary structure) when updated_len == 0 so find_boundary and related
logic won't return URLs that no longer exist; adjust the branch around
init_prefill_worker_urls in the removal block (references:
bucket_guard.prefill_worker_urls, bucket_guard.chars_per_url,
bucket_guard.init_prefill_worker_urls, bucket_guard.bucket_cnt, boundary,
find_boundary).
- Around line 116-137: The code always calls
bucket_guard.init_prefill_worker_urls and logs "Added worker" even when the URL
already existed, which resets per-URL state; modify the block that reads
bucket_guard.prefill_worker_urls and bucket_guard.chars_per_url so it first
checks for existence and only performs the push, chars_per_url.entry(...)
insertion, cloning, the call to init_prefill_worker_urls, and the info! log when
the URL was actually newly inserted. Use the existing symbols worker.url(),
bucket_guard.prefill_worker_urls, bucket_guard.chars_per_url, and
init_prefill_worker_urls to gate the state mutation and logging on an actual
addition.

In `@model_gateway/src/routers/grpc/regular/streaming.rs`:
- Around line 372-417: The current branch always continues when tool parsing is
attempted, causing normal delta text to be dropped if process_tool_calls_stream
(called on self.process_tool_calls_stream) fails or returns an empty
tool_chunks; change the control flow so you only skip regular content when
tool_chunks actually contains emitted/buffered chunks (i.e., when the parser
successfully handled the delta). Concretely, after calling
Self::process_specific_function_stream or
self.process_tool_calls_stream(...).await, check whether tool_chunks is empty
(or have the called function return a clear "handled" flag/result) and only run
the loop that formats/sends chunks and execute continue when there were emitted
chunks; otherwise fall through to the regular delta processing path so normal
content is preserved.

In `@model_gateway/tests/otel_tracing_test.rs`:
- Around line 249-254: The assertion message in otel_tracing_test.rs is
inconsistent: it currently says "Expected to receive at least 2 span" while the
code asserts equality (span_count == 2); update the assertion message used with
assert! to reflect exact equality and correct pluralization (e.g., "Expected to
receive exactly 2 spans, but got {span_count}."), targeting the assertion
involving the span_count variable in the test and the subsequent println message
to ensure both use consistent wording ("spans" and "exactly 2").

In `@multimodal/src/tracker.rs`:
- Around line 166-169: The expect attribute's reason string in the
#[expect(clippy::disallowed_methods, reason = "...")] on the spawn handle
comment is inaccurate — it says the handle is awaited in resolve() but the
actual method is finalize(); update the reason string to reference finalize()
instead so it reads something like "spawn handle is stored in self.pending and
awaited in finalize(); fire-and-forget is intentional for concurrent media
fetching", keeping the rest of the attribute intact (locate the expect attribute
in tracker.rs near the spawn/pending logic).

In `@protocols/src/responses.rs`:
- Around line 928-931: Replace the unsafe-style comment before the guard with a
safe-code invariant note: change the line starting with "// SAFETY: has_tools is
true here, so tools is Some and non-empty" that precedes the pattern match "let
Some(tools) = request.tools.as_ref() else { return Ok(()); }" to use "//
INVARIANT:" (or "// Note:") instead, keeping the same explanation about
has_tools and tools being Some and non-empty.

In `@protocols/src/worker.rs`:
- Around line 338-343: The defensive fallback in the match arm that handles the
case where models.len() == 1 is unreachable because into_iter().next() must
return Some; replace the current let Some(model) = models.into_iter().next()
else { return Self::Wildcard; } pattern with a direct unwrap/expect to make the
invariant explicit (e.g., call expect with a clear message) and return
Self::Single(Box::new(model)) as before; update the match arm around
models.len() == 1, Self::Single, and Self::Wildcard to reflect this change.

Comment thread mesh/src/crdt.rs
Comment on lines +296 to 299
#[expect(dead_code)]
pub fn contains_key(&self, key: &SKey) -> bool {
self.inner.read().contains_key(key)
}

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

# Search for contains_key usage across the codebase
echo "=== Searching for contains_key usage ==="
rg -n '\.contains_key\(' --type rust

echo -e "\n=== Searching for SyncCRDTMap context ==="
rg -n 'SyncCRDTMap' --type rust -B 2 -A 5

echo -e "\n=== Checking mesh/src/crdt.rs around line 296 ==="
sed -n '285,310p' mesh/src/crdt.rs

Repository: lightseekorg/smg

Length of output: 16715


Consider adding a documentation comment to clarify API intent.

The #[expect(dead_code)] attribute correctly identifies that contains_key is unused internally. If this method is retained for API completeness or future use, add a comment explaining that intent rather than relying solely on the attribute to communicate purpose.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mesh/src/crdt.rs` around lines 296 - 299, Add a short documentation comment
above the contains_key method explaining its purpose and why it exists despite
being unused internally (e.g., provided for API completeness or future external
use), so the #[expect(dead_code)] attribute isn’t the only signal; update the
doc to reference the method name contains_key and mention that it checks
membership via self.inner.read().contains_key(key) for clarity to future
readers.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The #[expect(dead_code)] with reason attribute already documents the intent. Adding additional doc comments is a style preference out of scope for this PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Acknowledged. We’ll leave contains_key as-is with #[expect(dead_code)] and won’t push additional doc comments in this clippy-enforcement PR. Noting this preference for future reviews.


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: mesh/src/crdt.rs:296-299
Timestamp: 2026-02-21T02:36:27.133Z
Learning: Repo lightseekorg/smg — For clippy/lint-only PRs (e.g., PR `#489`), avoid requesting stylistic doc comments when an item is already annotated with #[expect(...)] (e.g., #[expect(dead_code)] on SyncCRDTMap::contains_key in mesh/src/crdt.rs); such style changes are considered out of scope.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: kv_index/src/string_tree.rs:481-484
Timestamp: 2026-02-21T02:30:52.128Z
Learning: Preference noted: In kv_index/src/string_tree.rs (Rust radix tree), production code should avoid panics on invariant breaches; prefer a defensive non-panicking path (e.g., early return) and use debug_assert! for debug/test builds. Consider documenting the invariant with a comment, and optionally log under cfg(debug_assertions).

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Comment thread mesh/src/sync.rs
/// Sync policy state to mesh stores
pub fn sync_policy_state(&self, model_id: String, policy_type: String, config: Vec<u8>) {
let key = SKey::new(format!("policy:{}", model_id));
let key = SKey::new(format!("policy:{model_id}"));

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Inconsistent key formatting style with apply_remote_policy_state.

Lines 83, 112, and 130 use named interpolation format!("policy:{model_id}"), but line 172 in apply_remote_policy_state still uses positional interpolation format!("policy:{}", state.model_id). Consider updating line 172 for consistency.

Also applies to: 112-112, 130-130

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mesh/src/sync.rs` at line 83, The key formatting is inconsistent: several
places construct the policy key with named interpolation using
format!("policy:{model_id}") (e.g., SKey::new calls that use that pattern), but
apply_remote_policy_state still uses positional interpolation
format!("policy:{}", state.model_id); update the call inside
apply_remote_policy_state to use the same named-interpolation style
(format!("policy:{model_id}") referencing state.model_id) so all
SKey::new(policy...) usages are consistent with the rest of the file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

False positive. Rust named interpolation ({model_id}) only works with simple identifiers, not field access expressions. format\!("policy:{}", state.model_id) on line 172 uses positional interpolation because state.model_id is a field access which cannot be inlined into the format string.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 You’re absolutely right—thanks for the correction. Rust’s implicit capture in format strings only supports simple identifiers, not field paths, so {state.model_id} isn’t valid. Line 172 using format!("policy:{}", state.model_id) is correct as-is. No change needed.

If we ever wanted to unify style, we’d have to bind a local first (e.g., let model_id = &state.model_id; then format!("policy:{model_id}")), but that’s unnecessary churn here, especially for this clippy-focused PR where we avoid nonessential edits.


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: mesh/src/sync.rs:83-83
Timestamp: 2026-02-21T02:37:01.416Z
Learning: Rust format! implicit capture like "{ident}" only supports simple identifiers, not field accesses. In mesh/src/sync.rs, keep format!("policy:{}", state.model_id) rather than attempting "{state.model_id}". Use a local binding (e.g., let model_id = &state.model_id;) if named interpolation is desired.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Comment thread model_gateway/benches/wasm_middleware_latency.rs
Comment thread model_gateway/benches/wasm_middleware_latency.rs
Comment thread model_gateway/src/routers/grpc/regular/streaming.rs Outdated
Comment on lines +411 to +413
assert_eq!(images.channels().unwrap(), 3);
assert_eq!(images.height().unwrap(), 336);
assert_eq!(images.width().unwrap(), 336);

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding a test for invalid tensor dimensionality.

The existing tests only cover the happy path. Consider adding a test that verifies channels(), height(), and width() return TransformError::InvalidShape when given a tensor with unsupported dimensionality (e.g., 3D or 6D).

🧪 Proposed test for error case
#[test]
fn test_preprocessed_images_invalid_ndim() {
    use ndarray::ArrayD;
    
    // Create a 3D tensor (invalid for this API)
    let pixel_values_3d = ArrayD::<f32>::zeros(vec![2, 3, 336]);
    let images = PreprocessedImages::new_dynamic(
        pixel_values_3d,
        vec![576],
        vec![(640, 480)],
    );

    assert!(images.channels().is_err());
    assert!(images.height().is_err());
    assert!(images.width().is_err());
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@multimodal/src/vision/image_processor.rs` around lines 411 - 413, Add a test
that exercises invalid tensor dimensionality for PreprocessedImages by creating
a mismatched-rank ArrayD (e.g., 3D or 6D) and asserting that
PreprocessedImages::new_dynamic yields an instance where calling channels(),
height(), and width() returns Err(TransformError::InvalidShape); locate the APIs
by referencing PreprocessedImages::new_dynamic and the methods channels(),
height(), width() and assert the error variant TransformError::InvalidShape for
each call.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adding new tests is out of scope for this clippy-focused PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Acknowledged—sticking to the clippy-only scope; I won’t propose adding new tests in this PR. If you’d like, I can open a follow-up issue to add invalid-ndim tests for PreprocessedImages::channels/height/width later. I’ve noted this repo preference for future reviews.


🧠 Learnings used
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: mesh/src/crdt.rs:296-299
Timestamp: 2026-02-21T02:36:27.133Z
Learning: Repo lightseekorg/smg — For clippy/lint-only PRs (e.g., PR `#489`), avoid requesting stylistic doc comments when an item is already annotated with #[expect(...)] (e.g., #[expect(dead_code)] on SyncCRDTMap::contains_key in mesh/src/crdt.rs); such style changes are considered out of scope.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/benches/wasm_middleware_latency.rs:88-91
Timestamp: 2026-02-21T02:36:55.621Z
Learning: Repo: lightseekorg/smg — For clippy-only/enforcement PRs (e.g., PR `#489`), even micro-optimizations (like replacing an async closure with std::future::ready in benches such as model_gateway/benches/wasm_middleware_latency.rs) should be deferred to a follow-up PR rather than included inline.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/benches/wasm_middleware_latency.rs:1-1
Timestamp: 2026-02-21T02:37:00.043Z
Learning: Repo: lightseekorg/smg — For benchmark files (e.g., model_gateway/benches/*.rs), using a crate-level `#![expect(clippy::unwrap_used, clippy::disallowed_methods)]` is preferred when unwrap/spawn are used throughout. Do not push to per-function scoping; a single crate-level `reason` is acceptable when justification is required.

Comment on lines +486 to +490
let max_crops = all_outputs
.iter()
.map(|o| o.shape()[0])
.max()
.ok_or(TransformError::EmptyBatch)?;

@coderabbitai coderabbitai Bot Feb 21, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Defensive but technically unreachable error case.

The ok_or(TransformError::EmptyBatch)? is better than the previous .unwrap() since it provides a proper error type. However, this error case is unreachable because:

  1. The early check at lines 459-464 returns an error if images.is_empty().
  2. all_outputs is populated by iterating over images (lines 477-483).

The defensive approach is acceptable, but consider whether an expect("checked non-empty above") would be clearer about the invariant.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@multimodal/src/vision/processors/phi4_vision.rs` around lines 486 - 490,
Replace the defensive ok_or(TransformError::EmptyBatch)? on the max_crops
computation with an expect that documents the proven invariant (e.g., change the
call on all_outputs.iter().map(|o| o.shape()[0]).max() to .expect("images
non-empty; all_outputs populated from images") so the code reflects the checked
precondition), updating the variable max_crops accordingly and leaving
TransformError usage untouched elsewhere.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The defensive .ok_or(TransformError::EmptyBatch)? is intentional — returning a proper error type is safer than panicking via expect(), consistent with this PR's philosophy of replacing panicking code with recoverable errors.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@slin1237 Got it—thanks for the clarification. We’ll keep the defensive ok_or(TransformError::EmptyBatch)? here. That aligns with the repository’s preference to avoid panics in production paths for this PR. I’ll refrain from suggesting expect/unreachable on proven invariants in similar spots going forward.


✏️ Learnings added
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: multimodal/src/vision/processors/phi4_vision.rs:486-490
Timestamp: 2026-02-21T02:39:17.064Z
Learning: Repo: lightseekorg/smg — For multimodal/src/vision/processors/phi4_vision.rs (Phi4VisionProcessor::preprocess), prefer returning a recoverable error via ok_or(TransformError::EmptyBatch)? over using expect/unreachable, even when a prior non-empty check exists. This follows the repo’s “avoid panics in production code” guideline for PR `#489` and similar lint-only efforts.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: protocols/src/worker.rs:338-343
Timestamp: 2026-02-21T02:36:00.013Z
Learning: Repo: lightseekorg/smg PR: 489
File: protocols/src/worker.rs (impl From<Vec<ModelCard>> for WorkerModels)
Learning: For the single-element case (models.len() == 1), keep the defensive Option guard with a non-panicking fallback to WorkerModels::Wildcard instead of using expect()/unwrap(). This is intentional to avoid introducing panic paths in production code for PR `#489` and similar clippy/lint-only efforts.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs:189-194
Timestamp: 2026-02-21T02:32:04.647Z
Learning: Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs
Context: GrpcClient::generate fallback match arm
Learning: The catch-all panic for mismatched client/request types in GrpcClient::generate is intentional to enforce pipeline invariants; do not convert this to a returned error in PR `#489` or similar lint-only changes.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: kv_index/src/string_tree.rs:481-484
Timestamp: 2026-02-21T02:30:52.128Z
Learning: Preference noted: In kv_index/src/string_tree.rs (Rust radix tree), production code should avoid panics on invariant breaches; prefer a defensive non-panicking path (e.g., early return) and use debug_assert! for debug/test builds. Consider documenting the invariant with a comment, and optionally log under cfg(debug_assertions).

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/routers/grpc/client.rs:206-211
Timestamp: 2026-02-21T02:31:14.142Z
Learning: Repo: lightseekorg/smg
File: model_gateway/src/routers/grpc/client.rs
Context: GrpcClient::embed match arm
Learning: The catch-all panic in GrpcClient::embed for mismatched client/request types or unsupported embedding backends is intentional to catch invariant violations and unsupported configurations at development time. Converting this path to a returned error is out of scope for PR `#489`.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/core/token_bucket.rs:58-63
Timestamp: 2026-02-21T02:30:51.443Z
Learning: For lint-only/Clippy enforcement PRs in this repo (e.g., PR `#489`), avoid introducing behavioral changes (like new input validation). Prefer a separate, follow-up issue/PR for such hardening.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: mesh/src/crdt.rs:296-299
Timestamp: 2026-02-21T02:36:27.133Z
Learning: Repo lightseekorg/smg — For clippy/lint-only PRs (e.g., PR `#489`), avoid requesting stylistic doc comments when an item is already annotated with #[expect(...)] (e.g., #[expect(dead_code)] on SyncCRDTMap::contains_key in mesh/src/crdt.rs); such style changes are considered out of scope.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/benches/wasm_middleware_latency.rs:88-91
Timestamp: 2026-02-21T02:36:55.621Z
Learning: Repo: lightseekorg/smg — For clippy-only/enforcement PRs (e.g., PR `#489`), even micro-optimizations (like replacing an async closure with std::future::ready in benches such as model_gateway/benches/wasm_middleware_latency.rs) should be deferred to a follow-up PR rather than included inline.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/src/policies/bucket.rs:116-137
Timestamp: 2026-02-21T02:30:56.454Z
Learning: For clippy-focused PRs in this repository, avoid behavior changes (e.g., load-balancing logic). Defer such changes to a separate PR/issue.

Learnt from: slin1237
Repo: lightseekorg/smg PR: 489
File: model_gateway/benches/wasm_middleware_latency.rs:1-1
Timestamp: 2026-02-21T02:37:00.043Z
Learning: Repo: lightseekorg/smg — For benchmark files (e.g., model_gateway/benches/*.rs), using a crate-level `#![expect(clippy::unwrap_used, clippy::disallowed_methods)]` is preferred when unwrap/spawn are used throughout. Do not push to per-function scoping; a single crate-level `reason` is acceptable when justification is required.

Comment thread multimodal/tests/vision_golden_tests.rs
Comment thread multimodal/tests/vision_golden_tests.rs
What changed:
- server.rs: Fix P1 bug — HealthChecker handle was bound to block-local
  variable inside else branch, causing immediate Drop and aborting the
  health check background task. Moved binding to outer scope so it lives
  for the entire server lifetime.
- middleware.rs: Fix inaccurate #[expect] reason string about spawned
  task lifetime — task is bounded by remaining_timeout and self-terminates,
  dropping JoinHandle only detaches it.
- metrics_aggregator_test.rs: Remove redundant .trim() calls since
  assert_eq_sorted already trims internally.
- otel_tracing_test.rs: Fix assertion/message mismatch — assertion uses
  == (exact) but message said "at least". Fixed to "exactly 2 spans".
- tracker.rs: Fix incorrect method name in #[expect] reason string —
  resolve() → finalize() to match actual method.
- responses.rs: Rename // SAFETY: to // INVARIANT: for non-unsafe code
  following Rust documentation conventions.

Why:
Addresses PR #489 review feedback. The HealthChecker bug is a real
production issue where periodic worker health checks were never running
after startup. Other fixes correct documentation accuracy.

Signed-off-by: Simo Lin <simo.lin@oracle.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @slin1237, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances code quality and reliability across the entire workspace by enforcing strict Clippy linting rules. It addresses numerous potential panic points, improves error handling, and refines API consistency and efficiency. The changes span across 26 crates, involving a comprehensive audit and fix of over 300 files, leading to a more robust and maintainable codebase.

Highlights

  • Strict Clippy Linting: Introduced clippy.toml and workspace-level [lints.clippy] to enforce production-grade code quality, denying unwrap/expect/panic in production code paths without justification.
  • Bug Fixes: Fixed critical bugs including CRDT timestamp data corruption, a DashMap TOCTOU race condition, a HealthChecker task leak, dead Result wrappers, and Postgres constructor panics.
  • Code Quality Improvements: Migrated std::sync::Mutex/RwLock to parking_lot equivalents, removed unnecessary async from 19 functions, improved API signatures, and eliminated panics in production code.
  • Mechanical Code Refinements: Applied widespread mechanical fixes such as updating format! macros to Rust 2021 syntax, reducing raw string hashes, migrating #[allow] to #[expect], using clone_from() for efficiency, and refining match arms and parameter passing for Copy types.
  • Test and Benchmark Updates: Updated test and benchmark files with file-level #[expect] attributes for ergonomic linting, ensuring mechanical fixes without altering test assertions.
Changelog
  • Cargo.toml
    • Added unsafe_code = "deny" to [workspace.lints.rust].
    • Introduced [workspace.lints.clippy] section to deny unwrap_used, dbg_macro, todo, unimplemented, unreachable, and warn on expect_used, panic, print_stdout, print_stderr, allow_attributes, disallowed_methods, and various code quality lints.
    • Explicitly allowed some pedantic Clippy lints.
  • auth/src/config.rs
    • Refactored is_admin method to accept self by value.
    • Updated string formatting to Rust 2021 syntax.
  • auth/src/jwks.rs
    • Modified IP address validation functions to accept Ipv4Addr by value.
    • Updated string formatting to Rust 2021 syntax.
    • Migrated #[allow(dead_code)] to #[expect(dead_code)].
  • auth/src/jwt.rs
    • Migrated #[allow(dead_code)] to #[expect(dead_code)] with reasons.
    • Improved LruCache initialization to prevent panics on zero capacity.
    • Refactored extract_role to return Role directly instead of Result<Role, JwtValidatorError>.
    • Updated string formatting to Rust 2021 syntax.
  • auth/src/middleware.rs
    • Updated string formatting to Rust 2021 syntax.
  • bindings/golang/src/client.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Adjusted generate_tool_constraints to take tool_choice by reference.
  • bindings/golang/src/error.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
  • bindings/golang/src/grpc_converter.rs
    • Simplified null checks for optional JSON fields.
    • Replaced unwrap() with unwrap_or_default() for SystemTime conversion with justification.
    • Replaced CString::new("").unwrap() with CString::default().
    • Updated string formatting to Rust 2021 syntax.
    • Corrected arguments and content conditional assignments to check for empty values.
  • bindings/golang/src/lib.rs
    • Added #![allow(unsafe_code)] with a reason for FFI bindings.
  • bindings/golang/src/policy.rs
    • Modified api_key method signature to return Option<&String>.
    • Updated string formatting to Rust 2021 syntax.
    • Modified build_http_client to pass token.as_deref().
    • Modified generate_tool_constraints to take tool_choice by reference.
  • bindings/golang/src/postprocessor.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
  • bindings/golang/src/preprocessor.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Adjusted generate_tool_constraints to take tool_choice by reference.
  • bindings/golang/src/runtime.rs
    • Added #[expect(clippy::expect_used)] to the global Tokio runtime initialization.
  • bindings/golang/src/stream.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
    • Updated string formatting in error messages to Rust 2021 syntax.
  • bindings/golang/src/tokenizer.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Replaced CString::new("").unwrap() with CString::default().
  • bindings/golang/src/tool_parser.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Simplified tool parsing logic for tools.
  • bindings/python/src/lib.rs
    • Replaced #[allow(clippy::too_many_arguments)] with #[expect(clippy::too_many_arguments)].
    • Added #[expect(clippy::unnecessary_wraps)] to PyO3 #[new] methods.
    • Updated string formatting to Rust 2021 syntax.
  • clippy.toml
    • Added a new configuration file to allow unwrap/expect/panic in test code.
    • Configured disallowed-macros and disallowed-methods for specific panic-inducing patterns.
    • Set cognitive-complexity-threshold and type-complexity-threshold.
  • data_connector/src/config.rs
    • Updated string formatting in validation messages to Rust 2021 syntax.
    • Added #[expect(clippy::unnecessary_wraps)] to default_redis_retention_days.
  • data_connector/src/core.rs
    • Updated string formatting in ID generation to Rust 2021 syntax.
  • data_connector/src/memory.rs
    • Removed #[allow(clippy::type_complexity)] attributes.
    • Updated iteration patterns for BTreeMap.
    • Changed #[allow(dead_code)] to #[cfg(test)] for test-only functions.
    • Used clone_from instead of clone for current_id.
  • data_connector/src/oracle.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Replaced #[allow(clippy::manual_async_fn)] with #[expect(clippy::manual_async_fn)].
    • Used clone_from instead of clone for current_id.
  • data_connector/src/postgres.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
    • Simplified if !rows.is_empty() check.
    • Used clone_from instead of clone for current_id.
  • data_connector/src/redis.rs
    • Updated string formatting in key generation to Rust 2021 syntax.
    • Used clone_from instead of clone for current_id.
  • grpc_client/src/sglang_scheduler.rs
    • Replaced #[allow(clippy::all)] with #[expect(clippy::allow_attributes)].
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn in Drop impl.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unused_self)] to builder methods for API consistency.
    • Changed build_grpc_sampling_params_from_chat, extract_stop_strings, build_constraint_for_chat, build_grpc_sampling_params_from_responses, build_constraint_for_responses to be static methods.
    • Used clone_from for sampling.stop_token_ids.
  • grpc_client/src/trtllm_service.rs
    • Replaced #[allow(clippy::all)] with #[expect(clippy::allow_attributes)] and added clippy::trivially_copy_pass_by_ref.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn in Drop impl.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unused_self)] and #[expect(clippy::unnecessary_wraps)] to builder methods for API consistency.
    • Changed build_sampling_config_from_chat, build_output_config_from_chat, build_guided_decoding_from_chat, build_sampling_config_from_responses, build_guided_decoding_from_responses, build_sampling_config_from_plain, build_guided_decoding_from_plain to be static methods and removed Result wrappers where infallible.
  • grpc_client/src/vllm_engine.rs
    • Replaced #[allow(clippy::all)] with #[expect(clippy::allow_attributes)].
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn in Drop impl.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unused_self)] to builder methods for API consistency.
    • Changed build_grpc_sampling_params_from_chat, extract_stop_strings, build_constraint_for_chat, build_grpc_sampling_params_from_responses, build_constraint_for_responses to be static methods.
    • Used clone_from for sampling.stop_token_ids.
  • kv_index/src/string_tree.rs
    • Replaced #[allow(clippy::non_canonical_partial_ord_impl)] with #[expect(clippy::non_canonical_partial_ord_impl)].
    • Updated while loop patterns for character iteration.
    • Added else { return; } to handle potential empty suffixes.
    • Removed #[allow(dead_code)] from several public methods.
    • Updated iteration patterns for DashMap and BTreeMap.
    • Added #[expect(clippy::print_stdout)] to pretty_print and test module.
    • Updated string formatting to Rust 2021 syntax.
    • Changed sizes_after.iter() to sizes_after.values().
  • kv_index/src/token_tree.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
    • Updated assert_eq! message in with_config.
    • Updated iteration patterns for DashMap.
    • Updated string formatting to Rust 2021 syntax.
  • mcp/src/approval/audit.rs
    • Updated string formatting to Rust 2021 syntax.
  • mcp/src/approval/manager.rs
    • Added #[expect(clippy::unused_async)] to request_interactive and resolve methods.
    • Refined pattern matching for ApprovalDecision in denial reason.
    • Updated panic! message for expected ApprovalOutcome.
  • mcp/src/approval/policy.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed evaluate_with_trust to accept TrustLevel by value.
  • mcp/src/core/config.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed response_format method to accept self by value.
  • mcp/src/core/handler.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
  • mcp/src/core/oauth.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for OAuth callback server.
  • mcp/src/core/orchestrator.rs
    • Modified build_request_headers and build_http_client to accept Option<&str> for tokens.
    • Updated string formatting to Rust 2021 syntax.
    • Modified build_http_client to pass token.as_deref().
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for refresh handler.
    • Changed _ = token.cancelled() to () = token.cancelled().
    • Updated iteration patterns for static_servers.
    • Changed call_result_to_json, apply_arg_mapping, transform_result to be static methods.
  • mcp/src/core/pool.rs
    • Adjusted hash_auth to accept Option<&String>.
    • Modified hash_auth to pass token.as_ref().
    • Ensured max_connections is at least 1 and used unwrap_or(NonZeroUsize::MIN) for NonZeroUsize::new.
  • mcp/src/core/proxy.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
  • mcp/src/core/reconnect.rs
    • Updated string formatting in error messages to Rust 2021 syntax.
  • mcp/src/core/session.rs
    • Updated string formatting to Rust 2021 syntax.
  • mcp/src/inventory/index.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to test_concurrent_access.
  • mcp/src/inventory/types.rs
    • Updated string formatting to Rust 2021 syntax.
  • mcp/src/responses_bridge.rs
    • Replaced unwrap_or with unwrap_or_else.
  • mcp/src/transform/transformer.rs
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/consistent_hash.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::expect_used)] to hash_position.
    • Replaced #[allow(dead_code)] with #[cfg(test)] for test-only functions.
  • mesh/src/controller.rs
    • Updated tokio::select! patterns to use () for ignored futures.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Used clone_from for e.address.
    • Changed or_insert to or_insert_with.
    • Fixed unreachable_node.status = NodeStatus::Down as i32 to include semicolon.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls.
    • Changed cloned() to copied() for get_random_values_refs.
  • mesh/src/crdt.rs
    • Added #[expect(clippy::expect_used)] to LWWRegister::new and write methods with justification.
    • Used clone_from for self.actor.
    • Replaced #[allow(dead_code)] with #[expect(dead_code)] and #[cfg(test)].
    • Added #[expect(clippy::print_stdout)] to test diagnostic output.
    • Updated string formatting to Rust 2021 syntax.
    • Changed values.sort() to values.sort_unstable().
  • mesh/src/flow_control.rs
    • Removed #[allow(dead_code)] from module level.
    • Replaced #[allow(dead_code)] with #[expect(dead_code)] for specific functions.
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/incremental.rs
    • Added #[expect(clippy::expect_used)] to current_timestamp with justification.
  • mesh/src/metrics.rs
    • Removed #[allow(dead_code)] from module level.
    • Replaced #[allow(dead_code)] with #[expect(dead_code)] for test-related metrics.
  • mesh/src/mtls.rs
    • Added #[expect(clippy::disallowed_methods)] to start_rotation_monitor with justification.
  • mesh/src/node_state_machine.rs
    • Changed as_str method to accept self by value.
  • mesh/src/partition.rs
    • Updated iteration patterns for cluster_state.
  • mesh/src/ping_server.rs
    • Added #[expect(clippy::expect_used)] to create_snapshot_chunks and SystemTime conversions with justification.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls with justification.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Changed _ to StreamMessageType::SnapshotComplete for pattern matching.
    • Changed async fn merge_state to fn merge_state.
    • Used clone_from for peer_id.
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/rate_limit_window.rs
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn in tests with justification.
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/service.rs
    • Added #![allow(clippy::trivially_copy_pass_by_ref, clippy::allow_attributes)] to the gossip module.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls with justification.
    • Added #[expect(clippy::expect_used)] to partition_detector access with justification.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/stores.rs
    • Changed as_str method to accept self by value.
    • Updated string formatting to Rust 2021 syntax.
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
  • mesh/src/sync.rs
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/tests/comprehensive.rs
    • Updated string formatting to Rust 2021 syntax.
  • mesh/src/topology.rs
    • Added #![cfg_attr(not(test), allow(dead_code, clippy::allow_attributes))] to suppress dead code in non-test builds.
    • Removed #[allow(dead_code)] from module level.
    • Updated iteration patterns for state.
  • mesh/src/tree_ops.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/benches/manual_policy_benchmark.rs
    • Added #![expect(clippy::unwrap_used, clippy::uninlined_format_args)] for benchmark code.
  • model_gateway/benches/radix_tree_benchmark.rs
    • Added #![expect(clippy::unwrap_used, clippy::print_stderr, reason = "benchmark code")] for benchmark code.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/benches/request_processing.rs
    • Added #![expect(clippy::unwrap_used, clippy::print_stdout, clippy::allow_attributes, clippy::uninlined_format_args)] for benchmark code.
  • model_gateway/benches/router_registry_bench.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/benches/tokenizer_benchmark.rs
    • Added #![expect(clippy::unwrap_used, clippy::expect_used, clippy::print_stdout, clippy::uninlined_format_args)] for benchmark code.
    • Corrected b.iter_custom logic for latency distribution.
    • Used clone_from for current_category.
  • model_gateway/benches/tool_parser_benchmark.rs
    • Added #![expect(clippy::unwrap_used, clippy::expect_used, clippy::print_stdout, reason = "benchmark code")] for benchmark code.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/benches/wasm_instantiation.rs
    • Added #![expect(clippy::unwrap_used, clippy::expect_used)] for benchmark code.
  • model_gateway/benches/wasm_middleware_latency.rs
    • Added #![expect(clippy::unwrap_used, clippy::disallowed_methods)] for benchmark code.
    • Changed async fn mock_next_streaming to fn mock_next_streaming.
  • model_gateway/build.rs
    • Removed Result<(), Box<dyn std::error::Error>> from main function.
  • model_gateway/src/app_context.rs
    • Changed AppContext::from_config to return Pin<Box<dyn Future>>.
    • Changed AppContextBuilder::from_config to be synchronous.
    • Updated string formatting to Rust 2021 syntax.
    • Changed with_tokenizer_registry to be synchronous and return Self.
    • Changed with_load_monitor to return Result<Self, String>.
    • Removed map_err from WasmModuleManager::new.
    • Changed with_wasm_manager to return Self.
  • model_gateway/src/config/builder.rs
    • Used String::new() instead of "".to_string().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/config/types.rs
    • Updated string formatting to Rust 2021 syntax.
    • Used String::new() instead of "".to_string().
  • model_gateway/src/config/validation.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/circuit_breaker.rs
    • Changed as_str and as_int methods to accept self by value.
  • model_gateway/src/core/error.rs
    • Used String::new() instead of "".to_string().
  • model_gateway/src/core/job_queue.rs
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls with justification.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Updated string formatting to Rust 2021 syntax.
    • Used clone_from for spec.api_key.
    • Changed unwrap() to unwrap_or_default() for SystemTime conversion.
  • model_gateway/src/core/metrics_aggregator.rs
    • Updated iteration patterns for b.families.
  • model_gateway/src/core/retry.rs
    • Changed Err(_) to Err(()) for pattern matching.
  • model_gateway/src/core/steps/tokenizer_registration.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/wasm_module_registration.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/wasm_module_removal.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/worker/external/create_workers.rs
    • Updated string formatting to Rust 2021 syntax.
    • Updated iteration patterns for model_cards.
  • model_gateway/src/core/steps/worker/external/discover_models.rs
    • Added #[expect(clippy::expect_used)] to HTTP_CLIENT and DATE_SUFFIX_PATTERN initializations.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/worker/local/create_worker.rs
    • Changed normalize_url to accept connection_mode by value.
    • Updated string formatting to Rust 2021 syntax.
    • Changed labels.get("supports_vision").or(labels.get("has_image_understanding")) to or_else.
  • model_gateway/src/core/steps/worker/local/detect_backend.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed Ok(_) to Ok(()) for pattern matching.
  • model_gateway/src/core/steps/worker/local/detect_connection.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed Ok(_) to Ok(()) for pattern matching.
  • model_gateway/src/core/steps/worker/local/discover_dp.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed or to or_else.
  • model_gateway/src/core/steps/worker/local/discover_metadata.rs
    • Added #[expect(clippy::expect_used)] to HTTP_CLIENT initialization.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/worker/local/find_worker_to_update.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/worker/local/mod.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/steps/worker/local/remove_from_policy_registry.rs
    • Updated iteration patterns for workers_to_remove.
  • model_gateway/src/core/steps/worker/local/remove_from_worker_registry.rs
    • Updated iteration patterns for worker_urls.
    • Simplified conditional logic for logging removed workers.
  • model_gateway/src/core/steps/worker/local/submit_tokenizer_job.rs
    • Updated iteration patterns for workers.
  • model_gateway/src/core/steps/worker/local/update_remaining_policies.rs
    • Updated iteration patterns for affected_models.
  • model_gateway/src/core/steps/worker/local/update_worker_properties.rs
    • Updated iteration patterns for workers_to_update.
    • Changed unwrap_or to unwrap_or_else.
    • Simplified DP configuration logic.
  • model_gateway/src/core/steps/worker/shared/activate.rs
    • Updated iteration patterns for workers.
  • model_gateway/src/core/steps/worker/shared/register.rs
    • Updated iteration patterns for workers.
  • model_gateway/src/core/steps/worker/shared/update_policies.rs
    • Changed check_worker_conflicts to be a static method.
    • Updated iteration patterns for workers.
  • model_gateway/src/core/steps/workflow_engines.rs
    • Added #[expect(clippy::expect_used)] to WorkflowEngines::new initialization.
  • model_gateway/src/core/token_bucket.rs
    • Added #[expect(clippy::result_unit_err)] to try_acquire.
    • Changed async methods to synchronous where possible (try_acquire, return_tokens, available_tokens).
    • Updated tokio::select! patterns to use () for ignored futures.
  • model_gateway/src/core/worker.rs
    • Added #[expect(clippy::expect_used)] to WORKER_CLIENT initialization.
    • Changed api_key method to return Option<&String>.
    • Changed unwrap_or to unwrap_or_else.
    • Updated string formatting to Rust 2021 syntax.
    • Changed handle: tokio::task::JoinHandle<()> to handle: Option<tokio::task::JoinHandle<()>> in HealthChecker.
    • Added Drop impl for HealthChecker to abort tasks.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls in tests.
    • Added #[expect(clippy::print_stderr)] to test diagnostic output.
  • model_gateway/src/core/worker_builder.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/core/worker_manager.rs
    • Changed worker.api_key().clone() to worker.api_key().cloned().
    • Updated string formatting to Rust 2021 syntax.
    • Changed json.as_array().unwrap() to Value::Array(arr).
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for load monitor.
    • Simplified if !loads.is_empty() conditional logic.
  • model_gateway/src/core/worker_registry.rs
    • Migrated std::sync::{Arc, RwLock} to std::sync::Arc and parking_lot::RwLock.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::expect_used)] to hash_position with justification.
    • Used let mut guard = self.mesh_sync.write(); *guard = mesh_sync; for mesh sync updates.
    • Used clone_from for worker.is_healthy().
    • Changed get_by_type and get_by_connection to take WorkerType and ConnectionMode by value.
    • Changed worker.api_key().clone() to worker.api_key().cloned().
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for health checker with justification.
    • Changed unwrap_or to unwrap_or_else.
    • Updated tokio::select! patterns to use () for ignored futures.
  • model_gateway/src/core/worker_service.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed parse_worker_id to be a static method.
  • model_gateway/src/main.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::print_stderr)] to parse_role_mapping and parse_control_plane_api_key with justification.
    • Used clone_from for jwt_config.role_claim.
    • Added #[expect(clippy::panic)] to parse_policy and parse_assignment_mode with justification.
    • Changed ok_or to ok_or_else.
    • Added #[expect(clippy::print_stdout)] to main function with justification.
  • model_gateway/src/middleware.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed token_bucket.try_acquire(1.0).await to token_bucket.try_acquire(1.0).
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for permit acquisition with justification.
    • Changed Ok(_) to Ok(()) for pattern matching.
  • model_gateway/src/observability/gauge_histogram.rs
    • Added #[expect(clippy::unused_self)] to bucket_count and bound_count with justification.
    • Fixed DashMap TOCTOU race condition by using downgrade() on the entry reference.
  • model_gateway/src/observability/inflight_tracker.rs
    • Added #[expect(clippy::expect_used)] to sampler.set(task) with justification.
    • Changed sort() to sort_unstable().
  • model_gateway/src/observability/logging.rs
    • Removed #[allow(dead_code)] from LogGuard struct.
    • Added #[expect(clippy::print_stderr)] to eprintln! calls with justification.
  • model_gateway/src/observability/metrics.rs
    • Changed #[allow(dead_code)] to #[cfg(test)] for test-only function.
    • Added #[expect(clippy::expect_used)] to start_prometheus with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/observability/otel_trace.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::print_stderr)] to eprintln! calls with justification.
  • model_gateway/src/policies/bucket.rs
    • Migrated std::sync::{Arc, Mutex, RwLock} to std::sync::Arc and parking_lot::{Mutex, RwLock}.
    • Removed error! macro calls for lock poisoning.
    • Changed bucket.write() to direct assignment.
    • Changed bucket_guard.prefill_worker_urls.lock().unwrap() to bucket_guard.prefill_worker_urls.lock().
    • Changed bucket_guard.chars_per_url.lock().unwrap() to bucket_guard.chars_per_url.lock().
    • Used clone_from for urls_lock.
    • Updated iteration patterns for prefill_worker_urls.
    • Changed buc.read().unwrap() to buc.read().
    • Changed buc.chars_per_url.lock().unwrap().clone() to buc.chars_per_url.lock().clone().
    • Changed buc.write().unwrap() to buc.write().
    • Changed hist_load.values().cloned().collect() to hist_load.values().copied().collect().
    • Changed hist_load.sort() to hist_load.sort_unstable().
    • Updated iteration patterns for hist_load.
  • model_gateway/src/policies/cache_aware.rs
    • Used clone_from for self.mesh_sync.
    • Added #[expect(clippy::unused_self)] to remove_worker and remove_worker_by_url with justification.
  • model_gateway/src/policies/consistent_hashing.rs
    • Changed as_str method to accept self by value.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::expect_used)] to hash_position with justification.
    • Added #[expect(clippy::unused_self)] to select_worker_impl for API consistency.
    • Changed map(|(i, _)| i).unwrap() to map(|(i, _)| i).
  • model_gateway/src/policies/manual.rs
    • Changed as_str method to accept self by value.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/policies/power_of_two.rs
    • Used clone_from for self.cached_loads.
    • Added #[expect(clippy::print_stdout)] to tests for diagnostic output.
  • model_gateway/src/policies/prefix_hash.rs
    • Changed as_str method to accept self by value.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/policies/registry.rs
    • Migrated std::sync::{Arc, OnceLock, RwLock} to std::sync::Arc and parking_lot::RwLock.
    • Used let mut guard = self.mesh_sync.write(); *guard = mesh_sync; for mesh sync updates.
    • Used let guard = self.mesh_sync.read(); if let Some(ref mesh_sync) = *guard for mesh sync updates.
  • model_gateway/src/routers/anthropic/mcp.rs
    • Changed allowed_tools_filter to Option<&[String]>.
    • Changed collect_allowed_tools_from_toolsets to take tools as Option<&[Tool]>.
  • model_gateway/src/routers/anthropic/models.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/anthropic/non_streaming.rs
    • Updated string formatting to Rust 2021 syntax.
    • Adjusted tool injection to use allowed_tools.as_deref().
  • model_gateway/src/routers/anthropic/sse.rs
    • Updated iteration patterns for upstream_headers.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/anthropic/streaming.rs
    • Changed execute_mcp_streaming to be synchronous.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
    • Adjusted tool injection to use allowed_tools.as_deref().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/anthropic/utils.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/anthropic/worker.rs
    • Added #[expect(clippy::result_large_err)] to select_worker.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/conversations/handlers.rs
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Simplified conditional logic for warning message.
    • Updated iteration patterns for stored_items and current_items.
  • model_gateway/src/routers/error.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::expect_used)] to ORG_ID_RE and PROJ_ID_RE initializations.
  • model_gateway/src/routers/factory.rs
    • Changed Self::create_grpc_router(ctx).await to Self::create_grpc_router(ctx).
    • Changed Self::create_grpc_pd_router(...).await to Self::create_grpc_pd_router(...).
    • Added #[expect(clippy::unused_async)] to create_anthropic_router for API consistency.
  • model_gateway/src/routers/grpc/client.rs
    • Added #[expect(clippy::panic)] to as_sglang, as_vllm, as_trtllm accessors with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/common/responses/handlers.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/common/responses/streaming.rs
    • Updated iteration patterns for output_items.
    • Changed &req.instructions to req.instructions.as_ref() and similar for other optional fields.
    • Used empty_tools and empty_metadata for unwrap_or.
    • Changed &Option<T> to Option<&T> for add_optional_field.
    • Simplified if let (Some(output_index), Some(item_id)) logic.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unused_self)] to send_event for API consistency.
    • Added #[expect(clippy::expect_used)] to build_sse_response with justification.
  • model_gateway/src/routers/grpc/common/stages/request_execution.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/common/stages/worker_selection.rs
    • Updated string formatting to Rust 2021 syntax.
    • Refined pattern matching for WorkerType.
  • model_gateway/src/routers/grpc/context.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)] for unused fields.
    • Added #[expect(clippy::panic)] to chat_request, generate_request, responses_request accessors with justification.
    • Changed _ => None to specific variants for WorkerSelection and ClientSelection.
  • model_gateway/src/routers/grpc/harmony/builder.rs
    • Added #[expect(clippy::expect_used)] to get_harmony_encoding initialization.
    • Changed convert_harmony_logprobs to return ChatLogProbs directly.
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
    • Updated string formatting to Rust 2021 syntax.
    • Changed convert_chat_messages to return Vec<HarmonyMessage> directly.
    • Added #[expect(clippy::unused_self)] to builder methods for logical grouping.
  • model_gateway/src/routers/grpc/harmony/parser.rs
    • Updated string formatting to Rust 2021 syntax.
    • Simplified recipient_str.strip_prefix("functions.").unwrap() logic.
    • Changed finalize to return HarmonyChannelOutput directly.
    • Added #[expect(clippy::expect_used)] to Default impl for parser creation.
  • model_gateway/src/routers/grpc/harmony/processor.rs
    • Updated string formatting to Rust 2021 syntax.
    • Simplified logprobs conversion to direct mapping.
  • model_gateway/src/routers/grpc/harmony/responses/common.rs
    • Changed build_next_request_with_tools to return ResponsesRequest directly.
    • Updated string formatting to Rust 2021 syntax.
    • Updated iteration patterns for chain.responses and tool_results.
  • model_gateway/src/routers/grpc/harmony/responses/non_streaming.rs
    • Updated string formatting to Rust 2021 syntax.
    • Used clone_from for response_request.tools.
    • Simplified mcp_results assignment.
    • Removed map_err(|e| *e)? from build_next_request_with_tools.
  • model_gateway/src/routers/grpc/harmony/responses/streaming.rs
    • Added #[expect(clippy::disallowed_methods)] to serve_harmony_responses_stream with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Changed unwrap() to unwrap_or_default() for SystemTime conversion.
    • Updated iteration patterns for session.mcp_servers().
    • Simplified if let (Some(output_index), Some(item_id)) logic.
    • Used clone_from for accumulated_tool_calls.
  • model_gateway/src/routers/grpc/harmony/stages/preparation.rs
    • Changed async fn prepare_chat and prepare_responses to synchronous.
    • Added #[expect(clippy::result_large_err)] to prepare_chat and prepare_responses.
    • Updated string formatting to Rust 2021 syntax.
    • Changed generate_tool_call_constraint to take tool_choice by reference.
  • model_gateway/src/routers/grpc/harmony/stages/request_building.rs
    • Updated string formatting to Rust 2021 syntax.
    • Simplified unwrap_or logic for body.
    • Refined RequestType::Embedding and _ pattern matching.
  • model_gateway/src/routers/grpc/harmony/streaming.rs
    • Added #[expect(clippy::unused_self, clippy::disallowed_methods)] for streaming methods with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Simplified logprobs conversion to direct mapping.
    • Changed finalize to return HarmonyChannelOutput directly.
    • Updated tokio::select! patterns to use () for ignored futures.
  • model_gateway/src/routers/grpc/harmony/types.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
  • model_gateway/src/routers/grpc/mod.rs
    • Removed #[allow(dead_code)] from ProcessedMessages struct.
  • model_gateway/src/routers/grpc/pd_router.rs
    • Changed async fn new to fn new.
  • model_gateway/src/routers/grpc/pipeline.rs
    • Replaced #[allow(dead_code)] with #[expect(dead_code)].
  • model_gateway/src/routers/grpc/proto_wrapper.rs
    • Added #[expect(clippy::panic)] to ProtoGenerateRequest and ProtoGenerateStreamChunk accessors with justification.
  • model_gateway/src/routers/grpc/regular/processor.rs
    • Migrated #[allow(clippy::too_many_arguments)] to #[expect(clippy::too_many_arguments)].
    • Updated string formatting to Rust 2021 syntax.
    • Simplified logprobs conversion to direct mapping.
  • model_gateway/src/routers/grpc/regular/responses/common.rs
    • Updated iteration patterns for chain.responses and current_items.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/regular/responses/conversions.rs
    • Changed map_text_to_response_format to take text as Option<&TextConfig>.
    • Refined pattern matching for ResponseContentPart.
  • model_gateway/src/routers/grpc/regular/responses/handlers.rs
    • Changed await for execute_tool_loop_streaming to direct call.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/regular/responses/non_streaming.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/regular/responses/streaming.rs
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Changed unwrap() to unwrap_or_default() for SystemTime conversion.
    • Simplified logprobs conversion to direct mapping.
    • Simplified if !in_reasoning && tool_choice_enabled && tools.is_some() logic.
    • Changed if !tool_call_item.parameters.is_empty() to if tool_call_item.parameters.is_empty().
    • Migrated #[allow(clippy::too_many_arguments)] to #[expect(clippy::too_many_arguments)].
    • Added #[expect(clippy::expect_used)] to reasoning_parsers.entry(index) and tool_parsers.entry(index).
  • model_gateway/src/routers/grpc/regular/stages/chat/preparation.rs
    • Changed async fn prepare_chat to fn prepare_chat.
    • Added #[expect(clippy::unused_self)] and #[expect(clippy::result_large_err)] to prepare_chat.
    • Updated string formatting to Rust 2021 syntax.
    • Changed generate_tool_constraints to take tool_choice by reference.
  • model_gateway/src/routers/grpc/regular/stages/chat/request_building.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added ok_or_else for prep.processed_messages.
  • model_gateway/src/routers/grpc/regular/stages/classify/response_processing.rs
    • Changed iter().cloned() to iter().copied().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/regular/stages/embedding/preparation.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/grpc/regular/stages/embedding/response_processing.rs
    • Added #[expect(clippy::unused_self)] for API consistency.
  • model_gateway/src/routers/grpc/regular/stages/generate/preparation.rs
    • Changed async fn prepare_generate to fn prepare_generate.
    • Added #[expect(clippy::result_large_err)] to prepare_generate.
    • Added #[expect(clippy::unused_self)] to tokenize_single_text.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/header_utils.rs
    • Updated iteration patterns for reqwest_headers and headers.
    • Changed worker_api_key: &Option<String> to worker_api_key: Option<&String>.
    • Simplified user_auth.or_else(...) logic.
  • model_gateway/src/routers/http/pd_router.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unused_async)] to new for API consistency.
    • Adjusted select_pd_pair logic for effective_model_id.
    • Added #[expect(clippy::unused_async)] to select_pd_pair for API consistency.
    • Migrated #[allow(clippy::too_many_arguments)] to #[expect(clippy::too_many_arguments)].
    • Added #[expect(clippy::unused_self)] to create_streaming_response for API consistency.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
    • Updated iteration patterns for headers.
  • model_gateway/src/routers/http/pd_types.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/http/router.rs
    • Added #[expect(clippy::unused_async)] to new for API consistency.
    • Updated string formatting to Rust 2021 syntax.
    • Changed worker.api_key().clone() to worker.api_key().cloned().
    • Simplified if !is_stream and else blocks for response handling.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
  • model_gateway/src/routers/mesh/handlers.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for graceful shutdown.
  • model_gateway/src/routers/openai/context.rs
    • Removed #[allow(dead_code)] from fields.
    • Refined pattern matching for responses_request.
  • model_gateway/src/routers/openai/provider.rs
    • Removed #[allow(dead_code)] from methods.
    • Changed unwrap_or to unwrap_or_else.
  • model_gateway/src/routers/openai/responses/mcp.rs
    • Updated string formatting to Rust 2021 syntax.
    • Updated iteration patterns for mcp_servers.
  • model_gateway/src/routers/openai/responses/non_streaming.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/openai/responses/streaming.rs
    • Updated string formatting to Rust 2021 syntax.
    • Simplified conditional logic for should_skip.
  • model_gateway/src/routers/openai/responses/tool_handler.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::expect_used)] to self.pending_calls.last_mut().
  • model_gateway/src/routers/openai/responses/utils.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed &Option<String> to Option<&String> for insert_optional_string.
  • model_gateway/src/routers/openai/router.rs
    • Added #[expect(clippy::unused_async)] to new for API consistency.
    • Updated string formatting to Rust 2021 syntax.
    • Changed extract_auth_header to take None instead of &None.
    • Changed worker.api_key().clone() to worker.api_key().cloned().
    • Added #[expect(clippy::expect_used)] to payload_ref with justification.
    • Changed extract_auth_header to take (*worker_api_key).as_ref().
    • Simplified if !is_streaming and else blocks for response handling.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
  • model_gateway/src/routers/parse/handlers.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/persistence_utils.rs
    • Used clone_from for stored.safety_identifier and stored.conversation_id.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/router_manager.rs
    • Changed connection_mode: &ConnectionMode to connection_mode: ConnectionMode.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/routers/tokenize/handlers.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/src/server.rs
    • Simplified _log_guard assignment.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for mesh server with justification.
    • Added #[expect(clippy::expect_used)] to app_context.worker_job_queue.set(worker_job_queue) and app_context.workflow_engines.set(engines) with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn for graceful shutdown with justification.
    • Added #[expect(clippy::expect_used)] to shutdown_signal with justification.
    • Updated tokio::select! patterns to use () for ignored futures.
  • model_gateway/src/service_discovery.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn calls with justification.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Used clone_from for spec.api_key.
  • model_gateway/src/version.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::print_stdout)] to print_banner with justification.
  • model_gateway/src/wasm/route.rs
    • Updated iteration patterns for modules.
    • Changed Ok(_) to Ok(()) for pattern matching.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/api/api_endpoints_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/api/parser_endpoints_test.rs
    • Added #[expect(clippy::unwrap_used)] to new_with_config with justification.
    • Changed create_app().await to create_app().
  • model_gateway/tests/api/responses_api_test.rs
    • Added #[expect(clippy::print_stdout)] to tests for diagnostic output.
    • Added #[expect(clippy::expect_used, clippy::unwrap_used)] to setup_streaming_mcp_test with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/api/streaming_tests.rs
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/common/mock_mcp_server.rs
    • Added #[expect(clippy::unused_self, clippy::unnecessary_wraps)] to MockSearchServer methods.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods, clippy::expect_used)] to MockMCPServer::start with justification.
    • Removed #[allow(unused_imports)].
  • model_gateway/tests/common/mock_openai_server.rs
    • Added #![allow(dead_code, clippy::allow_attributes)].
    • Added #[expect(clippy::unwrap_used, clippy::disallowed_methods)] to new_with_auth with justification.
  • model_gateway/tests/common/mock_worker.rs
    • Added #![allow(dead_code, clippy::allow_attributes)].
    • Added #[expect(clippy::disallowed_methods, clippy::print_stderr)] to start with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Changed async fn should_fail to fn should_fail.
    • Added #[expect(clippy::unwrap_used)] to handlers with justification.
  • model_gateway/tests/common/mod.rs
    • Added #![allow(dead_code, clippy::allow_attributes)].
    • Added #[expect(clippy::unwrap_used)] to WorkerTestContext::new with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::unwrap_used, clippy::expect_used)] to create_test_context, create_test_context_with_parsers, create_test_context_with_mcp_config with justification.
    • Added #[expect(clippy::unwrap_used, clippy::expect_used, clippy::print_stdout)] to ensure_tokenizer_cached with justification.
    • Updated assert! messages.
    • Removed #[allow(dead_code)] from create_test_tools.
  • model_gateway/tests/common/streaming_helpers.rs
    • Simplified raw string literals.
    • Removed #[allow(unused_imports)].
  • model_gateway/tests/common/test_app.rs
    • Added #[expect(clippy::unwrap_used)] to create_test_app and create_test_app_with_context with justification.
    • Added #[expect(clippy::unwrap_used, clippy::expect_used)] to create_test_app_context with justification.
  • model_gateway/tests/common/test_certs.rs
    • Added #![allow(dead_code, clippy::allow_attributes)].
    • Added #[expect(clippy::unwrap_used)] to TestCertificates accessors with justification.
  • model_gateway/tests/common/tls_mock_worker.rs
    • Added #![allow(dead_code, clippy::allow_attributes)].
    • Added #[expect(clippy::disallowed_methods, clippy::print_stderr)] to start with justification.
    • Changed build_mtls_config to build_mtls_config_sync.
    • Updated string formatting to Rust 2021 syntax.
    • Changed async fn should_fail to fn should_fail.
    • Added #[expect(clippy::unwrap_used)] to handlers with justification.
  • model_gateway/tests/inflight_tracker_test.rs
    • Added #[expect(clippy::disallowed_methods)] to tests with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/load_guard_raii_test.rs
    • Added #[expect(clippy::disallowed_methods)] to test with justification.
  • model_gateway/tests/mcp_test.rs
    • Added #[expect(clippy::expect_used)] to create_mock_server with justification.
    • Updated string formatting to Rust 2021 syntax.
    • Changed _ => panic!("Expected Success result") to ToolCallResult::PendingApproval(_) => panic!("Expected Success result").
  • model_gateway/tests/metrics_aggregator_test.rs
    • Changed raw string literal for metrics_text.
    • Removed println! for result output.
    • Changed sort() to sort_unstable().
  • model_gateway/tests/otel_tracing_test.rs
    • Added #[expect(clippy::disallowed_methods)] to start_collector with justification.
    • Added #[expect(clippy::print_stdout)] to tests for diagnostic output.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/reliability/circuit_breaker_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/reliability/fault_tolerance_test.rs
    • Changed create_app().await to create_app().
    • Added #[expect(clippy::disallowed_methods)] to test_slow_worker_handling with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/reliability/rate_limiting_test.rs
    • Changed create_app().await to create_app().
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tests with justification.
  • model_gateway/tests/reliability/retries_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/routing/header_forwarding_test.rs
    • Changed create_app().await to create_app().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/routing/load_balancing_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/routing/manual_routing_test.rs
    • Changed create_app().await to create_app().
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::disallowed_methods)] to tests with justification.
  • model_gateway/tests/routing/payload_size_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/routing/pd_routing_test.rs
    • Changed create_app().await to create_app().
    • Added #[expect(clippy::print_stdout)] to tests for diagnostic output.
  • model_gateway/tests/routing/policy_registry_integration.rs
    • Added #[expect(clippy::print_stdout)] to tests for diagnostic output.
  • model_gateway/tests/routing/power_of_two_test.rs
    • Changed create_app().await to create_app().
    • Added #[expect(clippy::disallowed_methods)] to test with justification.
  • model_gateway/tests/routing/service_discovery_test.rs
    • Changed create_app().await to create_app().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/routing/worker_management_test.rs
    • Changed create_app().await to create_app().
  • model_gateway/tests/security/auth_integration_test.rs
    • Added #[expect(clippy::expect_used)] to TestKeyPair::generate and create_test_token with justification.
    • Added #[expect(clippy::unwrap_used)] to create_claims with justification.
    • Added #[expect(clippy::unwrap_used, clippy::disallowed_methods)] to start_mock_jwks_server with justification.
    • Updated assert! messages.
  • model_gateway/tests/security/auth_test.rs
    • Changed create_app().await to create_app().
    • Added #[expect(clippy::disallowed_methods)] to test_concurrent_authenticated_requests with justification.
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/security/mtls_test.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed build_mtls_config to build_mtls_config_sync.
    • Added #[expect(clippy::disallowed_methods)] to test_mtls_concurrent_requests with justification.
  • model_gateway/tests/spec/chat_completion.rs
    • Migrated #[allow(deprecated)] to #[expect(deprecated)].
    • Updated assert! messages.
  • model_gateway/tests/spec/chat_message.rs
    • Refined pattern matching for MessageContent and SystemContent.
  • model_gateway/tests/spec/rerank.rs
    • Used String::new() instead of "".to_string().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/spec/responses.rs
    • Updated assert! messages.
    • Used String::new() instead of "".to_string().
    • Updated string formatting to Rust 2021 syntax.
  • model_gateway/tests/wasm_test.rs
    • Added #[expect(clippy::expect_used)] to create_test_context_with_wasm and create_test_wasm_component with justification.
    • Added #[expect(clippy::expect_used)] to create_test_app_with_wasm with justification.
    • Updated assert! messages.
    • Updated string formatting to Rust 2021 syntax.
  • multimodal/src/registry.rs
    • Changed size: &ImageSize to size: ImageSize.
    • Changed cloned() to copied().
  • multimodal/src/tracker.rs
    • Added #[expect(clippy::disallowed_methods)] to tokio::spawn with justification.
  • multimodal/src/vision/image_processor.rs
    • Added dim_for_ndim helper function.
    • Changed channels, height, width to return Result<usize, TransformError>.
  • multimodal/src/vision/processors/llama4_vision.rs
    • Changed cloned() to copied().
    • Simplified selected_scale logic.
    • Added #[expect(clippy::unused_self)] to pad_image for API consistency.
    • Changed process_single_image to return (Array4<f32>, (usize, usize)) directly.
    • Simplified resize_target logic.
    • Changed process_single_image to return directly.
    • Changed unwrap() to ok_or(TransformError::EmptyBatch)? for max_tiles.
  • multimodal/src/vision/processors/llava.rs
    • Changed process_one_image and process_patch to return Array3<f32> directly.
    • Added #[expect(clippy::unused_self)] to calculate_unpad, resize_and_pad_image, divide_to_samples for API consistency.
  • multimodal/src/vision/processors/phi3_vision.rs
    • Added #[expect(clippy::unused_self)] to padding_336, create_global_image, reshape_to_tiles, calculate_num_tokens for API consistency.
    • Changed process_single_image to return (Array4<f32>, (usize, usize), usize) directly.
    • Changed unwrap() to ok_or(TransformError::EmptyBatch)? for max_tiles.
    • Updated string formatting to Rust 2021 syntax.
  • multimodal/src/vision/processors/phi4_vision.rs
    • Added #[expect(clippy::unused_self)] to compute_target_ratios, pad_image, calculate_num_tokens for API consistency.
    • Changed dynamic_preprocess to return (DynamicImage, Array2<u32>, usize, usize) directly.
    • Changed process_single_image to return SingleImageResult directly.
  • multimodal/src/vision/processors/qwen2_vl.rs
    • Changed reshape_to_patches to return Result<Vec<f32>, TransformError>.
  • multimodal/src/vision/processors/qwen3_vl.rs
    • Changed reshape_to_patches to return Result<Vec<f32>, TransformError>.
  • multimodal/src/vision/processors/qwen_vl_base.rs
    • Updated string formatting to Rust 2021 syntax.
    • Changed reshape_to_patches to return Result<Vec<f32>, TransformError>.
    • Added ok_or_else for broadcast failure.
    • Added map_err for reshape failure.
  • multimodal/src/vision/transforms.rs
    • Updated string formatting to Rust 2021 syntax.
    • Updated iteration patterns for tensor.
  • multimodal/tests/multimodal_tracker_test.rs
    • Added #[expect(clippy::expect_used)] to tiny_png_bytes and test_connector with justification.
    • Updated string formatting to Rust 2021 syntax.
  • multimodal/tests/vision_golden_tests.rs
    • Added #![expect(...)] for various clippy lints and test helpers with justification.
    • Updated string formatting to Rust 2021 syntax.
  • protocols/src/builders/chat/response.rs
    • Used clone_from for self.model.
  • protocols/src/builders/chat/stream_response.rs
    • Used clone_from for self.model.
  • protocols/src/builders/responses/response.rs
    • Used clone_from for self.instructions, self.previous_response_id, self.user.
  • protocols/src/chat.rs
    • Simplified conditional logic for append_text_to.
    • Refined pattern matching for MessageContent.
    • Updated iteration patterns for messages.
    • Simplified if has_tools logic.
    • Updated string formatting to Rust 2021 syntax.
    • Migrated #[allow(deprecated)] to #[expect(deprecated)].
    • Simplified if !tools.is_empty() logic.
  • protocols/src/common.rs
    • Changed tool_choice: &Option<ToolChoice> to tool_choice: Option<&ToolChoice>.
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::enum_variant_names)] to PromptVariableTyped.
  • protocols/src/event_types.rs
    • Changed as_str methods to take self by value.
  • protocols/src/interactions.rs
    • Changed is_option_blank to take Option<&String>.
    • Updated string formatting to Rust 2021 syntax.
  • protocols/src/messages.rs
    • Added #[expect(clippy::enum_variant_names)] to Citation, ContentBlockDelta, ApiError.
  • protocols/src/model_card.rs
    • Added #[expect(clippy::trivially_copy_pass_by_ref)] to is_zero.
    • Updated string formatting to Rust 2021 syntax.
  • protocols/src/model_type.rs
    • Changed methods to take self by value.
    • Updated string formatting to Rust 2021 syntax.
  • protocols/src/realtime_session.rs
    • Added #[expect(clippy::unnecessary_wraps)] to audio.
    • Added #[expect(clippy::enum_variant_names)] to ConnectorId.
  • protocols/src/rerank.rs
    • Added #[expect(clippy::unnecessary_wraps)] to validate_rerank_request.
    • Used String::new() instead of "".to_string().
  • protocols/src/responses.rs
    • Added #[expect(clippy::unnecessary_wraps)] to default functions.
    • Simplified if !tools.is_empty() logic.
    • Updated string formatting to Rust 2021 syntax.
    • Simplified if !raw_label.chars().next().unwrap().is_ascii_alphabetic() logic.
    • Changed _ => {} to ResponseInputOutputItem::FunctionToolCall { .. } => {}.
  • protocols/src/validated.rs
    • Updated string formatting to Rust 2021 syntax.
    • Used String::new() instead of "".to_string().
  • protocols/src/worker.rs
    • Updated string formatting to Rust 2021 syntax.
    • Added #[expect(clippy::upper_case_acronyms)] to ProviderType::XAI.
    • Simplified match models.len() logic.
  • reasoning_parser/Cargo.toml
    • Added parking_lot dependency.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This is an excellent pull request that significantly improves the codebase's quality and robustness by enforcing a much stricter set of clippy lints across the entire workspace. The changes are extensive, touching over 300 files, and demonstrate a deep understanding of Rust best practices.

I'm particularly impressed by the proactive bug fixes that emerged from this linting effort, such as resolving data corruption issues, race conditions, and task leaks. The mechanical fixes, like migrating to parking_lot locks and eliminating unnecessary async blocks, further enhance maintainability and performance.

The use of #[expect] with clear justifications for lint suppressions is a great practice that will help maintain code quality going forward. The entire pull request is well-structured and the detailed description provides valuable context for this large-scale refactoring. This is a fantastic contribution to the project's long-term health.

slin1237 added a commit that referenced this pull request Feb 21, 2026
…error events

Hand-built JSON format strings like `format!("data: {{\"error\": \"{e}\"}}\n\n")`
produce invalid JSON when the error message contains quotes, newlines, or other
special characters. This introduces a shared `send_error_sse()` helper in
`grpc/utils.rs` that uses `serde_json::json!()` for proper escaping and
standardizes the error event shape to `{"error":{"message":"...","type":"..."}}`.

Files changed:
- model_gateway/src/routers/grpc/utils.rs: add SseSender type alias and
  send_error_sse() helper function
- model_gateway/src/routers/grpc/regular/streaming.rs: replace 5 hand-built
  SSE error chunks (chat single/dual, generate single/dual, embedding) with
  send_error_sse()
- model_gateway/src/routers/grpc/harmony/streaming.rs: replace 3 hand-built
  SSE error chunks (single, dual, embedding) with send_error_sse()
- model_gateway/src/routers/grpc/regular/responses/streaming.rs: replace 2
  hand-built SSE error events (stream_error, tool_loop_error) with
  send_error_sse()

Addresses PR #489 review comment about JSON escaping correctness.

Signed-off-by: Simo Lin <simo.lin@oracle.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@model_gateway/src/middleware.rs`:
- Around line 425-428: The clippy expect attribute's reason string for
clippy::disallowed_methods is already correct—leave the attribute as-is on the
spawn/oneshot block (the expect applied to the spawn/JoinHandle/oneshot usage
that performs a fire-and-forget permit acquisition bounded by
remaining_timeout); no code change required other than keeping this precise
reason text to document why the disallowed_methods lint is allowed here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
model_gateway/src/routers/grpc/utils.rs (1)

475-507: ⚠️ Potential issue | 🟡 Minor

Avoid silent fallback on invariant violation.

The pop() fallback returns an empty ProcessedMessages, which silently changes behavior if the invariant is ever violated. Prefer an expect with an invariant message to keep fail-fast behavior.

Suggested fix
-            let Some(last_msg) = transformed_messages.pop() else {
-                return Ok(ProcessedMessages {
-                    text: String::new(),
-                    multimodal_inputs: None,
-                    stop_sequences: request.stop.clone(),
-                });
-            };
+            let last_msg = transformed_messages
+                .pop()
+                .expect("INVARIANT: last message exists after !is_empty() check");

Based on learnings: For lint-only/Clippy enforcement PRs in this repository, avoid introducing behavioral changes (e.g., new input validation or logic changes). Treat such PRs as non-functional changes and plan a separate follow-up issue/PR for hardening or behavior changes; and in Rust code across the repository, use the marker INVARIANT: to document assumptions in safe code. Reserve SAFETY: for explaining why unsafe blocks are sound.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/utils.rs` around lines 475 - 507, The code
currently silently returns an empty ProcessedMessages if
transformed_messages.pop() unexpectedly fails; change this to fail fast by
replacing the fallible pop handling with a panic via expect (e.g., call
transformed_messages.pop().expect(...)) and add an INVARIANT: comment
documenting the assumption that transformed_messages is non-empty when
request.continue_final_message is true and last role == "assistant" (refer to
the assistant_prefix block and the transformed_messages.pop() usage); do not
alter surrounding control flow or return values—only replace the silent fallback
with expect and annotate the invariant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@model_gateway/src/routers/grpc/harmony/streaming.rs`:
- Around line 110-117: The Embedding arm (context::ExecutionResult::Embedding)
sends an error via utils::send_error_sse(&tx, ...) but does not send the final
"[DONE]" terminator like the Single and Dual arms; update this branch to call
the same done-terminator used elsewhere (e.g., utils::send_done_sse(&tx) or the
existing helper used in the Single/Dual paths) immediately after
utils::send_error_sse so SSE clients receive the final "[DONE]" event and don't
hang.

In `@model_gateway/src/routers/grpc/regular/responses/streaming.rs`:
- Around line 517-520: The computed created_at value in streaming.rs (the let
created_at =
SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();)
silently falls back to 0 if the system clock is before 1970; add a brief inline
comment next to this created_at calculation clarifying that unwrap_or_default()
intentionally yields 0 as a cosmetic metadata fallback (safe for SSE event
metadata) so future readers/debuggers understand the behavior and that this is
not the CRDT timestamp bug.

---

Outside diff comments:
In `@model_gateway/src/routers/grpc/utils.rs`:
- Around line 475-507: The code currently silently returns an empty
ProcessedMessages if transformed_messages.pop() unexpectedly fails; change this
to fail fast by replacing the fallible pop handling with a panic via expect
(e.g., call transformed_messages.pop().expect(...)) and add an INVARIANT:
comment documenting the assumption that transformed_messages is non-empty when
request.continue_final_message is true and last role == "assistant" (refer to
the assistant_prefix block and the transformed_messages.pop() usage); do not
alter surrounding control flow or return values—only replace the silent fallback
with expect and annotate the invariant.

---

Duplicate comments:
In `@model_gateway/src/routers/grpc/regular/streaming.rs`:
- Around line 349-394: The code unconditionally continues when tool parsing is
active, causing normal_text to be dropped if parsing fails; change the control
flow around process_specific_function_stream/process_tool_calls_stream so you
only skip the normal content when the parser actually succeeded/emitted chunks
or explicitly buffered the normal_text (i.e., inspect the result/ok-value of
Self::process_specific_function_stream and self.process_tool_calls_stream and
only execute the continue when those return a successful indication of handled
tool output), otherwise let execution fall through to the existing normal-text
handling path and ensure parse errors are propagated or logged alongside
emitting any partial normal_text; reference functions
process_specific_function_stream, process_tool_calls_stream, variables
tool_chunks, sse_buffer, tx, and delta to locate and adjust the logic.

Comment on lines 110 to 117
context::ExecutionResult::Embedding { .. } => {
error!("Harmony streaming not supported for embeddings");
let error_chunk = format!(
"data: {}\n\n",
json!({
"error": {
"message": "Embeddings not supported in Harmony streaming",
"type": "invalid_request_error"
}
})
utils::send_error_sse(
&tx,
"Embeddings not supported in Harmony streaming",
"invalid_request_error",
);
let _ = tx.send(Ok(Bytes::from(error_chunk)));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Pre-existing: Missing [DONE] terminator for embedding error path.

The Single and Dual paths (lines 93, 107) send [DONE] after errors, but the Embedding path only sends the error SSE without a [DONE] terminator. This could leave SSE clients hanging.

Since this is a lint-only PR, consider addressing in a follow-up:

 context::ExecutionResult::Embedding { .. } => {
     error!("Harmony streaming not supported for embeddings");
     utils::send_error_sse(
         &tx,
         "Embeddings not supported in Harmony streaming",
         "invalid_request_error",
     );
+    let _ = tx.send(Ok(Bytes::from("data: [DONE]\n\n")));
 }

Based on learnings: For lint-only/Clippy enforcement PRs, avoid introducing behavioral changes; prefer a separate follow-up issue/PR for such hardening.

Do you want me to open a follow-up issue to track this?

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
context::ExecutionResult::Embedding { .. } => {
error!("Harmony streaming not supported for embeddings");
let error_chunk = format!(
"data: {}\n\n",
json!({
"error": {
"message": "Embeddings not supported in Harmony streaming",
"type": "invalid_request_error"
}
})
utils::send_error_sse(
&tx,
"Embeddings not supported in Harmony streaming",
"invalid_request_error",
);
let _ = tx.send(Ok(Bytes::from(error_chunk)));
}
context::ExecutionResult::Embedding { .. } => {
error!("Harmony streaming not supported for embeddings");
utils::send_error_sse(
&tx,
"Embeddings not supported in Harmony streaming",
"invalid_request_error",
);
let _ = tx.send(Ok(Bytes::from("data: [DONE]\n\n")));
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/harmony/streaming.rs` around lines 110 - 117,
The Embedding arm (context::ExecutionResult::Embedding) sends an error via
utils::send_error_sse(&tx, ...) but does not send the final "[DONE]" terminator
like the Single and Dual arms; update this branch to call the same
done-terminator used elsewhere (e.g., utils::send_done_sse(&tx) or the existing
helper used in the Single/Dual paths) immediately after utils::send_error_sse so
SSE clients receive the final "[DONE]" event and don't hang.

Comment on lines 517 to 520
let created_at = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.unwrap_or_default()
.as_secs();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Minor: Consider documenting the fallback behavior.

duration_since(UNIX_EPOCH) fails if the system clock is set before 1970. Using unwrap_or_default() silently falls back to 0, which is acceptable for SSE event metadata but could be confusing during debugging.

This is different from the CRDT timestamp fix mentioned in the PR objectives—there, timestamp=0 causes data corruption, whereas here it's just cosmetic metadata. No change needed, but a brief inline comment could clarify intent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@model_gateway/src/routers/grpc/regular/responses/streaming.rs` around lines
517 - 520, The computed created_at value in streaming.rs (the let created_at =
SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();)
silently falls back to 0 if the system clock is before 1970; add a brief inline
comment next to this created_at calculation clarifying that unwrap_or_default()
intentionally yields 0 as a cosmetic metadata fallback (safe for SSE event
metadata) so future readers/debuggers understand the behavior and that this is
not the CRDT timestamp bug.

…error events

Hand-built JSON format strings like `format!("data: {{\"error\": \"{e}\"}}\n\n")`
produce invalid JSON when the error message contains quotes, newlines, or other
special characters. This introduces a shared `send_error_sse()` helper in
`grpc/utils.rs` that uses `serde_json::json!()` for proper escaping and
standardizes the error event shape to `{"error":{"message":"...","type":"..."}}`.

Files changed:
- model_gateway/src/routers/grpc/utils.rs: add SseSender type alias and
  send_error_sse() helper function
- model_gateway/src/routers/grpc/regular/streaming.rs: replace 5 hand-built
  SSE error chunks (chat single/dual, generate single/dual, embedding) with
  send_error_sse()
- model_gateway/src/routers/grpc/harmony/streaming.rs: replace 3 hand-built
  SSE error chunks (single, dual, embedding) with send_error_sse()
- model_gateway/src/routers/grpc/regular/responses/streaming.rs: replace 2
  hand-built SSE error events (stream_error, tool_loop_error) with
  send_error_sse()

Addresses PR #489 review comment about JSON escaping correctness.

Signed-off-by: Simo Lin <simo.lin@oracle.com>
@slin1237
slin1237 merged commit 9e686a7 into main Feb 21, 2026
17 of 19 checks passed
@slin1237
slin1237 deleted the slin/oai-3 branch February 21, 2026 07:54
slin1237 added a commit that referenced this pull request Feb 22, 2026
Fixes deferred from the clippy enforcement PR that required behavioral
changes:

SSE streaming:
- harmony/streaming.rs, regular/streaming.rs: add missing [DONE]
  terminator to embedding error paths. Single/Dual paths already sent
  [DONE] after errors, but the Embedding path did not, which could leave
  SSE clients hanging waiting for the stream to end.

Bucket policy:
- policies/bucket.rs (add_prefill_url): add early-return guard when the
  worker URL already exists. Previously, duplicate adds would call
  init_prefill_worker_urls which resets load counters (chars_per_url)
  and recomputes boundaries, wiping balancing history.
- policies/bucket.rs (remove_prefill_url): always call
  init_prefill_worker_urls after removal, even when the last URL is
  removed. Previously the cleanup was skipped when updated_len == 0,
  leaving stale boundary and chars_per_url state.

Token bucket:
- core/token_bucket.rs: add debug_assert! on try_acquire_sync and
  return_tokens_sync to catch non-finite or negative token amounts
  during development. Zero-cost in release builds.

Worker properties:
- update_worker_properties.rs: add warn! log when a DP-aware worker is
  missing dp_rank or dp_size metadata. Previously this inconsistent
  state was silently ignored, making misconfigurations hard to diagnose.

Refs: PR #489 review comments
Signed-off-by: Simo Lin <simo.lin@oracle.com>
slin1237 added a commit that referenced this pull request Feb 22, 2026
Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

anthropic Anthropic router changes auth Authentication crate changes benchmarks Benchmark changes data-connector Data connector crate changes dependencies Dependency updates grpc gRPC client and router changes mcp MCP related changes model-gateway Model gateway crate changes multimodal Multimodal crate changes openai OpenAI router changes protocols Protocols crate changes python-bindings Python bindings changes realtime-api Realtime API related changes reasoning-parser Reasoning parser changes tests Test changes tokenizer Tokenizer related changes tool-parser Tool/function call parser changes wasm WebAssembly related changes workflow Workflow crate changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant