Repository navigation
refactor(grpc): deduplicate Harmony Chat Completion streaming decode logic - #594
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Summary of ChangesHello, 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 refactors the gRPC Chat Completion streaming logic by addressing and eliminating substantial code duplication. The core decode loop, including metrics and usage emission, has been extracted into a new, shared helper function. This change enhances the maintainability and clarity of the streaming implementation across both single and dual stream processing paths, making the codebase more robust and easier to understand. Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughIntroduces Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant HarmonyProcessor
participant PrefillStream
participant DecodeStream
participant Parser as HarmonyParserAdapter
participant TX as mpsc::UnboundedSender
Client->>HarmonyProcessor: start single or dual streaming
alt dual flow
HarmonyProcessor->>PrefillStream: consume prefill until ready
end
HarmonyProcessor->>DecodeStream: read decode chunks
DecodeStream-->>HarmonyProcessor: chunk bytes
HarmonyProcessor->>Parser: parse chunk -> deltas / final / usage
Parser-->>HarmonyProcessor: delta events, final event, usage
HarmonyProcessor->>TX: emit delta bytes
HarmonyProcessor->>DecodeStream: mark_completed (when decode done)
alt dual flow post-decode
HarmonyProcessor->>PrefillStream: mark_completed
end
HarmonyProcessor->>TX: emit final bytes and usage
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
This comment was marked as resolved.
This comment was marked as resolved.
f575849 to
a93b339
Compare
There was a problem hiding this comment.
Code Review
This pull request refactors the chat completion streaming logic, successfully deduplicating code by introducing the process_chat_decode_stream helper function. No security vulnerabilities were found. The solution is clean and elegant, with a suggestion to improve the maintainability of the new helper function by encapsulating its state into a dedicated struct.
…ess_chat_decode_stream The decode loop, chunk parsing, delta emission, completion handling, finalization, usage emission, and metrics recording were nearly identical (~160 lines duplicated) between process_single_stream and process_dual_stream. Extract the shared decode logic into process_chat_decode_stream(). The only meaningful difference — prompt_tokens/cached_tokens population — is handled via entry().or_insert_with(): single-stream passes empty maps (always inserts), dual-stream passes pre-populated maps from prefill (no-op on Complete). Signed-off-by: Chang Su <chang.s.su@oracle.com>
a93b339 to
770ff9f
Compare
There was a problem hiding this comment.
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/harmony/streaming.rs (1)
205-206: 🧹 Nitpick | 🔵 TrivialRemove unused
finish_reasonsmap from the shared decode helper.
finish_reasonsis populated (Line 275) but never read, so it adds dead state in a hot streaming path.♻️ Suggested cleanup
- let mut finish_reasons: HashMap<u32, Option<String>> = HashMap::new(); @@ - finish_reasons - .insert(index, Some(complete_wrapper.finish_reason().to_string()));Also applies to: 275-277
🤖 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 205 - 206, The variable finish_reasons in the shared decode helper is unused and introduces dead state; remove its declaration (the HashMap<u32, Option<String>>) and any code that inserts into or references finish_reasons (the population logic around where finish_reasons is set) so the streaming path only keeps matched_stops (HashMap<u32, Option<serde_json::Value>>) and related logic; update any function signatures or variables that referenced finish_reasons to stop expecting it and run tests/build to ensure no remaining references.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@model_gateway/src/routers/grpc/harmony/streaming.rs`:
- Around line 205-206: The variable finish_reasons in the shared decode helper
is unused and introduces dead state; remove its declaration (the HashMap<u32,
Option<String>>) and any code that inserts into or references finish_reasons
(the population logic around where finish_reasons is set) so the streaming path
only keeps matched_stops (HashMap<u32, Option<serde_json::Value>>) and related
logic; update any function signatures or variables that referenced
finish_reasons to stop expecting it and run tests/build to ensure no remaining
references.
finish_reasons was populated but never read back; the finish reason is consumed directly from complete_wrapper.finish_reason() instead. Signed-off-by: Chang Su <chang.s.su@oracle.com>
Description
Problem
PR #592 review (Gemini, high priority) flagged significant code duplication between
process_single_streamandprocess_dual_streaminstreaming.rs. The decode loop, chunk parsing, delta emission, completion handling, finalization, usage emission, and metrics recording were nearly identical (~160 lines duplicated). The only differences:dual_streamhas a prefill phase that pre-populatesprompt_tokensandcached_tokenssingle_streampopulatesprompt_tokens/cached_tokensfrom Complete messages;dual_streamdoesn'tdual_streammarks two streams complete (decode first, then prefill);single_streammarks oneSolution
Extract the shared decode logic into
process_chat_decode_stream(). Callers only set upprompt_tokens/cached_tokensand handle prefill-specific cleanup.The
prompt_tokens/cached_tokensdifference is handled viaentry().or_insert_with():.insert())or_insert_withis a no-op (closure never called)Changes
process_chat_decode_stream()— shared helper containing the full decode loop, metrics, and usage emissionprocess_single_stream()— now just creates empty maps and delegates to the helperprocess_dual_stream()— keeps prefill phase, delegates decode to the helper, marks prefill stream completed afterPerformance note: The dual-stream path now does an
entry().or_insert_with()lookup in the Complete arm where the original code didn't touch those maps at all. This is oneu32hash + comparison per Complete message per map — sub-nanosecond and completely negligible compared to any network I/O in the stream. The closure is lazy socomplete_wrapper.prompt_tokens()/cached_tokens()are never called when the key already exists.Test Plan
cargo build -p smg— passescargo clippy -p smg -- -D warnings— passes (zero warnings)cargo test -p smg— all tests passpre-commit run --all-files— all hooks passNote: PR #592 will need to rebase on this after merge.
Checklist
cargo +nightly fmtpassescargo clippy --all-targets --all-features -- -D warningspassesSummary by CodeRabbit