Commit graph

39204 commits

Author SHA1 Message Date
Ishaan Jaff
6a0f04c8f3
fix(cloud-agents): stop trusting X-Forwarded-Host in install URL (Greptile P1)
Resolution order for the URL embedded in the install one-liner is now:

  1. LITELLM_CLOUD_AGENT_PROXY_BASE_URL env var (operator-configured,
     fully trusted) — recommended for production.
  2. X-Forwarded-Host / X-Forwarded-Proto, ONLY when the operator
     opts in via LITELLM_TRUST_PROXY_HEADERS=1.
  3. The request's direct Host header — safe by default because it
     reflects the actual TCP destination, not an attacker-supplied hop.

Previously any authenticated caller could forge X-Forwarded-Host to
embed an attacker-controlled URL in the install command. If a second
operator ran that command, the worker would send its raw pair token to
the attacker's host, who could then call POST /v2/agent-workers/register
and gain a long-lived worker JWT.

Also adds structured logging on /register failures (invalid / replayed
/ expired tokens) so operators running the proxy behind a WAF / fail2ban
can detect abuse at the network layer (the proxy itself doesn't ship a
built-in per-IP limiter).
2026-05-06 15:31:35 -07:00
Ishaan Jaff
0a942c2ed8
test(cloud-agents): _aws_mock_enabled defaults off and only "1" enables it
Locks the production-safe default for LITELLM_CLOUD_AGENT_MOCK_AWS so a
future revert to the unsafe "1" default trips CI. Also covers the
strict-string parsing — typos like "true" / "yes" must NOT silently
flip on the mock.
2026-05-06 15:31:22 -07:00
Ishaan Jaff
a9cd1fc764
fix(cloud-agents): default LITELLM_CLOUD_AGENT_MOCK_AWS to off (Greptile P1)
Previously the test-connection endpoint defaulted to mock-on, so a fresh
production proxy would silently return a synthetic success for any
non-empty AWS access key. Operators saving incorrect credentials would
only discover the failure later when VMs failed to launch.

Default is now "0" — operators must set LITELLM_CLOUD_AGENT_MOCK_AWS=1
explicitly to opt into the mock path during local development.

Also adds an inline comment on _build_update_payload's `is not None`
guard so a future contributor doesn't silently drop `False` / `0`
updates by switching to truthy comparison.
2026-05-06 15:31:17 -07:00
Ishaan Jaff
793e769bd5
test(cloud-agents): pin shell-quoting behavior for install command
Adds three regression cases that fail if a future change drops the
shlex.quote() pass on proxy_url, raw_token, or install_script_url. The
existing simple-input cases still pass unchanged because shlex.quote
returns alnum/colon/slash/dot strings verbatim.
2026-05-06 15:31:08 -07:00
Ishaan Jaff
e4cce78b6e
fix(cloud-agents): shell-quote install command interpolations (Greptile P1)
shlex.quote() the install_script_url, proxy_url, and raw_token before
interpolating into the curl-pipe-sh one-liner. Without quoting, a
proxy_url containing spaces or shell metacharacters (e.g. via a misconfig
or the X-Forwarded-Host issue Greptile also flagged) could produce a
malformed or exploitable command on the worker box.
2026-05-06 15:31:02 -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-berri
c15718f9d1
Fix Anthropic streaming reasoning token usage (#27319)
* fix anthropic streaming reasoning token usage

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

* test anthropic streaming reasoning usage end to end

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

* address anthropic reasoning token text split

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

* harden anthropic reasoning usage for mocked tokens

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 15:28:22 -07:00
ishaan-berri
bd1a05aed9
Fix MCP DB reload partial failures (#27314)
* Fix MCP database reload partial failures

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

* Avoid staged MCP registry exposure

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 15:18:18 -07:00
ishaan-berri
924c141843
Add new chat model metadata (#27313)
* add new model metadata

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

* address 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 15:15:21 -07:00
Ishaan Jaffer
45b1336115
test(cloud-agents): write-only secret invariants (LIT-2891 validation #2) 2026-05-06 15:14:22 -07:00
Ishaan Jaffer
d384bb757f
test(cloud-agents): pair token + worker JWT helper tests (LIT-2891 validation #5) 2026-05-06 15:14:22 -07:00
Ishaan Jaffer
2c3b4fd397
test(cloud-agents): scope filter unit tests (LIT-2891 validation #3) 2026-05-06 15:14:15 -07:00
Ishaan Jaffer
6ae896ac40
test(cloud-agents): scaffold agent_settings_endpoints test package 2026-05-06 15:14:15 -07:00
Ishaan Jaffer
6848a17fa4
fix(ui/agents): drop @ant-design/icons from ToolCallCard
@ant-design/icons isn't a direct dependency of the dashboard. Use a
text glyph (▸/▾) instead — keeps the toggle visible without adding
a runtime import.
2026-05-06 15:12:13 -07:00
Ishaan Jaffer
5f2c518dd2
fix(ui/agents): swap AgentDetail to typed dayjs helper 2026-05-06 15:12:11 -07:00
Ishaan Jaffer
62ccc79a4c
fix(ui/agents): swap SessionRow to typed dayjs helper 2026-05-06 15:12:09 -07:00
Ishaan Jaffer
15bb07d1fb
fix(ui/agents): swap AgentList to typed dayjs helper
Optional-chaining dayjs(...).fromNow?.() was a TS error because the
relativeTime plugin wasn't loaded. Use relativeOrAbsolute() from the
shared helper instead.
2026-05-06 15:12:08 -07:00
Ishaan Jaffer
d75651912e
feat(ui/agents): add _dayjs helper with relativeTime plugin
Centralizes dayjs.extend(relativeTime) so fromNow() is typed and
loaded across the agents components. relativeOrAbsolute() falls back
to '—' for null/invalid timestamps so callers don't have to
re-implement the guard.
2026-05-06 15:12:06 -07:00
Ishaan Jaffer
f6e5951556
test(agent_session_endpoints): validate cleanup sweeper for expiry/dead-daemon/stuck-runs (LIT-2877 #13) 2026-05-06 15:10:37 -07:00
Ishaan Jaffer
6a815d2b1f
test(agent_session_endpoints): validate JWT scope/exp/cross-session/terminated rejection (LIT-2877 #12) 2026-05-06 15:10:35 -07:00
Ishaan Jaffer
306df1aecc
test(agent_session_endpoints): validate cascade delete + provider.terminate (LIT-2877 #11) 2026-05-06 15:10:34 -07:00
Ishaan Jaffer
5e93b44177
test(agent_session_endpoints): validate cross-tenant isolation at all 3 levels (LIT-2877 #10) 2026-05-06 15:10:32 -07:00
Ishaan Jaffer
3f60ae6a90
test(agent_session_endpoints): validate session + run idempotency (LIT-2877 #9) 2026-05-06 15:10:31 -07:00
Ishaan Jaffer
1b481e4949
test(agent_session_endpoints): validate SSE resume + Last-Event-ID header (LIT-2877 #8) 2026-05-06 15:10:29 -07:00
Ishaan Jaffer
8feafae5b9
test(agent_session_endpoints): validate concurrent run-create returns 409 run_busy (LIT-2877 #7) 2026-05-06 15:10:28 -07:00
Ishaan Jaffer
42d8fdb741
test(agent_session_endpoints): validate /followup smart inject vs new-run (LIT-2877 #6) 2026-05-06 15:10:26 -07:00
Ishaan Jaffer
1567c00c20
test(agent_session_endpoints): validate run state transitions + cancel (LIT-2877 #5) 2026-05-06 15:10:25 -07:00
Ishaan Jaffer
a271a73276
test(agent_session_endpoints): validate session state transitions (LIT-2877 #4) 2026-05-06 15:10:23 -07:00
Ishaan Jaffer
46266b1dd3
test(agent_session_endpoints): validate agent reused across sessions (LIT-2877 #3) 2026-05-06 15:10:22 -07:00
Ishaan Jaffer
1801c1cf15
test(agent_session_endpoints): add in-memory Prisma fake + multi-tenant TestClient fixtures 2026-05-06 15:10:21 -07:00
Ishaan Jaffer
b483dbe7e9
test(agent_session_endpoints): add package marker 2026-05-06 15:10:19 -07:00
Ishaan Jaffer
be5ac1885a
test(e2e/agents): add tenant-isolation spec for Validation #8
Exercises the auth gate plumbing — present a fake token, navigate, then
swap to a fresh token and reload. Real backend partitioning is gated
on Epic A; the spec is structured so its assertions can be tightened
once the real /v2/ endpoints land.
2026-05-06 15:09:35 -07:00
Ishaan Jaffer
f6b2dda923
test(e2e/agents): add terminal-tab spec for Validation #7
Switch to the Terminal tab; mock streamer emits a terminal_chunk with
ANSI red. Assert the rendered span has computed color rgb(255, 0, 0).
2026-05-06 15:09:32 -07:00
Ishaan Jaffer
fac72a5362
test(e2e/agents): add composer spec for Validation #6
Type a message, send; assert the user_message bubble count strictly
grows. Mock provider acks the user_message synchronously — that's
enough to verify the composer plumbing without Epic A.
2026-05-06 15:09:27 -07:00
Ishaan Jaffer
36ac39d3af
test(e2e/agents): add sse-reconnect spec for Validation #5
Mid-stream, page.context().setOffline(true)/(false); event count never
regresses and continues climbing after reconnect. Exercises the seq
dedup branch of useSessionEventStream.
2026-05-06 15:09:24 -07:00
Ishaan Jaffer
50b2ad9482
test(e2e/agents): add live-stream spec for Validation #4
Inside a session, poll until ≥3 events have rendered in the conversation
pane (combination of message bubbles and tool-call cards). Mock provider
ticks every 400ms so this lands well under the 10s budget.
2026-05-06 15:09:22 -07:00
Ishaan Jaffer
bf6017a5b7
test(e2e/agents): add create-session spec for Validation #3
From /agents/{aid}, click + New Session, fill repo URL; assert the URL
redirects into the three-pane view and the status pill shows
'provisioning'.
2026-05-06 15:09:16 -07:00
Ishaan Jaffer
f4e29c1c74
test(e2e/agents): add create-agent spec for Validation #2
Open New Agent dialog, fill name + model, submit; assert the new row
shows up in the table within 5s. Definition only — no VM.
2026-05-06 15:09:14 -07:00
Ishaan Jaffer
9b3b656671
test(e2e/agents): add list-agents spec for Validation #1
Routes load — /agents, /agents/{aid}, /agents/{aid}/sessions/{sid}
each render their primary container. Captures console errors and
asserts none on the list view.
2026-05-06 15:09:11 -07:00
Ishaan Jaffer
cc96c81e4b
test(e2e/agents): add shared _helpers (fake JWT + auth cookie)
useAuthorized requires an unexpired JWT in the `token` cookie before it
renders. We mint an unsigned 1-hour token here — jwt-decode never
verifies the signature, so any structurally valid base64 payload works.
Helper plus an AGENTS_DEV_URL constant (overridable via env).
2026-05-06 15:09:05 -07:00
Ishaan Jaffer
ffd37b7ed8
test(e2e/agents): add e2e:agents npm script
Wraps the agents-suite Playwright config so it can run alongside the
existing e2e suite without colliding on globalSetup.
2026-05-06 15:09:02 -07:00
Ishaan Jaffer
59e1293c10
test(e2e/agents): add Playwright config for cloud-agents suite
Targets http://localhost:3000 (Next.js dev server) directly. The agents
UI lives in App Router routes which only render under `next dev`, not
the proxy's static export — separate config skips the proxy globalSetup
that the rest of the suite needs.
2026-05-06 15:09:00 -07:00
Ishaan Jaffer
3c4065b36c
feat(cloud-agents): wire vm-config/secrets/workers/pool-status routers in proxy_server 2026-05-06 15:08:18 -07:00
Ishaan Jaffer
430a39bbfd
feat(cloud-agents): add /v2/agent-vm-pool/status stub (real impl owned by LIT-2890) 2026-05-06 15:08:14 -07:00
Ishaan Jaffer
fd3b3637ac
feat(cloud-agents): add /v2/agent-workers register/list/revoke endpoints 2026-05-06 15:06:37 -07:00
Ishaan Jaffer
75ef38573a
feat(cloud-agents): add /v2/agent-secrets CRUD endpoints (write-only values) 2026-05-06 15:05:44 -07:00
Ishaan Jaffer
aae137ad00
feat(ui/agents): add /agents/[agent_id]/sessions/[session_id] route page
Three-pane session view. Resolves auth via useAuthorized and passes
the agent_id + session_id params to ThreePane.
2026-05-06 15:05:42 -07:00
Ishaan Jaffer
f990d6a1b7
feat(ui/agents): add /agents/[agent_id] route page
Per-agent landing page. Resolves auth via useAuthorized and passes the
agent_id param to AgentDetail.
2026-05-06 15:05:40 -07:00