Repository navigation
feat(decisions): backport the decisions and Jev follow-ups to stable/1.104.x and bump to 1.104.3 - #45906
Conversation
…ne translation (#45129) * feat(decisions): add the OpenAI Decisions spec types and the System One translation Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): share one DecisionsModel config and require model and usage on responses Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): rename the shared pydantic parent to DecisionsObjectBase Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(decisions): match the SDK on strict choice values and drop the invented min_length bounds Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): compose DecisionsRequest from model and body and read the translator top down Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): use the plural Decisions prefix only for the request and response envelopes Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(decisions): import assert_never from typing_extensions for Python 3.10 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 79f62db)
…and the shared HTTP handler (#45130) * refactor(decisions): dispatch /v1/decisions through provider configs and the shared HTTP handler Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(decisions): map OpenRouter connection failures to APIConnectionError and drop explanatory docstrings Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(decisions): keep APIConnectionError for unreachable deployments on every provider `_map_upstream_exception` now maps a status `_handle_error` synthesized for a non-HTTP failure to `APIConnectionError` before `exception_type` runs, so a Perplexity (openai-compatible) deployment that cannot be reached no longer answers `InternalServerError` where main answers `APIConnectionError`. Audit cells: the unreachable-deployment integration cell is parametrized over the five providers, OpenRouter connection failures are pinned on chat, stream, embeddings, decisions and the SDK, a deployment whose provider has no decisions config gets the 400 naming every supported provider, and a unit cell pins the mapper alone. The first docstring sentence of the five translation bases is dropped. --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit 0e09e99) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…list (#45335) * feat(ui): add TypeSafe and Strands Decider to the Add Model provider list * test(public_endpoints): type the provider fields helper against the route's model --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit 3a3b8ca)
…pes left dead by #45214 (#45442) #45214 routed both decision formats through the shared decisions IR in litellm/llms/base_llm/decisions/transformation.py and litellm/types/decisions.py. That left litellm/llms/base_llm/decisions/systemone.py (to_system_one_request, question_keys, to_decisions_response, the SystemOne* models and their adapter) and litellm/types/openai_decisions.py with no importer outside their own unit tests, so both modules and both test files go. Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit 0e48048)
* feat(decisions): add hosted_vllm provider Adds HostedVLLMDecisionsConfig so hosted_vllm/<served model> works on POST /v1/systemone and POST /v1/decisions against a vLLM server that serves the System One body (vllm-project/vllm#59299, after v0.31.0). vLLM only supports choice questions and rejects others, so the base decisions config gains a per-provider health_check_questions attribute and the evaluation-mode health probe sends a choice question for hosted_vllm while every other provider keeps the noul probe. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): move the hosted_vllm placeholder key to constants Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 61e5f2d)
Price-Sync: litellm-providers Co-authored-by: berriai-litellm-provider-info-sync[bot] <328147090+berriai-litellm-provider-info-sync[bot]@users.noreply.github.com> (cherry picked from commit de6a071)
…e.cost and always allow reasoning params (#45640) [partial: decisions and pass-through billing only] Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 465f20f) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…5673) * feat(azure_ai): support Microsoft-Decision-1 on the decisions API Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(azure_ai): strip project path and API suffix together in decisions base Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 2fcc780)
…ke it unless drop_params drops it (#44955) * feat(decisions): add the OpenAI Decisions spec types and the System One translation Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): share one DecisionsModel config and require model and usage on responses Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): rename the shared pydantic parent to DecisionsObjectBase Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(decisions): dispatch /v1/decisions through provider configs and the shared HTTP handler Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(decisions): map OpenRouter connection failures to APIConnectionError and drop explanatory docstrings Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(decisions): switch /v1/decisions to the OpenAI Decisions schema Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(decisions): build the usage the OpenAI response schema now requires Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(lens): ask signal questions through the OpenAI Decisions schema Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(decisions): refuse safety_identifier for System One providers unless drop_params * feat(decisions): refuse safety_identifier on providers that cannot take it unless drop_params drops it * test(decisions): cover hosted_vllm in the safety_identifier and per-provider wire tests * fix(decisions): check a System One request's safety_identifier against the provider too * fix(decisions): drop a non-string safety_identifier under drop_params A malformed safety_identifier now follows the drop_params convention in both body shapes: it answers 400 without drop_params and is dropped before the provider call with it. A string identifier on OpenAI stays on the wire either way. * fix(decisions): let /v1/decisions drop a non-string safety_identifier under drop_params The route checked the whole body before routing, so a non-string safety_identifier answered 400 even when the deployment or the body set drop_params. The route now leaves that field to the Decisions call, which knows every drop_params source * refactor(decisions): return the unsupported safety_identifier as a value and raise it in _prepare_call --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit 546402c)
… ARN (#45678) * feat(strands_decider): call a Strands Decider on an AgentCore runtime ARN A strands_decider deployment whose api_base is a bedrock-agentcore runtime ARN now calls InvokeAgentRuntime on that runtime, signed with SigV4 from the deployment's aws_* params or the default chain, reuses one session per runtime, and maps the runtime's 200 error envelopes to 400, 503, or 500 * ci: run the strands_decider unit tests in the llms job * fix(strands_decider): take the AgentCore session id from the deployment, never the caller A caller could pick the runtime session through extra_headers, and every new id starts another microVM. The session id now comes from the deployment's agentcore_runtime_session_id (banned in request bodies) or the ARN default, and caller-supplied host, x-amz-*, and x-amzn-bedrock-agentcore-runtime-* headers are not forwarded * fix(strands_decider): map runtime error replies only on AgentCore ARN calls * fix(strands_decider): sign plain decisions calls inline, off the AWS signing executor * test(strands_decider): cover AgentCore runtime ARN calls in integration wire tests --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit ed9c31c)
…45838) * docs(proxy): describe /v1/decisions and /v1/systemone in Swagger UI Add summaries, descriptions, inlined request body schemas with examples and typed 200 responses to the decision routes and their aliases, so the OpenAPI document and the lazy snapshot show both request formats Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(proxy): cap _inlined schema walk depth for the recursion check Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit bc2cc42)
…-reported cost (#45853) PR #45667 removed openrouter/typesafe/jev-1.13 from the cost map after #45640 moved OpenRouter decisions billing to usage.cost. The OpenAI-format wire test still read the removed row and raised KeyError on CircleCI integration-providers Co-authored-by: mateo <mateo@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 5894968)
…enAI shape (#45846) * feat(sdk): add litellm.systemone and trim litellm.decisions to the OpenAI shape Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: run tests/unit/systemone in the core-utils unit shard Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(sdk): keep litellm.decisions(state=...) working with a DeprecationWarning Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test: make tests/unit/systemone a package Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * feat(sdk): surface the litellm.decisions(state=...) deprecation as a UserWarning Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 25d9b05)
…o rc/1.105.0 schema.d.ts is regenerated with npm run gen:api instead of hand-merged, the Strands logo the Add Model list imports is copied from main, and the picked tests get the import order and Final import this line's ruff asks for Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…allback checks stay isolated Ports the pytest_runtest_call hook from tests/unit/conftest.py on main (#44146). Without it the asystemone call type test picks up adecisions callbacks queued by earlier tests in the same worker Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ui/litellm-dashboard/src/lib/http/schema.d.ts is generated from the proxy OpenAPI schema, so it is rebuilt with npm run gen:api on this line instead of merged by hand Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
|
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fd7aec3. Configure here.
TLDR
Backports the decisions and Jev work merged on main since #45190 onto stable/1.104.x, without the decisions playground, so the 1.104.3 patch serves every decisions provider and SDK shape the launch ships with
Problem this solves:
litellm.systemoneusage.costHow it solves it:
git cherry-pick -x, adapted where stable/1.104.x lacks what they build onschema.d.tson the line instead of merging the generated file by handUser Flow
Before: a proxy admin on 1.104.2 cannot route a decisions request to a hosted vLLM or Azure decider
hosted_vllm/my-deciderorazure_ai/Microsoft-Decision-1to the config and start the proxyAfter: the same request is answered, and the new providers show up everywhere the old ones did
usageblock, billed at the line's price for that modellitellm.systemone(...)andlitellm.decisions(...)work from the SDK with the same shapes as mainPicks
Skipped on purpose
ai_decideand the auto-router decider need the Laya and Bespoke classifier work (feat: add Laya gateway and OSS classifier providers #43626, feat: add Bespoke Nimble gateway and OSS classifier support #44246, fix(auto-router): separate tuning and select chained heuristic #44928) that is not on the linetests/integration/translationrunnerAdaptations on this line
_get_httpx_clientname and itsDecisionsIRRequestflow, with the AgentCore signing from feat(strands_decider): call a Strands Decider on an AgentCore runtime ARN #45678 on toplitellm_core_utils.hidden_params, which the line does not have; the decisions and pass-through billing fromusage.costis intests/unit/decisions/test_main.pyare dropped with feat(decisions): add Databricks ai_decide as a /v1/decisions provider and auto-router decider #45200tests/unit/conftest.pygets the per-test logging worker flush from main (perf(ci): isolate and shard integration suites #44146), without which the new systemone callback test sees callbacks queued by earlier testsui/litellm-dashboard/src/lib/http/schema.d.tsis regenerated withnpm run gen:api, and the Strands logo is copied from maintests/integration/management/test_model_health_check.pyis not on this line so its hunk is droppedbump: version 1.104.3commitTesting
tests/unit/decisions,tests/unit/systemone,tests/unit/proxy/decisions_endpoints,tests/unit/proxy/public_endpoints, the strands_decider, openrouter, azure_ai and hosted_vllm provider tests,tests/test_litellm/proxy/auth/test_auth_utils.py,tests/test_litellm/proxy/common_utils/test_custom_openapi_spec.pyandtests/unit/test_cost_map_guard.py: 1131 passed on this branchprovider_info_helpers.test.tsx: 75 passed, no type errorsScreenshots / Proof of Fix
Live /qa leg at this tip (fd7aec3) against the merge base (19180f3, 1.104.2): two proxies booted from clean worktrees with
--num_workers 2, their own Postgres and Redis, real TypeSafe, OpenRouter and Azure AI Foundry keys from the shared vault, real spend. Full command and output log in the QA record kept with the run; the flips a user sees:Two picks could not be exercised live and are blocked, not mocked: hosted_vllm (no vLLM server; the route now resolves the provider and fails on connect instead of 400 unknown provider) and the Strands Decider AgentCore call (no AgentCore runtime ARN credential in the shared vault)
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/unit/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Type
🆕 New Feature
Caveats (if any)
Medium
databricks/...decisions requests still return the unknown provider 400usage.costLow
safety_identifieron a provider that cannot take it is now a 400 unlessdrop_paramsdrops itFinal Attestation