Commit graph

53352 commits

Author SHA1 Message Date
yuneng-jiang
375b48fe62
Merge pull request #48280 from BerriAI/image-content-cleanup-slim-1.104
build(docker): refresh base images and ship only runtime files in component images (1.104.x)
2026-10-24 23:01:07 -07:00
Yuneng Jiang
99aa8f8177
build(docker): copy only runtime files into the gateway, backend and migrations images
The component runtime stages copied the builder's whole /app, which is the
entire repository plus build output: six lockfiles, helm, terraform, docs,
.env.example and the Rust build tree. Measured at runtime with an audit hook
on a booted container, the gateway reads only gateway/, litellm/ and
enterprise/ from /app, the backend only backend/, litellm/ and enterprise/,
and the migrations job only litellm/ and run.py. The pyproject.toml read is
prisma-python's optional [tool.prisma] lookup, which ours does not define

Copy just those, plus .venv, the entrypoint script and schema.prisma for the
gateway and backend. PYTHONPATH=/app and the in-Dockerfile asserts are
unchanged
2026-10-24 19:04:52 -07:00
Yuneng Jiang
0e943b10b2
build(docker): move to newer wolfi-base and nginx base images
Bump the pinned wolfi-base digest in every Wolfi Dockerfile to 360896ef, which
ships brotli 1.2.1-r1 and ca-certificates-bundle 20260909-r3. The previous
digest already carried libbrotli 1.2.0-r6 as an OpenSSL dependency, and
`apk add --no-cache` never upgrades a package the base already has

Move the UI image to nginx 1.31.8-alpine3.24, whose CA bundle is the 20261020
Mozilla set, and upgrade brotli-libs in its runtime stage since no nginx
digest ships 1.2.1 yet
2026-10-24 19:04:52 -07:00
yuneng-jiang
4a8940a9fb
Merge pull request #48076 from BerriAI/litellm_backport_47670_47969_stable_1_104_x
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled
chore(release): backport #44345, #47670, #47969, #48055, #48103, #48110 to stable/1.104.x
2026-10-23 16:15:38 -07:00
Yuneng Jiang
1a026cc38c
chore(deps): bump mlflow, pypdf and setuptools
Redoes #48110 on this line. The lock moves mlflow, mlflow-skinny and mlflow-tracing to 3.17.2, pypdf to 6.21.2 and setuptools to 84.1.0 inside their existing ranges. mlflow 3.17.2 and pypdf 6.21.2 are still inside the 3-day exclude-newer window, so they get their own exclude-newer-package cutoffs, matching main. The lock was regenerated with uv 0.11.7
2026-10-23 15:36:54 -07:00
Yuneng Jiang
883deaf08b
Rotate the cosign image-signing public key
(cherry picked from commit e82a3c6469)
2026-10-23 15:27:48 -07:00
Yuneng Jiang
c3b9a751b3
chore: update Next.js build artifacts (2026-10-23 22:19 UTC, node v24.19.0) 2026-10-23 15:19:30 -07:00
Yuneng Jiang
2b157b4151
chore(deps): bump vscode-extension vite and vitest
Raises the vitest floor to ^4.1.12 and moves the locked vite to 8.3.4, matching main. The lock only moves the vitest packages, vite, and what vite 8.3.4 requires, which is rolldown 1.2.14 with its bindings and @oxc-project/types, postcss 8.5.30 and nanoid 3.3.20
2026-10-23 15:17:21 -07:00
devin-ai-integration[bot]
285d52bb63
refactor(dashboard): migrate to zod 4 and openai 6 (#44345)
* refactor(dashboard): migrate to zod 4 and openai 6

Bump the dashboard to real zod 4.6.5 and openai 6.49.0 so every module
imports from bare "zod" instead of "zod/v4". Ports the ten files that
still used the zod 3 API (error params, record, passthrough, strict,
email/date validators, union discriminator codes) and adapts the
LiteAdmin tool schemas and form plumbing where openai 6 and zod 4
changed behaviour.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style(dashboard): prettier format zod 4 schema files

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(dashboard): restore system one missing state message under zod 4

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

Backport notes for stable 1.104.x. package.json and package-lock.json were restored from the line and only openai moves to 6.49.0, since zod is already on 4.6.6 here. The lock change is openai plus the 21 packages only openai 4 needed

agent_identity.ts and the systemOneUI schemas.ts and validatePayload.test.ts do not exist on this line, so their hunks are dropped
build_auto_router_routing_test_request.ts keeps the line's jev-only schema with the record key and loose() from this change, and its default({}) becomes prefault({}) so the saved JEV config defaults are still parsed in under zod 4
jev_classifier_config.ts keeps the line's plain object schema, because the provider transform and refine this change edits are not on this line

---------

Co-authored-by: Yujong Lee <yujong@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 0c86d6bfc9)
2026-10-23 15:17:21 -07:00
Yuneng Jiang
bee14f41e9
chore(deps): bump dashboard next, zod, vite, vitest and sharp
Moves next to 16.4.1, zod to 4.6.6, vite to 7.3.7, vitest and @vitest/ui to 4.1.12, and raises the sharp override to ^0.35.5, matching main. @vitest/coverage-v8 goes to 4.1.12 with them because it peers on the exact vitest version

A top-level zod override points every nested consumer at the root copy, so the lock carries a single zod 4.6.6 instead of keeping knip's nested 4.4.3

npm install also refreshed rollup, chai, obug, std-env and tinyrainbow to newer releases although the bumped packages accept the locked ones. Those entries are kept at their previous versions, the same versions main resolves, so the lock only moves the packages above and their platform builds
2026-10-23 15:17:21 -07:00
Yuneng Jiang
5758936e8d
chore(deps): bump OpenTelemetry, logfire, pypdf, GitPython, graphql-core, Brotli and Pillow
Moves the OpenTelemetry API, SDK and OTLP exporter pins to 1.45.1 and the FastAPI instrumentation to 0.66b1 in every group, logfire to 5.2.0, and splits Pillow so Python 3.11 and newer get 13.0.0 while 3.10 stays on 12.3.0, matching main

The lock is re-derived on this line with uv 0.11.7. GitPython goes to 3.2.1, graphql-core to 3.2.12, Brotli to 1.2.1 and pypdf to 6.21.1 inside their existing ranges, and the OpenTelemetry 1.45 line pulls in opentelemetry-exporter-http-transport and opentelemetry-exporter-otlp-common. No other package moves

Brotli 1.2.1 is still inside the 3-day release window, so it gets its own exclude-newer-package cutoff
2026-10-23 15:17:21 -07:00
Ishaan
16287b7133 fix(ci): unblock dependency checks (#48055)
* fix(deps): upgrade Python dependencies

* fix(deps): lock patched Python dependency versions

* fix(otel): preserve JSON export with the updated SDK

* test(otel): cover JSON export with the updated SDK

* test(otel): update SDK log records and worker discovery

* fix(ui): align Lens peer dependency with patched Next.js

* fix(otel): hand the AgentOps exporter a session it owns for the JWT header

OpenTelemetry 1.45 moved the OTLP HTTP exporter's requests.Session behind a
transport, so writing the minted JWT to the exporter's private _session raised,
was swallowed, and every AgentOps batch went out unauthenticated. The exporter
now creates the session, passes it through the public session= argument and
sets the Authorization header on it

The tests now drive a real export, serving the token endpoint with respx and
capturing the OTLP POST with requests_mock, instead of reading SDK internals

* fix(otel): skip FastAPI instrumentation once the app has started

opentelemetry-instrumentation-fastapi 0.66b1 wraps build_middleware_stack instead
of calling add_middleware, so instrumenting an app whose middleware stack is
already built no longer raises. The call silently did nothing while we still
registered the global response propagator. Check the built stack up front and
skip both, which is what the existing test expects

* test(otel): assert exported requests and span flags instead of SDK internals

OpenTelemetry 1.45 dropped the exporter's private _headers and sets the W3C
random-trace-id flag on new traces, so traceresponse ends in -03. The Langtrace
and Langfuse tests now export through requests_mock and check the URL and headers
the collector receives, and the traceresponse tests expect the server span's own
trace flags

* fix(deps): bump dashboard zod to 4.6.6 and make the vendored Lens use it

zod 4.6.5 is flagged by the dependency scan and blocks osv-scan on every PR. A
root bump alone leaves the vendored Lens tarball, which pins zod 4.6.5 exactly,
on its own nested copy, so a top-level zod override points every consumer at the
root version and the lock carries a single zod 4.6.6

* test(ui): stub the tag summary fetch the client panel retry refreshes

Retrying the model breakdown refetches /tag/summary, which this integration test
left on the real network. When that request failed before the assertion, the
panel switched to its summary error and unmounted the model row, so the test
passed or failed by timing

* fix(deps): drop the duplicated Lens override from the dashboard package.json

* style(ui): format the client panel fetch stub

Backport notes for stable 1.104.x. The dependency files (pyproject.toml, uv.lock, the dashboard package.json and package-lock.json) were left out of this pick and are re-derived on the line in the following commits

ClientUsagePanel.integration.test.tsx does not exist on this line, so its stub hunk is dropped
test_otel_v2_mount.py keeps the line's version because the traceresponse tests the squash edits are not on this line
test_litellm_logging.py keeps the line's version because the Langtrace export test the squash edits is not on this line
test_opentelemetry.py keeps the line's trace import without SpanLimits, which only the newer tests on main use

---------

Co-authored-by: Yuneng Jiang <yuneng@berri.ai>
(cherry picked from commit 8f9894fbd6)
2026-10-23 15:17:20 -07:00
shrey-berri
97c2c560c1
fix(security): update bundled CA roots and preserve Prisma image compatibility (#47969)
* fix(security): bump grpcio and boto3 so their bundled CA files drop the compromised eMudhra roots

grpc ignores SSL_CERT_FILE and verifies every channel against its own bundled roots.pem. In 1.78.0 that file still trusts emSign ECC Root CA - G3 and AAA Certificate Services, so Vertex AI, Google KMS, Chirp STT and OTLP gRPC exporters (Arize) accept all 14 advisory chains. 1.84.1 is the first release whose roots.pem drops both roots.

botocore uses certifi when it is installed and falls back to its bundled cacert.pem otherwise. Through 1.43.116 that file still trusts AAA Certificate Services. Requiring boto3 1.43.117 pulls in botocore 1.43.117, the first release whose cacert.pem rejects all 14 advisory chains, so the fallback stays safe if certifi is ever absent

* fix(docker): provide OpenSSL 3 when generating Prisma engines

(cherry picked from commit 52166b51a1)
2026-10-23 11:58:40 -07:00
ryan-crabbe-berri
ba74025478
fix(security): stop trusting the compromised eMudhra root CA (#47670)
Update certifi, Rust trust roots, and the Docker CA bundle to remove emSign ECC Root CA - G3

Require the fixed certifi release in litellm-core and retain libssl3 in Docker runtimes for Prisma compatibility

Co-authored-by: shin-berri <shin-laptop@berri.ai>
(cherry picked from commit f2118fc767)
2026-10-23 11:58:34 -07:00
yuneng-jiang
a742ca3693
Merge pull request #47805 from BerriAI/litellm_/jovial-curie-bf54f1
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled
chore: rebuild Admin UI bundle for stable/1.104.x (v1.104.6)
2026-10-21 00:55:36 -07:00
yuneng-jiang
c1f73e4bf5
Merge pull request #47705 from BerriAI/litellm_count_tokens_hard400_stable_1_104_x
feat(count_tokens)!: reject known-wrong local estimates with HTTP 400 on stable/1.104.x
2026-10-21 00:53:35 -07:00
yuneng-jiang
9372fc0b86
Merge pull request #47685 from BerriAI/litellm_backport_count_tokens_1_104_5_stable_1_104_x
fix(count_tokens): backport #47173 and #47353 to stable/1.104.x for v1.104.5
2026-10-21 00:53:12 -07:00
Yuneng Jiang
0361e81f4a
chore: update Next.js build artifacts (2026-10-21 07:18 UTC, node v24.19.0) 2026-10-21 00:18:21 -07:00
yuneng-jiang
250fda4240
Merge pull request #47802 from BerriAI/patch_d351e54e
fix: backport the 1.103.x parity fixes and #43600 to stable/1.104.x for v1.104.6
2026-10-21 00:14:45 -07:00
Yuneng Jiang
2b2e960848
Merge stable/1.104.x (v1.104.6 prep) into patch_d351e54e
Keeps stable/1.104.x's 1.104.6 version in pyproject.toml and uv.lock, so this branch no longer bumps the version. In litellm_logging.py both async success helpers stay, the base's enqueued flag and the claim that #44508 adds, matching main. The two test files keep both sides' new tests
2026-10-20 23:54:09 -07:00
yuneng-jiang
b2e44bf862
Merge pull request #47726 from BerriAI/litellm_backport_p0_batch_translation_cost_stable_1_104_x
fix(batches)!: backport P0 batch-cost, pricing and translation fixes to stable/1.104.x for v1.104.6
2026-10-20 23:32:24 -07:00
Yuneng Jiang
bd382afc17
Merge stable/1.104.x (#47718) into litellm_backport_p0_batch_translation_cost_stable_1_104_x
# Conflicts:
#	litellm/model_prices_and_context_window_backup.json
#	litellm/proxy/hooks/proxy_track_cost_callback.py
#	litellm/responses/litellm_completion_transformation/streaming_iterator.py
#	model_prices_and_context_window.json
#	tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
#	tests/unit/test_utils.py
2026-10-20 23:07:37 -07:00
yuneng-jiang
01823bd07f
Merge pull request #47718 from BerriAI/litellm_backport_lit145_stable_1_104_x
fix(proxy): backport the LIT-145 spend tracking fixes to stable/1.104.x for v1.104.6
2026-10-20 23:04:12 -07:00
Yuneng Jiang
7b0e159628
bump: litellm 1.104.5 -> 1.104.6 2026-10-20 22:42:33 -07:00
Yuneng Jiang
240d4157f8
bump: litellm 1.104.5 -> 1.104.6, litellm-enterprise 0.1.71 -> 0.1.71.post1 2026-10-20 22:42:08 -07:00
Yuneng Jiang
b465d97ead
Merge stable/1.104.x (v1.104.5) into litellm_backport_lit145_stable_1_104_x
# Conflicts:
#	uv.lock
2026-10-20 22:42:07 -07:00
Mrinal Chanshetty
aa960d620a fix(anthropic): carry main's dangerous-tool-use beta map entries; skip worker-kill chaos test
The bundled beta map stripped dangerous-tool-use-2026-09-03 for providers
main supports it on, so safeguards requests went upstream without the beta
whenever the proxy used the bundled map. The worker-SIGKILL chaos test needs
OwnedProxy.replacing_worker, which this line's integration harness lacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:27:07 -07:00
mateo-berri
ce19cf4b61 Merge remote-tracking branch 'origin/stable/1.104.x' into litellm_backport_count_tokens_1_104_5_stable_1_104_x
# Conflicts:
#	uv.lock
2026-10-20 20:54:25 -07:00
mateo-berri
2de6c76055 chore(count_tokens): give the picked token counter lines type-discipline reasons on stable/1.104.x 2026-10-20 20:43:03 -07:00
Mrinal Chanshetty
c4b5c45196 Merge branch 'stable/1.104.x' into litellm_backport_p0_batch_translation_cost_stable_1_104_x 2026-10-20 18:40:29 -07:00
mateo
5a30e632e7 fix(count_tokens): resolve provider during cooldown and script upstream in tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:35:39 +00:00
Mrinal Chanshetty
810db3747d bump: version 1.104.5 2026-10-20 18:24:14 -07:00
Mrinal Chanshetty
f13eb6d8fb chore: bump litellm-enterprise 0.1.71 -> 0.1.71.post1 2026-10-20 18:24:14 -07:00
Mrinal Chanshetty
b8e89a881b chore(cost-map): accept the mirrored map's search_free_requests and token_count_model.litellm_provider in the schema 2026-10-20 18:24:13 -07:00
Mrinal Chanshetty
9c28744ad5 test: retarget cost-map tests to the rows mirrored from main 2026-10-20 18:24:13 -07:00
Mrinal Chanshetty
631e26f361 chore(cost-map): mirror model_prices_and_context_window.json and backup from main at 6083cf9776 2026-10-20 18:24:13 -07:00
Mrinal Chanshetty
23e0a798c0 chore(deps): bump aiohttp to 3.14.5 and claude-agent-sdk to 0.2.165 to match main 2026-10-20 18:24:13 -07:00
devin-ai-integration[bot]
827cc15bfc bump: version 1.104.5 2026-10-21 01:14:53 +00:00
devin-ai-integration[bot]
97bcc92fad chore(deps): bump aiohttp to 3.14.4 2026-10-21 01:14:11 +00:00
Kerry Lu
2313d343ba fix(logging): spilled over PTU requests without base_model log the served model's rates (#47655)
* fix(logging): report pay-as-you-go rates for spilled over PTU requests without base_model

* fix(logging): keep the provider response model so spilled over PTU payloads price the served model

* fix(logging): keep a provider_response_model the response already carries

* fix(logging): read the carried provider_response_model through a typed adapter

---------

Backport of #47655 to stable/1.104.x
Cherry-picked from 6b1f4ed46f (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
5a34391482 fix(proxy): price earlier timed-out retry attempts at their own deployment's model rate (#47648)
* fix(proxy): bill every earlier timed-out retry attempt at its own deployment's model rate

* fix(router): read the retry record's base_model through the typed metadata helper

* fix(router): keep the four-record retry breadcrumb cap

* fix(router): carry a deployment's litellm_params base_model on its retry record

* chore(router): place the cast-ok reason on the cast line and list the base_model helper as covered through log_retry

---------

Backport of #47648 to stable/1.104.x
Cherry-picked from 27efc387f7 (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
a8807fb0bb fix(router): price cost-based routing through model_info.base_model (#47617)
* fix(router): price cost-based routing through model_info.base_model

* fix(router): keep cost-based routing pricing helpers fully typed

* fix(router): drop typing.cast from cost-based routing pricing helpers

* fix(router): read the cost map through a typed accessor in cost-based routing

* fix(router): avoid a Final rebind inside the cost-based routing loop

* refactor(router): share deployment_pricing_models across spend, listing and cost-based routing

* refactor(router): keep the /v1/models listing key inline, share pricing models for spend and routing

* refactor(router): inline the deployment pricing-model wrapper in cost-based routing

* refactor(router): read deployment pricing models through one shared helper

deployment_pricing_models(deployment) now owns the model_info.base_model / litellm_params.base_model /
litellm_params.model unpacking, used by cost-based routing and the /v1/models listing. pricing_models(base_model, model)
stays for the failure-row spend estimate, which already holds the two names

* refactor(router): share the str-keyed mapping validator with cost-based routing

* ci: re-run after flaky test_aiohttp_transport read timeout in llms-providers

---------

Backport of #47617 to stable/1.104.x
Cherry-picked from 0c6731eb5c (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
f9800f1fc0 fix(proxy): price a 499 spend row only for the proxy's own disconnect, and never after the call already completed (#47652)
* fix(proxy): price a 499 spend row only for the proxy's own disconnect, and never after the call already completed

* fix(proxy): gate the zero-cost 499 row on the success log being enqueued, not merely claimed

---------

Backport of #47652 to stable/1.104.x
Cherry-picked from ffb7133d32 (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
b2ed8bc1c3 fix(proxy): scope the search free-tier counter to the request's provider (#47646)
* fix(proxy): scope the search free-tier counter to the request's provider

* fix(proxy): read the provider with get so partial spend payloads still get the free tier

* test(proxy): give the grounded spend payload fixture its provider

---------

Backport of #47646 to stable/1.104.x
Cherry-picked from 640f2d865b (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
b092d90f75 fix(proxy): price a billed failure row at the deployment's long-context tier like the success path (#47647)
Backport of #47647 to stable/1.104.x
Cherry-picked from 70ece3501f (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
13779e98bd fix(proxy): strip caller base_model from spend pricing and reject lone surrogates in multipart metadata (#47639)
* fix(proxy): strip caller base_model from spend pricing and reject lone surrogates in multipart metadata

* fix(proxy): type the parsed multipart metadata so basedpyright does not grow reportArgumentType

---------

Backport of #47639 to stable/1.104.x
Cherry-picked from 2a268951c4 (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
d388cb8253 fix(proxy): bill partial Responses API streams when the client disconnects (#47611)
* fix(proxy): bill partial Responses API streams when the client disconnects

Streamed /v1/responses requests and the default-route OpenAI and Azure /v1/messages requests behind them logged a 499 with zero spend when the client went away mid-stream, while /v1/chat/completions already billed the chunks it had sent. The Responses API iterator now keeps the response.created payload and can hand the disconnect cleanup a response.incomplete event with counted usage and the served service_tier, and the messages-route byte stream and router wrappers delegate to it.

* fix(proxy): satisfy lint gates for partial Responses API disconnect billing

Make the disconnect helper public so the proxy, router and messages adapter can import it without reportPrivateUsage, type the SSE byte stream as an AsyncGenerator so aclose is known, read litellm_call_id off the logging object, and keep the new tests on Final locals with the recorder injected through dynamic_async_success_callbacks instead of litellm.callbacks.

* fix(router): bill the primary stream's tokens after a mid-stream hop and chat-bridge Responses streams on disconnect

The router's fallback wrapper now folds the primary Responses stream's relayed tokens into the fallback's disconnect event the way _combine_responses_fallback_usage does for a natural end of stream, and LiteLLMCompletionStreamingIterator (chat-only providers served through /v1/responses) builds its disconnect event from the chat completion chunks it collected. stamp_responses_usage_cost is now public so the bridge module can price that event.

* Potential fix for pull request finding 'CodeQL / Log Injection'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Backport of #47611 to stable/1.104.x
Cherry-picked from f0ae445cc4 (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
dbbebd07bf fix(proxy): flush the spend-log queue only for Responses turns the bridge reads back (#47614)
Every /v1/responses spend log asked its worker to flush the queue right away so a
chained previous_response_id could find the row. Only the chat-completions bridge
reads that row. Native Responses providers hold the conversation upstream, so their
rows now wait for the batch write like chat rows do

Backport of #47614 to stable/1.104.x
Cherry-picked from 423362bab2 (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
de1e76bd13 feat(proxy): opt-in free-tier allowance for Google Search grounding spend (#47494)
* feat(proxy): opt-in free-tier allowance for Google Search grounding spend

* fix(proxy): declare the search free tier counter's service target

* test(cost_map): allow search_free_requests in the cost map schema

* fix(proxy): skip cache hits and never free more than the billed cost in the search free tier

---------

Backport of #47494 to stable/1.104.x
Cherry-picked from e63aec029a (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00
Kerry Lu
223690801c feat(proxy): write one spend row per billed timed-out retry attempt (#47416)
_failure_spend_rows yields the final row plus one re-keyed row per lifted billed_failed_attempts entry (<request_id>-attempt-<position>, the attempt's usage, cost, retry count and deployment id), each written through DBSpendUpdateWriter.update_database so it also deducts from key, team and user spend

Backport of #47416 to stable/1.104.x
Cherry-picked from ad8ca533ca (main)

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 01:14:11 +00:00