Repository navigation
refactor(native): separate request data from execution context - #39941
yujonglee-berri wants to merge 6 commits into
Conversation
LiteLLM Rust workflowWorkflow completed successfully for |
0f886a6 to
c5cc1bd
Compare
c5cc1bd to
a8966bc
Compare
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
a8966bc to
e9d4c7e
Compare
e9d4c7e to
1c9679b
Compare
cd9ac16 to
8278ae7
Compare
8278ae7 to
2d27354
Compare
2d27354 to
290616d
Compare
81832ee to
629e796
Compare
Greptile SummaryThis PR separates endpoint payloads, execution options, request identity, attribution, and capability facts across the Python-to-Rust native boundary.
Confidence Score: 4/5The PR is not safe to merge until the server-enabled Rust gateway messages route is updated to the new three-argument API and compiles. One build-blocking API migration error remains: the gateway constructs a nonexistent Files Needing Attention: litellm-rust/crates/ai-gateway/src/routes/messages/service.rs, litellm-rust/README.md
|
| Filename | Overview |
|---|---|
| litellm-rust/crates/ai-gateway/src/routes/messages/service.rs | Migrates the gateway messages call incorrectly; the server feature cannot compile because options are embedded in MessagesRequest and omitted from entrypoint arguments. |
| litellm-rust/crates/core/src/messages/mod.rs | Changes messages entrypoints to receive request options and execution context as separate arguments. |
| litellm-rust/crates/core/src/request_context.rs | Adds typed call identity, attribution, and execution-capability context. |
| litellm-rust/crates/core/src/request_options.rs | Adds shared execution options with typed Bedrock, Anthropic, and Vertex configuration. |
| litellm-rust/crates/python-bridge/src/marshal.rs | Marshals the new Python request options and context records into Rust types. |
| litellm/rust_bridge/request.py | Defines immutable Python request, options, context, and provider-option records used by native calls. |
| litellm-rust/README.md | Documents the new native boundary but shows the same invalid MessagesRequest.options shape as the broken gateway call site. |
Reviews (1): Last reviewed commit: "feat(native): preserve request identity ..." | Re-trigger Greptile
| let request = MessagesRequest { | ||
| model: provider_model, | ||
| body, | ||
| api_key: deployment.litellm_params.api_key.as_deref(), | ||
| api_base: deployment.litellm_params.api_base.as_deref(), | ||
| custom_llm_provider, | ||
| extra_headers, | ||
| timeout: None, | ||
| options: RequestOptions { | ||
| api_key: (deployment.litellm_params.api_key.as_deref()).map(|value| value.to_string()), | ||
| api_base: (deployment.litellm_params.api_base.as_deref()) | ||
| .map(|value| value.to_string()), | ||
| custom_llm_provider: (custom_llm_provider).map(|value| value.to_string()), | ||
| extra_headers, | ||
| timeout: None, | ||
| ..Default::default() | ||
| }, | ||
| }; | ||
| if request.body.get("stream").and_then(Value::as_bool) == Some(true) { | ||
| return messages_stream(request).await.map(MessagesResponse::Stream); | ||
| return messages_stream( | ||
| request, | ||
| &LiteLlmRequestContext { | ||
| ..Default::default() | ||
| }, | ||
| ) | ||
| .await | ||
| .map(MessagesResponse::Stream); | ||
| } | ||
|
|
||
| let response = messages(request).await?; | ||
| let response = messages( | ||
| request, | ||
| &LiteLlmRequestContext { | ||
| ..Default::default() | ||
| }, | ||
| ) | ||
| .await?; |
There was a problem hiding this comment.
Messages route fails compilation
The server-enabled gateway constructs MessagesRequest with an options field, but that type only contains model and body. The messages and messages_stream functions also require RequestOptions as a separate argument. As a result, building litellm-ai-gateway with the server feature fails with E0560 and E0061. The README example uses the same invalid request shape and should be corrected as well.
| let request = MessagesRequest { | |
| model: provider_model, | |
| body, | |
| api_key: deployment.litellm_params.api_key.as_deref(), | |
| api_base: deployment.litellm_params.api_base.as_deref(), | |
| custom_llm_provider, | |
| extra_headers, | |
| timeout: None, | |
| options: RequestOptions { | |
| api_key: (deployment.litellm_params.api_key.as_deref()).map(|value| value.to_string()), | |
| api_base: (deployment.litellm_params.api_base.as_deref()) | |
| .map(|value| value.to_string()), | |
| custom_llm_provider: (custom_llm_provider).map(|value| value.to_string()), | |
| extra_headers, | |
| timeout: None, | |
| ..Default::default() | |
| }, | |
| }; | |
| if request.body.get("stream").and_then(Value::as_bool) == Some(true) { | |
| return messages_stream(request).await.map(MessagesResponse::Stream); | |
| return messages_stream( | |
| request, | |
| &LiteLlmRequestContext { | |
| ..Default::default() | |
| }, | |
| ) | |
| .await | |
| .map(MessagesResponse::Stream); | |
| } | |
| let response = messages(request).await?; | |
| let response = messages( | |
| request, | |
| &LiteLlmRequestContext { | |
| ..Default::default() | |
| }, | |
| ) | |
| .await?; | |
| let options = RequestOptions { | |
| api_key: (deployment.litellm_params.api_key.as_deref()).map(|value| value.to_string()), | |
| api_base: (deployment.litellm_params.api_base.as_deref()).map(|value| value.to_string()), | |
| custom_llm_provider: (custom_llm_provider).map(|value| value.to_string()), | |
| extra_headers, | |
| timeout: None, | |
| ..Default::default() | |
| }; | |
| let request = MessagesRequest { | |
| model: provider_model, | |
| body, | |
| }; | |
| if request.body.get("stream").and_then(Value::as_bool) == Some(true) { | |
| return messages_stream( | |
| request, | |
| &options, | |
| &LiteLlmRequestContext { | |
| ..Default::default() | |
| }, | |
| ) | |
| .await | |
| .map(MessagesResponse::Stream); | |
| } | |
| let response = messages( | |
| request, | |
| &options, | |
| &LiteLlmRequestContext { | |
| ..Default::default() | |
| }, | |
| ) | |
| .await?; |
c46fd72 to
905c5cb
Compare
905c5cb to
12c02dd
Compare
|
Closing; stack is being cleaned up. |
TLDR
Problem this solves:
How it solves it:
User Flow
Before: the SDK request can violate this layer contract.
After: the same request follows one predictable contract.
Relevant issues
Linear ticket
Pre-Submission checklist
Stack
39928 -> 39913 -> 39923 -> 39941 -> 39939 -> 39484 -> 39986 -> 40054 -> 40055 -> 40056 -> 39765Layer 4 of 11.
Screenshots / Proof of Fix
After (
c46fd72df65801f31265abc978dab5fc6142c33f)UV_PYTHON=3.12 make check: passedNo paid-provider calls were used for deterministic validation.
Type
Refactoring
Caveats (if any)
Medium
Final Attestation