Skip to content

fix(pd): route chat using full message history - #1929

Merged
slin1237 merged 1 commit into
lightseekorg:mainfrom
Moersity:fix/http-pd-chat-routing
Jul 16, 2026
Merged

fix(pd): route chat using full message history#1929
slin1237 merged 1 commit into
lightseekorg:mainfrom
Moersity:fix/http-pd-chat-routing

Conversation

@Moersity

@Moersity Moersity commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Closes #1928

Problem

The HTTP PD router only inspected the first chat message when building routing text. For multi-turn conversations, later messages did not participate in cache-aware or prefix-based worker selection. Multipart text in the first message could also produce no routing text.

Solution

Use ChatCompletionRequest::extract_text_for_routing(), matching the regular HTTP router and including text from the complete message history.

Changes

  • Replace first-message-only extraction in the HTTP PD chat route.
  • Remove the now-unused ChatMessage and MessageContent imports.

Test Plan

  1. Send two multi-turn chat requests with the same first message but different later messages through HTTP PD routing.
  2. Confirm the routing text differs and includes the complete message history.
  3. Send a request containing multipart text and confirm its text participates in routing.
  4. Run cargo test -p smg --lib routers::http::pd_router::tests (8 passed, 0 failed).
  5. Run cargo +nightly fmt --all -- --check (passed).

cargo clippy --workspace --all-targets -- -D warnings is currently blocked on macOS by two pre-existing unused imports in model_gateway/src/routers/grpc/multimodal/assemble.rs. The all-features variant additionally requires local OpenCV/pkg-config.

Checklist
  • cargo +nightly fmt passes
  • cargo clippy --all-targets --all-features -- -D warnings passes (blocked by the environment/pre-existing warnings described above)
  • (Optional) Documentation updated (not required; no user-facing API change)
  • (Optional) Please join us on Slack #sig-smg to discuss, review, and merge PRs

Summary by CodeRabbit

  • Refactor
    • Streamlined chat request text extraction for HTTP routing.
    • No user-visible behavior changes.

Signed-off-by: lixiang5 <lixiang5@sensetime.com>
@github-actions github-actions Bot added the model-gateway Model gateway crate changes label Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The HTTP chat router now obtains routing text through body.extract_text_for_routing() instead of manually scanning messages, with corresponding protocol import updates.

Changes

Chat routing

Layer / File(s) Summary
Use shared routing text extraction
model_gateway/src/routers/http/pd_router.rs
Updates protocol imports and replaces manual message text extraction in route_chat with body.extract_text_for_routing().

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: key4ng, slin1237

Poem

I’m a rabbit routing text with care,
No message-scanning maze to wear.
One shared extractor, swift and bright,
Sends chat requests along just right.
Hop, hop—imports are tidy tonight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: routing chat using the full message history.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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 pull request simplifies the routing text extraction logic in pd_router.rs by replacing manual pattern matching on ChatMessage with a call to body.extract_text_for_routing(). Feedback was provided to prevent potential load imbalance issues by ensuring that empty strings returned by extract_text_for_routing() are mapped to None instead of being wrapped in Some("").

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 1444 to 1448
let request_text = if self.policies_need_request_text() {
body.messages.first().and_then(|msg| match msg {
ChatMessage::User { content, .. } => match content {
MessageContent::Text(text) => Some(text.clone()),
MessageContent::Parts(_) => None,
},
ChatMessage::Developer { content, .. } => match content {
MessageContent::Text(text) => Some(text.clone()),
MessageContent::Parts(_) => None,
},
ChatMessage::System { content, .. } => Some(content.to_simple_string()),
_ => None,
})
Some(body.extract_text_for_routing())
} else {
None
};

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.

medium

If extract_text_for_routing() returns an empty string, wrapping it in Some results in Some(""). Passing an empty string to routing policies (like cache-aware or consistent hashing) can cause all requests with empty routing text to hash to the same worker, leading to load imbalance. It is better to map an empty string to None so that policies can correctly fall back to load-balancing or round-robin routing.

Suggested change
let request_text = if self.policies_need_request_text() {
body.messages.first().and_then(|msg| match msg {
ChatMessage::User { content, .. } => match content {
MessageContent::Text(text) => Some(text.clone()),
MessageContent::Parts(_) => None,
},
ChatMessage::Developer { content, .. } => match content {
MessageContent::Text(text) => Some(text.clone()),
MessageContent::Parts(_) => None,
},
ChatMessage::System { content, .. } => Some(content.to_simple_string()),
_ => None,
})
Some(body.extract_text_for_routing())
} else {
None
};
let request_text = if self.policies_need_request_text() {
let text = body.extract_text_for_routing();
(!text.is_empty()).then_some(text)
} else {
None
};

@slin1237
slin1237 merged commit 60e87b0 into lightseekorg:main Jul 16, 2026
49 of 52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

model-gateway Model gateway crate changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: http pd router only use the first message

2 participants