Normalize completion responses at the provider boundary - #2254
Draft
gold-silver-copper wants to merge 6 commits into
Draft
Normalize completion responses at the provider boundary#2254gold-silver-copper wants to merge 6 commits into
gold-silver-copper wants to merge 6 commits into
Conversation
Phase P1 of the data-oriented rearchitecture (audit/data-oriented-rearchitecture.md §14, Revision 2.1). The provider-typed response generics are gone from the payload layer: - CompletionResponse<T> -> concrete CompletionResponse with normalized metadata: finish_reason (new FinishReason enum — closes #2090, #1886), provider, model, message_id. raw_response is removed; provider-typed wire data stays reachable through each provider's own conversion layer. - The provider-typed streaming final becomes the normalized StreamFinal (kind discriminant for the untagged enum, usage as a field, finish reason, message_id, provider, model). The GetTokenUsage trait is deleted; wire usage types convert via From/Into<Usage>. - RawStreamingChoice, StreamingResult, StreamingCompletionResponse, StreamedAssistantContent, MultiTurnStreamItem, DriveStream/DriveItem and the StreamedTurnAssembler lose their type parameters; the entire rig-agent run module is now generic-free. - CompletionModel loses type Response / type StreamingResponse (the trait itself survives until P7); TurnSource loses type Raw entirely; StreamingPrompt/StreamingChat lose their response parameter. - Every finish/stop vocabulary is mapped per provider (25 in-core + the four companion crates); the OpenAI-compatible shared path stamps Ext::PROVIDER_NAME post-conversion. - Provider-specific streaming-final aliases (deepseek, groq, mistral, openrouter, gemini, copilot, candle placeholder) are removed. Verification: cargo check --workspace --all-targets clean; clippy clean; rig-core 1008 tests, rig-agent 500 tests, facade cassette suites 1214 tests all passing with cassette YAMLs byte-identical (no request-building code changed). Full narrative in audit/migration-log.md.
This was referenced Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR normalizes completion responses at the provider boundary:
CompletionModelnow returns concreteCompletionResponseandStreamingCompletionResponsevalues.CompletionClient; the model trait no longer owns response/client associated types ormake.raw_completionandraw_streamescape hatches.Breaking API changes are intentional; backwards compatibility is not a constraint for this prerequisite.
Relationship to other work
This is a prerequisite for #2252. It does not modify that PR or introduce runtime model-selection architecture. The response-shape normalization is independently useful and keeps the later hook-driven selection work focused on run-time steering.
Core API shape
ProviderCapabilitiesis public.RawStreamingChoice<R>,RawStreamingResult<R>, andnormalize_streamprovide the reusable typed raw-stream boundary.Provider-extension associated types such as
OpenAICompatibleProvider::{Response, StreamingUsage}intentionally remain at the native provider boundary; completion models and agents no longer propagate response associated types.Native-response escape hatches
Direct typed raw APIs are implemented for:
OpenAI-compatible extension types cover Azure, DeepSeek, Doubleword, Groq, Hugging Face, Hyperbolic, Llamafile, MiniMax, Mira, Mistral, Moonshot, OpenRouter, Perplexity, Together, Xiaomi MiMo, and Z.AI. Anthropic-compatible provider extensions retain their native response types as well.
Finish-reason normalization
stop;length;tool_callsorfunction_call;content_filterStop;Length;ToolCalls;ContentFilterStop(orToolCallswhen calls are present);Length;ContentFilterend_turn/stop_sequence;max_tokens;tool_useStop;Length;ToolCallsCOMPLETE/STOP_SEQUENCE;MAX_TOKENS;TOOL_CALLStop;Length;ToolCallsSTOP;MAX_TOKENS; safety/block reasonsStoporToolCallswhen calls are present;Length;ContentFilterCOMPLETED;REQUIRES_ACTION;BUDGET_EXCEEDEDStop;ToolCalls;LengthStoporToolCallswhen calls are present;LengthStop;Length;ToolCalls;ContentFilterStoporToolCallswhen parsed calls are present;LengthUnknown native reasons are preserved as
FinishReason::Otherrather than discarded.Correctness details
resp_*IDs with assistantmsg_*IDs.ToolCallsconsistently across unary and streaming paths.Verification
Passed locally:
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo testcargo test -p rig-core --lib --all-features— 1,041 passed, 3 ignoredcargo test -p rig-agent --lib --all-features— 487 passed, 2 ignoredRUSTDOCFLAGS='-D warnings' cargo doc -p rig-core -p rig-agent -p rig --no-depscargo check --target wasm32-unknown-unknown -p rig-core -p rig-agent -p rigNo cassette fixture files changed.
An independent reviewer inspected the complete 107-file diff against merge base
6cfae6d829da21f9dc9e775e065fee157b264f7e, reviewed all follow-up fixes, and reported no remaining P0–P3, security, unsafe-code, or regression findings.