Commit graph

9968 commits

Author SHA1 Message Date
Krrish Dholakia
26c7412339
feat: add litellm.compress() — BM25-based prompt compression with retrieval tool (#25637)
* feat: add litellm.compress() for BM25-based context compression

Adds a compress() utility that reduces context size for LLM calls using
BM25 relevance scoring (with optional semantic embeddings via
litellm.embedding()). Messages below a token threshold pass through
unchanged; messages above are scored, ranked, and the lowest-relevance
ones replaced with stubs. Originals are cached and a retrieval tool is
injected so the model can recover dropped content on demand.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(compress): truncate high-scoring messages instead of fully stubbing them

When a relevant message was too large to fit in the token budget it was
replaced with a stub, leaving the LLM with no real content to work with.
Now the highest-scoring overflow message is truncated (first 70% + last 30%
of words) to fill the remaining budget, so the LLM always receives actual
content rather than just a retrieval pointer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(bm25): add prefix expansion so query terms match inflected doc tokens

"cook" now matches "cooking", "auth" matches "authentication", etc.
Without this, short query terms scored 0 against longer inflected forms
in documents, causing the wrong message to be kept.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add routing correctness test and eval harness for litellm.compress()

- test_simple_compression: parametrized test verifying BM25 routes the
  right message based on query ("How to cook?" keeps cooking, "Fix auth"
  keeps auth content)
- eval_compression.py: end-to-end eval harness comparing baseline vs
  compressed model performance on HumanEval-style coding problems

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(eval): add SWE-bench Lite compression eval harness

Uses princeton-nlp/SWE-bench_Lite_bm25_27K which bundles ~27k tokens of
BM25-retrieved repo context per problem — large enough to meaningfully
stress litellm.compress() without Docker or GitHub API calls.

Proxy eval metrics (no test runner needed):
  - has_diff: model produced a valid unified diff
  - file_overlap: fraction of gold-patch files in generated patch
  - exact_file_match: generated patch touches exactly the right files

Run: python tests/eval_swe_bench.py --model gpt-4o --problems 10

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(eval): robust dataset loading + sys.path fix for worktree imports

- Add HuggingFace API fallback so the SWE-bench loader doesn't need
  the `datasets` library (avoids pyarrow/numpy binary compat issues)
- Insert repo root into sys.path so compression module resolves
  from worktrees
- Use direct import of litellm_compress to avoid __getattr__ issues

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* improve compression quality: line-based truncation, multi-message budget, 70% default target

- Switch truncate_message from word-based to line-based splitting to
  preserve code structure (function boundaries, indentation)
- Allow multiple messages to be truncated instead of burning entire
  budget on one overflow message
- Raise default compression target from 50% to 70% of trigger for
  better quality/cost tradeoff
- Add --compression-target CLI arg to SWE-bench eval harness
- Move tests to canonical locations (tests/test_litellm/, scripts/)
- Add docs page and sidebar entries for compress()

Eval results (5 problems, Opus, trigger=10k):
  Hunk overlap delta improved from -0.417 to -0.221
  Content similarity now matches baseline (+0.006)
  Cost savings: 72%

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add SWE-bench performance results to compress() docs

Include benchmark table from Opus eval (5 problems, trigger=10k)
showing 72% cost savings with file-level quality fully preserved.
Add metric explanations and eval runner examples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(eval): use tolerance-based hunk overlap metric

The exact line-number matching was too brittle — LLM-generated patches
often target the right code region but with slightly offset line numbers.
Switch to hunk-level overlap with a 10-line tolerance window so nearby
edits count as matches. This better reflects actual patch quality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add compression_interception callback for LiteLLM Proxy

Add a proxy callback that automatically compresses incoming /v1/messages
payloads above a configurable token threshold, runs the retrieval tool
loop server-side, and returns the final response. This brings compress()
support to proxy deployments (e.g. Claude Code via /v1/messages).

- New callback: litellm/integrations/compression_interception/
- Proxy config: compression_interception_params in litellm_settings
- Support for input_type param in compress() (openai vs anthropic)
- Docs: proxy setup instructions with YAML config example
- Tests: 139-line unit test suite for the interception handler

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Revert "feat: add compression_interception callback for LiteLLM Proxy"

This reverts commit 72bd5cb152.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 12:23:54 -07:00
Yuneng Jiang
df75e79615
raise ValueError on os.environ/ references in request-supplied callback params
Previously these were silently dropped with a verbose warning, which
could break observability integrations without surfacing a clear error.
Now raises ValueError with remediation steps (configure server-side
or pass the resolved value) so callers get immediate, actionable feedback.
2026-04-13 12:00:25 -07:00
michelligabriele
0eae9f101e
fix(auth): gate post-custom-auth DB lookups behind opt-in flag (#25634) 2026-04-13 08:02:16 -07:00
Sameer Kankute
2506ccb2bc
refactor(responses): drop use_responses_api_bridge; fix PLR0915
- Only use_chat_completions_api and openai/chat_completions/ opt into the bridge
- Extract MCP gateway and file_search emulation dispatch to cut responses() size
- Update docs and tests

Made-with: Cursor
2026-04-13 18:22:17 +05:30
Sameer Kankute
0a8bf4ec9e
feat(responses): rename bridge opt-in to use_chat_completions_api
- Add use_chat_completions_api (keep use_responses_api_bridge as deprecated alias)
- Support openai/chat_completions/<model> model prefix for the same behavior
- Forward use_chat_completions_api in file_search emulation inner calls
- Update response_api.md and extend unit tests

Made-with: Cursor
2026-04-13 18:03:27 +05:30
Sameer Kankute
5ac1089117
Merge branch 'main' into litellm_Sameerlite/openai-chat-to-responses 2026-04-13 17:59:13 +05:30
Sameer Kankute
380c14e7dd
fix: address Greptile review comments
- Sanitize custom_id to meet GCP label constraints (lowercase, alphanumeric, max 63 chars)
- Improve batch output detection heuristic with processed_time and candidates/status checks
- Move inline imports to module level
- Fix Content-Length header for transformed responses
- Add test for label sanitization

Made-with: Cursor
2026-04-13 17:16:17 +05:30
Sameer Kankute
f6d5502faa
feat(vertex-ai): transform batch prediction outputs to OpenAI format
- Add automatic conversion of Vertex AI batch prediction JSONL to OpenAI format
- Preserve custom_id via Vertex AI labels for request correlation
- Fix Content-Length header mismatch in transformed responses
- Add comprehensive tests for batch output transformation

Made-with: Cursor
2026-04-13 16:42:25 +05:30
Sameer Kankute
fa605d85c0
Merge pull request #25616 from BerriAI/main
merge main
2026-04-13 08:43:43 +05:30
Yuneng Jiang
4617d230f8
fix: hash sk- api_key in /spend/logs date-range path and add filter tests
Brings the date-range branch in line with the non-date-range branch which
already hashes sk- prefixed tokens before querying. Adds coverage for
filter-combination behavior in view_spend_logs.
2026-04-11 23:33:15 -07:00
Yuneng Jiang
6baee0dfcb
address review feedback
- Log a warning when dropping callback params that carry os.environ/
  references so operators notice the misconfiguration.
- Require absolute paths in oidc/file/ and correct the documented
  example to use the leading-slash form.
- Drop the unused return value from _reject_os_environ_references.
2026-04-11 21:52:39 -07:00
Yuneng Jiang
06a0d4498a
fix: tighten handling of environment references in request parameters
- Reject os.environ/ references supplied via /health/test_connection
  request params instead of resolving them; config-sourced values are
  already resolved before reaching the endpoint.
- Skip os.environ/ references in dynamic callback params loaded from
  per-request metadata.
- Constrain oidc/file/ to an allowed credential directory allowlist
  (defaults to /var/run/secrets and /run/secrets, overridable via
  LITELLM_OIDC_ALLOWED_CREDENTIAL_DIRS).
2026-04-11 21:41:41 -07:00
csoni-cweave
ee06b9278a
feat(model):add wandb model offerings to include kimi-k2.5 and minimax-m2.5 (#25409) 2026-04-11 19:46:40 -07:00
Dmitriy Alergant
e1bf114591
fix(budget): align budget table reset times with standardized calendar schedule (#25440)
Budget table entries (team members, end-users) used duration_in_seconds()
for a sliding-window reset, while keys/users/teams used calendar-aligned
get_budget_reset_time(). This made "30d" and "1mo" mean different things
depending on entity type. Now both paths use get_budget_reset_time() for
consistent calendar-aligned resets (e.g. "30d" → 1st of next month).

Fixes #25432

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:45:23 -07:00
Utsab Dahal
e3d160f158
fix(embedding): omit null encoding_format for openai requests (#25395) 2026-04-11 19:39:19 -07:00
Darien Kindlund
f54e4e664b
fix(proxy): use _hash_token_if_needed for cache invalidation in bulk update and key rotation (#25552)
Two code paths in key_management_endpoints.py call hash_token()
unconditionally when invalidating the user_api_key_cache after a key
update.  When the caller passes a pre-hashed token ID (not an sk-
prefixed key), hash_token() double-hashes it, producing a cache key
that does not match the actual cached entry.  Cache invalidation
silently fails.

This is compounded by update_cache() which writes the stale cached key
object back with a fresh 60s TTL after every successful request,
preventing natural TTL expiry.  The stale entry (with outdated fields
like max_budget=None) persists indefinitely under load.

PR #24969 fixed this in update_key_fn but missed two other call sites:
- _process_single_key_update (bulk update path)
- _execute_virtual_key_regeneration (key rotation path)

Fix: replace hash_token() with _hash_token_if_needed() in both
locations, matching the pattern already used elsewhere in the file.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:36:40 -07:00
Ishaan Jaffer
9be7b4c07c
test(advisor): add integration tests for full dispatch path, max_uses, provider bypass 2026-04-11 18:16:56 -07:00
Ishaan Jaffer
fa5258466d
test(advisor): add unit tests for max_uses=0, missing model, default fallback 2026-04-11 18:16:56 -07:00
Ishaan Jaffer
844e34b68b
test(advisor): remove live e2e test file (tests run locally via script) 2026-04-11 17:52:06 -07:00
Ryan Crabbe
3d72e2a6f3
fix(guardrails): address PR #25575 review feedback + sync kill switch with opt-out list
Renames the new per-guardrail opt-out field from `disabled_global_guardrails`
to `opted_out_global_guardrails` to eliminate the one-character collision with
the legacy `disable_global_guardrails` boolean kill switch. Adds a type guard
on the new gate so a misnamed bool can't crash the guardrail check. Filters
duplicates out of the team-edit guardrail display for legacy teams that have a
global name persisted in `metadata.guardrails` from before this PR. Drops the
unused `isGuardrailsLoading` and `guardrailsError` destructures left in
AddModelForm after the hook refactor.

Adds Python tests for the new gate behavior (root, litellm_metadata, metadata,
non-matching name, empty list, malformed bool value, opt-in coexistence) and
extends useGuardrails.test.ts to exercise the global / optional partition
logic that the rebuilt hook performs in its `select` transform.

Wires the legacy kill switch and the new opt-out list together in the team
edit form so they can never fall out of sync:

- Toggling the kill switch reactively updates the Guardrails Select via
  `onValuesChange` — switch on strips all globals from the selection, switch
  off re-adds them. Existing opt-in extras are preserved either way.
- When the switch is on, global options in the Select are individually
  disabled (greyed out) so the user can still manage opt-in guardrails but
  cannot accidentally re-enable a global the kill switch is bypassing.
- The save handler writes both fields together: `disable_global_guardrails`
  reflects the switch, and `opted_out_global_guardrails` is set to either
  every global (when the switch is on) or the user's explicit opt-outs.
- `effectiveGuardrails` for the form's initialValues honors the kill switch
  on legacy teams so the form opens in a state that matches what the runtime
  gate is actually doing — fixes the visual lie where chips appeared active
  while the switch was bypassing them.

The backend gate already reads the list as the primary path with the bool
as a fallback, so untouched legacy teams keep working until they get edited,
at which point they migrate naturally.
2026-04-11 17:48:16 -07:00
Ishaan Jaffer
742e2fe1aa
test(advisor): add live e2e tests for advisor orchestration against real proxy 2026-04-11 17:46:17 -07:00
Ishaan Jaffer
ce3d039bcd
test(advisor): add unit tests for orchestration loop (mocked backends, 8 tests) 2026-04-11 17:43:26 -07:00
Ryan Crabbe
ef38c665ca
fix(guardrails): use plural key in get_disable_global_guardrail
Rename disable_global_guardrail → disable_global_guardrails to match
the key name used by litellm_pre_call_utils.py, the API endpoints,
and the UI when propagating key/team metadata.

The singular form was introduced in PR #16983 and has never matched
the plural form written by the rest of the codebase, so the feature
silently did nothing.

Re-applies fix originally from #25488. Original commit could not be
merged due to missing signature.

Co-Authored-By: Remi Mabon <remi.mabon@redcare-pharmacy.com>
2026-04-11 17:35:50 -07:00
Yuneng Jiang
909247785e
Merge remote-tracking branch 'origin' into litellm_internal_staging_04_11_2026 2026-04-11 15:41:03 -07:00
yuneng-jiang
9a43e32d6e
Merge pull request #25464 from BerriAI/litellm_passthrough_contenttype
fix(proxy): pass-through multipart uploads and Bedrock JSON body
2026-04-11 15:40:16 -07:00
yuneng-jiang
56e82451df
Merge pull request #25458 from BerriAI/litellm_team_members_logs
Team member permission /spend/logs for team-wide spend logs (UI + RBAC)
2026-04-11 13:55:00 -07:00
ishaan-berri
da75012a50
Merge pull request #25569 from BerriAI/litellm_harish_april11
Litellm harish april11
2026-04-11 13:26:18 -07:00
yuneng-jiang
150c37c47d
Merge pull request #25568 from BerriAI/litellm_yj_apr_10_2026
[Infra] Merge dev with main
2026-04-11 13:03:52 -07:00
Yuneng Jiang
218daca867
[Fix] Address Greptile review: POST /organization/info auth bypass, inline imports, team access denial tests
- Add _verify_org_access to deprecated POST /organization/info endpoint
- Move get_user_object to module-level import in organization_endpoints.py
- Add tests for _verify_team_access 403 denial path
2026-04-11 12:40:55 -07:00
ishaan-berri
c70a3c7093
Merge pull request #25450 from harish876/oom-file-fix-openai
Add file content streaming support for OpenAI and related utilities
2026-04-11 12:25:36 -07:00
ishaan-berri
5cb9b087ad
Merge pull request #25545 from BerriAI/litellm_ishaan_april10
Litellm ishaan april10
2026-04-11 12:14:08 -07:00
Ishaan Jaffer
d22a07a9ba
Merge remote-tracking branch 'origin/main' into ci-fix-april6-fixes 2026-04-11 12:04:14 -07:00
harish876
69eb34597c Refactor file content streaming handling to improve routing and support
- Introduced a new method in `FileContentStreamingHandler` to resolve streaming request parameters, enhancing the routing logic based on credentials.
- Updated the `should_stream_file_content` method to check against supported providers.
- Cleaned up type hints and imports across multiple files for better organization and clarity.
- Added comprehensive tests to validate the new routing behavior and ensure original data integrity during streaming requests.
2026-04-11 18:56:15 +00:00
Yuneng Jiang
92bbf0a0d3
Merge remote-tracking branch 'origin' into litellm_oss_staging_04_09_2026 2026-04-11 11:52:42 -07:00
ryan-crabbe-berri
eabb6a31f1
Merge pull request #25542 from BerriAI/litellm_fix-timestamp
fix(spend): session-TZ-independent date filtering for spend/error log queries
2026-04-11 10:57:25 -07:00
shreyes19
f686d33408 refactor: extract _get_cors_config() for testability, fix no-op CORS tests 2026-04-11 22:24:04 +05:30
michelligabriele
363f9fe5da
fix(proxy): preserve dict guardrail HTTPException.detail + bedrock context (#25558) 2026-04-11 09:40:39 -07:00
jimmychen-p72
2fe615b373
fix(s3): add retry with exponential backoff for transient S3 503/500 errors (#25530)
* fix(s3): add retry with exponential backoff for transient S3 503/500 errors

S3 occasionally returns 503 "Slow Down" during PUT operations when
request rates spike above partition limits. The current code makes a
single upload attempt via httpx — unlike boto3, httpx has no built-in
retry for transient S3 errors. Failed uploads permanently lose the
request's audit/logging data.

Add exponential backoff retry (3 attempts, 1s/2s delays) for S3
500/503 responses in both async_upload_data_to_s3 and
upload_data_to_s3. Logs a warning on each retry with the S3 object
key for observability.

In production we observed ~18 permanent S3 upload failures per day
(124 over 7 days) — all transient 503s that would have succeeded on
a single retry.

* test(s3): add unit tests for S3 upload retry logic

Tests cover:
- Async retry on 503 (succeeds on second attempt)
- Async retry on 500
- Exhausted retries on persistent 503 (calls handle_callback_failure)
- No retry on 4xx errors (403)
- Sync retry on 503

* style(s3): move time import to module level

Address review feedback: move `import time` from inside
upload_data_to_s3 to the top-level imports per project style guide.
2026-04-11 09:39:12 -07:00
Josh
7d2f069361
Reduce default latency histogram bucket cardinality (#25527)
* feat(prometheus): reduce default latency bucket cardinality and make configurable

* test(prometheus): add coverage for PrometheusServicesLogger latency buckets

* Revert "test(prometheus): add coverage for PrometheusServicesLogger latency buckets"

This reverts commit 1bfd004ad1.

* test(prometheus): add coverage for PrometheusServicesLogger latency buckets
2026-04-11 09:34:45 -07:00
michelligabriele
c9e4949485
fix(logging): preserve proxy key-auth metadata on /v1/messages Langfuse traces (#25448)
* fix(logging): preserve proxy key-auth metadata on /v1/messages Langfuse traces

update_from_kwargs() overwrites proxy metadata (user_api_key_hash, etc.)
with Anthropic's native metadata when both exist. Merge instead of replace.

* fix(test): update stale assertion for new metadata merge semantics

* test: add explicit conflict-resolution test for metadata merge
2026-04-11 09:29:34 -07:00
shreyes19
e01fe01d35 fix: address Greptile P1 review comments 2026-04-11 21:57:03 +05:30
Sameer Kankute
d03ecedba1
feat(containers): Azure routing, managed container IDs, delete response parsing (#25287)
* feat(containers): Azure container routing, managed IDs, and delete response wire format

- Add AzureContainerConfig and safe URL joining for paths with api-version query
- Encode/decode managed container IDs in responses, streaming, and proxy handlers
- Accept OpenAI delete response object literal container.file.deleted
- Tests for Azure URL regression and DeleteContainerFileResponse parsing

Made-with: Cursor

* fix(responses): gate response id update on parsed_chunk having response

Delta stream events do not include a response body; Mock-based tests
(and any truthy synthetic .response on transforms) must not trigger
_update_responses_api_response_id_with_model_id. Fixes
test_stop_async_iteration_not_logged_as_failure (TypeError: Mock not iterable).

Made-with: Cursor

* feat(containers): encode container IDs in SDK responses for routing

- Add ContainerRequestUtils.encode_container_id_in_response utility
- Encode container_id in create/retrieve/delete responses (SDK path)
- Fix streaming iterator: gate response ID update on parsed_chunk key
- Follows responses API pattern (encode after handler, not in handler)

Made-with: Cursor

* fix(containers): module-level imports and managed cntr_ ID encoding

- Move ResponsesAPIRequestUtils imports to module scope (utils, main, handler_factory).
- Serialize absent model_id as empty segment instead of literal None; decode empty
  and legacy "None" segments as missing for router affinity.
- Add unit tests for build/decode round-trip and legacy IDs.

Made-with: Cursor

* fix(containers): decode managed IDs in endpoint_factory SDK path

- Add decode_managed_container_id_for_request in containers/utils and reuse from main.
- Strip LiteLLM cntr_ wrappers before generic_container_handler (64-char API limit).
- Resolve provider for logging/errors; add unit test for decode helper.
- Use resolved_custom_llm_provider after decode for mypy-safe provider typing.

Made-with: Cursor

* Fix p1 concern

* Fix p1 concern
2026-04-11 09:21:01 -07:00
Yuneng Jiang
83c459225c
[Fix] CI: fix GHA timeouts and uv lock --check failures
1. exclude-newer: change from absolute "2026-04-10" to relative "3 days".
   All pinned deps were published before the 3-day cutoff. Re-locked so
   uv lock --check passes in test-mcp.yml and test-linting.yml.

2. test_eager_tiktoken_load: run all 10 env var values in a single
   subprocess instead of spawning 10 separate processes. Each cold
   import litellm takes ~78s on CI, so the old loop took ~13 min on a
   single xdist worker. Now takes ~78s total.

3. proxy-db remaining timeout: increase from 20 to 30 minutes. The
   remaining group has 51 test files and was consistently timing out at
   71% across all branches (pre-existing issue, not migration-related).
2026-04-11 09:04:49 -07:00
Sameer Kankute
40d8a25df9
feat(bedrock): skip dummy user continue for assistant prefix prefill (#25419)
When modify_params is true, Bedrock Converse setup no longer prepends or
appends the default user message if the boundary assistant turn has
prefix: true, so OpenAI-style assistant prefill reaches the API unchanged.

Made-with: Cursor
2026-04-11 09:04:15 -07:00
Sameer Kankute
c13be44e44
feat(guardrails): optional skip system message in unified guardrail inputs (#25481)
* feat(guardrails): optional skip system message in unified guardrail inputs

Made-with: Cursor

* feat(dashboard): skip_system_message_in_guardrail in guardrail UI

Add a tri-state control (inherit / yes / no) when creating or editing
guardrails so admins can set litellm_params.skip_system_message_in_guardrail
without YAML. Table edit merges existing litellm_params before PUT to avoid
wiping content-filter and other provider fields.

Document the dashboard flow in the guardrails quick start with a screenshot.

Made-with: Cursor

* fix(guardrails): type structured_messages as AllMessageValues for mypy

Use AllMessageValues in openai_messages_without_system and cast adapter
request messages so GenericGuardrailAPIInputs matches TypedDict.

Made-with: Cursor
2026-04-11 08:53:24 -07:00
Sameer Kankute
dc200c34a2
fix(responses): map refusal stop_reason to incomplete status in streaming (#25498)
* fix(responses): map refusal stop_reason to incomplete status in streaming

Fixes streaming responses API translation where Anthropic's stop_reason="refusal"
was incorrectly translated to status="completed" instead of "incomplete".

Root cause: build_base_response was unconditionally overwriting finish_reason
with None from later chunks, losing the terminal content_filter value.

Changes:
- streaming_chunk_builder_utils: skip None finish_reason values in build_base_response
- streaming_iterator: snapshot chunks before returning pending events (sync path)
- streaming_handler: treat usage-only chunks as meaningful content
- transformation: map finish_reason=refusal to status=incomplete
- tests: add regression tests for refusal handling

Made-with: Cursor

* Fix test
2026-04-11 08:48:15 -07:00
shreyes19
519095bfe5 test: add structural proxy_server CORS invariant test (Greptile review feedback)
Add test_proxy_server_cors_invariant which directly imports and checks the
module-level origins and allow_cors_credentials variables in proxy_server.py.
This catches any future drift between the mirror helper and the real code.
2026-04-11 21:13:04 +05:30
shreyes19
e079ee779f fix: harden CORS, create_views exception handling, and spend log cleanup loop
- proxy_server.py: disable allow_credentials when allow_origins=['*'] (wildcard
  + credentials is a browser security misconfiguration). Add LITELLM_CORS_ORIGINS
  env var to configure explicit allowed origins.
- create_views.py: narrow broad 'except Exception' to only catch genuine
  'view does not exist' errors; re-raise all other DB errors (auth, connection,
  etc.) that were previously silently swallowed.
- spend_log_cleanup.py: validate execute_raw() return type is int before using
  it as a deletion count; break loop safely on unexpected types to prevent
  infinite deletion loops.
2026-04-11 18:58:04 +05:30
Yuneng Jiang
d9a460277a
[Fix] CI: fix uv lock resolution and tiktoken test timeout
1. Cap requires-python to <3.14 — no deps ship 3.14 wheels yet, and
   uv's cross-version resolver fails on the Python 3.14 split.
2. Change exclude-newer from relative "30 days" to absolute "2026-04-10"
   so the lockfile stays reproducible. The relative date caused
   cryptography==46.0.7 (published April 8) to fall outside the window.
3. Parametrize test_eager_loading_env_var_values instead of looping —
   with xdist the 6 subprocess cases can run in parallel instead of all
   running sequentially on one worker (~13 min → ~2 min).
   Also removed redundant case variants (Yes/YES/On/ON) that test the
   same str_to_bool code path.
2026-04-10 22:21:15 -07:00
Yuneng Jiang
09ffc87734
fix: align org and team endpoint permission checks with existing patterns
Brings organization info and team management endpoints in line with the
access-control patterns used elsewhere in the proxy.
2026-04-10 22:17:05 -07:00