Commit graph

39008 commits

Author SHA1 Message Date
Ishaan Jaffer
1b0ca087d4
test(agent-sdk): cover snake_case <-> camelCase transform helpers
Round-trip + edge-case coverage: digits in keys (agent_v2_id), nested
objects, arrays of objects, top-level arrays, single-word key passthrough,
and primitive passthrough.
2026-05-06 16:10:50 -07:00
Ishaan Jaffer
fb05cf0200
test(agent-sdk): switch removed Run.conversation() test to session.conversation()
Also update the wait() test to expect the new 'finished' terminal status.
2026-05-06 16:10:44 -07:00
Ishaan Jaffer
290808fa64
test(agent-sdk): expect 'finished' instead of 'completed' for terminal RunStatus 2026-05-06 16:10:39 -07:00
Ishaan Jaffer
f68bd10230
test(agent-sdk): mirror backend snake_case wire format and new status enums in mock proxy
Mock proxy now serializes responses using snake_case keys (agent_id,
created_at, system_prompt, run_id, etc.) and reads request bodies as
snake_case so it matches the real backend that the SDK now talks to via
the new transform layer. Also update the status string literals to the
new SessionStatus and RunStatus values, and read the followup body as
{prompt: {text}}.
2026-05-06 16:10:35 -07:00
Ishaan Jaffer
b65d494c39
refactor(agent-sdk): drop Run.conversation() and update terminal states
There is no per-run conversation endpoint on the backend; conversation
history is session-scoped. Callers should use SessionHandle.conversation()
instead. Also update TERMINAL_STATES to the new RunStatus values
(finished/cancelled/error).
2026-05-06 16:10:28 -07:00
Ishaan Jaffer
3ffaad8b1a
fix(agent-sdk): send {prompt: {text}} as followup body to match backend FollowupCreate
The backend's followup endpoint expects a FollowupCreate payload with a
nested prompt object ({prompt: {text: ...}}), not a flat {message: ...}.
Public method signature followup(message: string) is unchanged - only
the wire body changes.
2026-05-06 16:10:22 -07:00
Ishaan Jaffer
68e58bf69b
feat(agent-sdk): add snake_case <-> camelCase transform layer to HTTP client
Backend speaks snake_case (Python idiom) while the SDK's public TS API
is camelCase. Add recursive snakeToCamel and camelToSnake helpers and
wire them into the HTTP layer so request bodies are camel->snake before
JSON.stringify and response JSON is snake->camel before being returned
to callers. Single-word keys like id/type/data/seq/status pass through
unchanged in both directions, and non-object values are not touched.
2026-05-06 16:10:16 -07:00
Ishaan Jaffer
595f660899
fix(agent-sdk): align SessionStatus and RunStatus enums with backend wire values
Backend (LIT-2890) emits provisioning/ready/busy/error/terminated for
session status and queued/running/finished/cancelled/error for run status.
Update the SDK type aliases so callers compare against the actual values
the proxy returns over the wire.
2026-05-06 16:10:10 -07:00
Ishaan Jaff
6f3895b07c
fix(agent-sdk): cap honored Retry-After at 60s
Greptile P2: a misbehaving or adversarial server returning
'Retry-After: 9999999' could stall the SDK indefinitely. Cap the
honored delay at MAX_RETRY_AFTER_MS (60s).
2026-05-06 15:28:48 -07:00
Ishaan Jaff
642ba64635
fix(agent-sdk): reset SSE reconnect counter after a successful connection
Greptile P1: the reconnects counter accumulated across the entire
stream lifetime — for a long-running stream with several transient
drops over hours, the budget would be exhausted even though every
individual reconnect succeeded. Now the counter tracks *consecutive*
failures: once a connection delivers at least one new event, the
counter resets to zero on the next drop, so only a sustained outage
trips sse_reconnect_exhausted.
2026-05-06 15:28:42 -07:00
Ishaan Jaff
67cad5ea60
fix(agent-sdk): add timeout/abort support to Run.wait() and drop runFromInfo
Greptile P1: wait() polled indefinitely with no escape hatch — a stuck
or partitioned server would hang the caller forever. Now accepts
{ signal, timeoutMs, pollMs } and throws LiteLLMAgentError with codes
wait_aborted / wait_timeout. Forwards the signal to the underlying
requestJson call and to the inter-poll sleep.

Greptile P2: runFromInfo was exported but had no internal callers
(agent.ts and session.ts both build Run directly). Removed to shrink
the surface and avoid leaking resolveClient as a construction detail.
2026-05-06 15:28:35 -07:00
Ishaan Jaffer
db579303fd chore(agent-sdk): ignore package-lock.json (use pnpm) 2026-05-06 15:00:19 -07:00
Ishaan Jaffer
a371832337 test(agent-sdk): add Symbol.asyncDispose teardown test 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
66527b6beb test(agent-sdk): add session.followup queueing test 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
bd1539285a test(agent-sdk): add SSE auto-reconnect test 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
b4b6c109e7 test(agent-sdk): add agent-reuse multi-session test 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
4926177cfd test(agent-sdk): add noop-roundtrip end-to-end test 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
e3683ec956 test(agent-sdk): add Run class tests 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
4aae87bd08 test(agent-sdk): add SessionHandle tests 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
e31d20e93d test(agent-sdk): add Agent class tests 2026-05-06 14:59:56 -07:00
Ishaan Jaffer
93954fc5a0 feat(agent-sdk): add followup multi-turn example 2026-05-06 14:59:48 -07:00
Ishaan Jaffer
61e8a07314 feat(agent-sdk): add basic usage example 2026-05-06 14:59:48 -07:00
Ishaan Jaffer
2f0e1d7415 docs(agent-sdk): add README with quickstart and API reference 2026-05-06 14:59:48 -07:00
Ishaan Jaffer
f68b984fe2 chore(agent-sdk): tweak package.json repository URL 2026-05-06 14:59:43 -07:00
Ishaan Jaffer
1a9fbc63e6 fix: target /v2/ agent-session API 2026-05-06 14:59:21 -07:00
Ishaan Jaffer
49e30b020d
test(agent-sdk): add in-memory mock proxy for tests 2026-05-06 14:52:53 -07:00
Ishaan Jaffer
7ffe2bbdae
feat(agent-sdk): add public surface re-exports 2026-05-06 14:52:53 -07:00
Ishaan Jaffer
82c03fd68a
feat(agent-sdk): add Run class with stream/wait/cancel 2026-05-06 14:52:53 -07:00
Ishaan Jaffer
33eb658f8b
feat(agent-sdk): add SessionHandle with asyncDispose 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
25ffa570c1
feat(agent-sdk): add Agent + AgentHandle classes 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
a7c94022a5
feat(agent-sdk): add SSE client with Last-Event-ID resume 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
8e20ed5ef8
feat(agent-sdk): add fetch wrapper with auth + retry 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
f3965f652a
feat(agent-sdk): add public types and LiteLLMAgentError 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
6fa5f15782
feat(agent-sdk): add vitest config 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
8ffd32036f
feat(agent-sdk): add tsconfig 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
e214328730
feat(agent-sdk): add package.json for @litellm/agent-sdk 2026-05-06 14:52:52 -07:00
Ishaan Jaffer
504c90bad7
feat(agent-sdk): add gitignore for typescript SDK package 2026-05-06 14:52:42 -07:00
ishaan-berri
487479eff7
perf: cap Prometheus end-user metric cardinality with TTL + LRU eviction (#27272)
Co-authored-by: Yassin Kortam <yassinkortam@g.ucla.edu>
2026-05-06 13:35:13 -07:00
oss-agent-shin
c8e47dcb43
Fix early proxy request size enforcement (#27311)
* Add early proxy request size guard

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

* Address request size review feedback

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

---------

Co-authored-by: oss-agent-shin <279349115+oss-agent-shin@users.noreply.github.com>
Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>
2026-05-06 12:29:11 -07:00
Dibyo Mukherjee
169c436684
Fix/member access group team (#27317)
* fix(auth): pass team_id in member-level model access check

_check_team_member_model_access calls _can_object_call_model without
team_id, so access groups defined via model_info.access_groups cannot
resolve for team-scoped DB models (their internal router name is
model_name_<team>_<uuid>, not the public name). The team-level check
already passes team_id; this mirrors that.

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

* test(auth): add tests for member-level access group resolution with team_id

Eight tests covering _can_object_call_model and
_check_team_member_model_access with team-scoped DB models:

- access group resolves when team_id is passed
- access group fails without team_id (pre-fix behavior)
- literal model name still works with team_id (no regression)
- denied model still denied with team_id
- second model in group also reachable
- end-to-end member access via access group (mocked membership)
- end-to-end member denied for model not in allowed list
- no-override member inherits team-level check

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-06 12:05:22 -07:00
oss-agent-shin
d90cf56245
Fix SCIM user lookup filters (#27308)
* Fix SCIM Okta userName lookup

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

* fix scim user filter typing

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

---------

Co-authored-by: oss-agent-shin <279349115+oss-agent-shin@users.noreply.github.com>
Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>
2026-05-06 11:58:47 -07:00
ishaan-berri
c92a08a307
Fix team member budget enforcement without user row (#27273)
* Fix team member budget enforcement without user row

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

* Clarify regenerated key budget repro

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

---------

Co-authored-by: oss-agent-shin <279349115+oss-agent-shin@users.noreply.github.com>
Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>
2026-05-06 11:42:29 -07:00
Yassin Kortam
b1f577199a
fix(proxy): keep spend log cleanup running after batch failures and surface DB errors (#27303)
Co-authored-by: Yassin Kortam <yassinkortam@g.ucla.edu>
2026-05-06 18:39:15 +00:00
Mateo Wang
b83d11351f
proxy: hot-reload config YAML when --reload is set (#27274)
* proxy: hot-reload config YAML when --reload is set

Uvicorn's --reload only watches *.py by default, so editing the
--config YAML did not restart the proxy. _get_reload_options() now
extends reload_dirs/reload_includes with the config file's directory
and basename when --config is provided.

* proxy: qualify reload_includes with absolute config path

Address Greptile review on PR #27274. When the --config file lives
outside cwd, reload_includes previously stored only the basename, which
meant uvicorn/watchfiles would also reload on edits to any same-named
file inside cwd. Use the absolute config path as the include pattern in
that case so only the actual proxy config triggers a restart.

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>

* fix(proxy): use basename for reload_includes config pattern

Uvicorn's resolve_reload_patterns() calls pathlib.Path.glob(), which
raises NotImplementedError on absolute patterns (uvicorn discussion
2156). Passing config_abs (an absolute path) when the config file lived
outside cwd crashed startup under --reload. The config_dir is already
added to reload_dirs, so using just the basename as the include pattern
is sufficient to match the specific config file.

* fix: make it reload app when yaml changes

* style: remove unneeded comments

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>
2026-05-06 16:06:58 +00:00
Yassin Kortam
bd1ea0252a
perf(proxy): run daily activity aggregation off the event loop (#27264)
Some checks are pending
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Waiting to run
Unit Tests: Proxy DB Operations / auth-checks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / schema-migration (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests: Security / security (push) Waiting to run
Unit Tests: Caching (Redis) / caching-redis (push) Waiting to run
Co-authored-by: Yassin Kortam <yassinkortam@g.ucla.edu>
2026-05-05 20:19:28 -07:00
ishaan-berri
c32ad90823
Fix Prometheus custom metadata label counts (#27268) (#27271)
* Fix Prometheus custom metadata label counts (#27268)

Co-authored-by: oss-agent-shin <279349115+oss-agent-shin@users.noreply.github.com>
Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>

* fix enterprise test: update positional label assertions to keyword args

prometheus_label_factory now calls .labels() with keyword arguments.
Update test_async_log_failure_event assertion to match.

---------

Co-authored-by: oss-agent-shin <ext-agent-shin@berri.ai>
Co-authored-by: oss-agent-shin <279349115+oss-agent-shin@users.noreply.github.com>
Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>
2026-05-05 20:04:56 -07:00
ishaan-berri
e9fb29061a
Include model name + configured TPM/RPM in priority rate-limit 429 er… (#27216)
* Include model name + configured TPM/RPM in priority rate-limit 429 errors (#27215)

* Include model name + configured TPM/RPM in priority rate-limit 429 errors

The current 429 message ('Priority-based rate limit exceeded. Priority: prod,
Rate limit type: tokens, Remaining: -664145, Model saturation: 86.3%') doesn't
tell the operator which model was hit or what the configured limit is, so they
can't tell whether the priority allocation needs tuning or the model TPM is
just too small.

Add Model, Model TPM, and Model RPM to both the priority-based 429 and the
sibling Model-capacity 429 in dynamic_rate_limiter_v3._check_rate_limits.
Pure error-message change — no behavior or schema impact.

* test: assert priority 429 includes model name + configured TPM/RPM

Adds a regression test for the new fields in the priority-based 429 detail
('Model:', 'Model TPM:', 'Model RPM:'). Verified locally that the test
fails against the unpatched dynamic_rate_limiter_v3.py and passes after
the patch.

---------

Co-authored-by: shin-watcher <ext-agent-shin@berri.ai>

* Update litellm/proxy/hooks/dynamic_rate_limiter_v3.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update litellm/proxy/hooks/dynamic_rate_limiter_v3.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: shin-watcher <ext-agent-shin@berri.ai>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-05-05 19:05:22 -07:00
Dennis Henry
73de892654
fix: replace user api key auth with authorization or cookie for mcp server creation (#27190)
* fix: replace user api key auth with authorization or cookie for mcp server creation

* updated tests
2026-05-05 18:36:22 -07:00
Michael-RZ-Berri
e75c7a312a
union x-litellm-tags with static team/key tags (#27247)
Co-authored-by: Michael Riad Zaky <michaelr@Mac.localdomain>
2026-05-05 17:46:42 -07:00
Mateo Wang
fdaa288607
ci(circleci): enable Rerun Failed Tests for all pytest jobs (#27155)
* ci(circleci): enable Rerun Failed Tests for all pytest suites

Migrated every pytest-based CircleCI job that uploads JUnit results to use
'circleci tests run' instead of invoking pytest directly. This is the
prerequisite for CircleCI's 'Rerun failed tests' feature to be available
on each job in the pipeline.

For each job:
- Glob test files via 'circleci tests glob' and pipe them into
  'circleci tests run --command="xargs ... pytest ..."' so the agent can
  feed the failed-test subset on rerun.
- Preserve all original pytest flags (parallelism, timeouts, retries,
  coverage, junit output paths).
- For jobs that previously lacked 'store_test_results' (proxy spend
  accuracy, proxy_build_from_pip, db_migration_disable_update_check),
  add the step so JUnit XML is uploaded and rerun is actually wired up.
- Replace the dynamic IGNORE_DIRS shell array in llm_translation_testing
  with a 'grep -v' filter on the glob output, matching the previous
  behavior of skipping tests/llm_translation/realtime.
- For 'build_and_test', glob 'tests/test_*.py' (top-level only) which
  matches the prior 'tests/*.py' shell glob; the long list of
  '--ignore=tests/<subdir>' flags was vestigial and is dropped.

Jobs already using 'circleci tests run' (local_testing_part1/2,
litellm_router_testing) are unchanged.

* fix(ci): convert classnames to file paths on rerun

CircleCI's Rerun Failed Tests sends each previously failed test as a
JUnit classname (e.g. 'tests.otel_tests.test_key_logging_callbacks'),
but pytest needs a file path. Without the awk preprocess step, rerun
runs fail with 'file or directory not found'.

Mirror the awk transform that local_testing_part1, local_testing_part2,
and litellm_router_testing already use, so rerun works in every job
that this PR migrated to 'circleci tests run'.

* ci: drop -x from OTEL pytest run so all failures are reported

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-05-05 17:27:09 -07:00