Commit graph

39211 commits

Author SHA1 Message Date
Ishaan Jaffer
119db234e0
fix(warm_pool): import build_vm_provider directly (factory has no get_vm_provider alias) 2026-05-06 17:14:43 -07:00
Ishaan Jaffer
2e9421e9d9
fix(schema): restore LiteLLM_AgentVM table from B2 (lost during conflict resolution) 2026-05-06 17:11:55 -07:00
Ishaan Jaffer
c6ec1a8ec6
merge: integrate B0 (LIT-2888) — EC2 spike 2026-05-06 16:48:00 -07:00
Ishaan Jaffer
06d6073586
merge: integrate E (LIT-2881) — Admin UI three-pane dashboard 2026-05-06 16:47:59 -07:00
Ishaan Jaffer
84cfae0220
merge: integrate D (LIT-2880) — TS SDK with snake↔camel transform 2026-05-06 16:47:58 -07:00
Ishaan Jaffer
0e371e2fbb
merge: integrate B2 (LIT-2890) — warm pool + LiteLLM_AgentVM tracking
reconcile: schema dedup B2's LiteLLM_AgentVMConfig/Secret/Worker (already in HEAD from G) — keep G's versions and add B2's new LiteLLM_AgentVM table.
2026-05-06 16:47:41 -07:00
Ishaan Jaffer
6dccf40e0e
merge: integrate Epic B (LIT-2878) — vm_providers, sweepers, AMI
Reconciliation:
- adopt B's richer base.py types (ProvisionContext, VMHandle, AwsCreds,
  Ec2Config, ProvisionError) as canonical; keep A's NoopVMProvider alias
  and the registry helpers (register_vm_provider, reset_vm_provider_registry)
  for tests.
- rename B's factory entry point from get_vm_provider to build_vm_provider so
  it doesn't collide with the runtime registry's get_vm_provider(name).
- update A's session_endpoints._provision_in_background to construct a
  ProvisionContext and call provider.provision(ctx); pass team_id from
  the caller's API key.
- update _terminate_session_internal to construct a VMHandle when a vm_id
  is recorded on the session row.
- extend B's NoopProvider with provision_calls/terminate_calls recording for
  backward compat with A's tests; accept either VMHandle-style or legacy
  keyword-style terminate args.
- de-duplicate LiteLLM_AgentVMConfig from all 3 schema.prisma files —
  G's (LIT-2891) version wins; B's stub at the top is collapsed to a
  comment pointing to G's section.
- delete B's 20260506220000_add_agent_vm_config migration (collides with
  G's 20260506220000_add_cloud_agent_settings_tables which already creates
  the table).
- rewrite team_config.py to read G's per-field encrypted columns
  (aws_access_key_id_enc, aws_secret_access_key_enc, aws_region) instead
  of B's single-blob aws_creds_enc; rewrite test_team_config.py to match.
2026-05-06 16:31:37 -07:00
Ishaan Jaffer
8a0f4203e7
merge: integrate litellm_lit-2891-settings-ui-cloud-agents into cursor-sdk-integration
Resolved schema conflicts in schema.prisma, litellm/proxy/schema.prisma,
and litellm-proxy-extras/litellm_proxy_extras/schema.prisma by unioning
A's agent/session/run/event tables with G's VM config / secrets /
worker / pairing-token tables. Both sets of tables now coexist.
2026-05-06 16:16:03 -07:00
Ishaan Jaffer
92bc874efc
merge: integrate litellm_lit-2877-proxy-api-surface into cursor-sdk-integration 2026-05-06 16:12:56 -07:00
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 Jaffer
ecf62c5fa8
test(cascade_delete): regression test for status-based cascade filter
Greptile P3 (regression coverage): the cascade filter in
delete_agent was changed from terminated_at is None to
status not in SESSION_TERMINAL_STATUSES in commit a0015e8564.
Add an explicit test that exercises the bug surface — a session
flipped to error (terminal) but with terminated_at deliberately
left None. The legacy filter would have re-terminated it; the
status-based filter must skip it.
2026-05-06 16:10:00 -07:00
Ishaan Jaffer
7561b4b9b8
test(warm-pool): real-cloud P95 latency gate (slow-marked, validation #2) 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
371893df6d
test(warm-pool): unit tests for race-safe attach (concurrent CAS) 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
9f5dbc81d8
test(warm-pool): unit tests for hydrate payload builder + scope filtering 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
1e8c1e9c13
test(warm-pool): unit tests for maintenance loop refill/reap/shrink 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
3c345b4220
test(warm-pool): test package marker 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
a356b2f81b
test(agent_session): RecordingNoopProvider tracks provision/terminate calls; warm-pool tables in fake DB 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
d955639aa9
fix(vm_providers): registry adapter threads session_id into terminate metadata for tests 2026-05-06 16:05:04 -07:00
Ishaan Jaffer
a1aaf55e45
test(agent_session_endpoints): regression tests for narrowed seq-collision catch
Asserts:
  * _is_seq_collision matches RuntimeError('event_seq_collision') and
    prisma.errors.UniqueViolationError, but rejects unrelated errors.
  * Real collision: insert at seq=N when seq=N already exists, retry
    at N+1 succeeds (no 409 surfaced).
  * Unrelated DB outage: a non-collision RuntimeError propagates as
    itself, NOT misclassified as 409 event_seq_collision.

Greptile follow-up regression coverage.
2026-05-06 16:01:40 -07:00
Ishaan Jaffer
e489150883
test(cleanup_sweeper): assert session flips to ready after stuck-run sweep
Greptile P1 regression coverage. The sweeper test only checked
run.status == RUN_STATUS_ERROR, leaving the session-status gap
undetected. Add a force-busy step before the sweep + assert the
session transitions to ready after.
2026-05-06 16:01:32 -07:00
Ishaan Jaffer
124c73c1ed
fix(internal_endpoints): only treat seq-collisions as 409 in events:append retry
The seq-collision retry in daemon_append_event previously caught all
Exception types and re-raised them as 409 event_seq_collision. A
transient DB error during retry would surface to the daemon as a
misleading 409, hiding the real outage and the daemon would respond
incorrectly (they treat 409 as 'data conflict, drop the event' rather
than 'retry').

Add a narrow _is_seq_collision predicate that matches:
  * prisma.errors.UniqueViolationError (production)
  * RuntimeError('event_seq_collision') marker (test stand-in)

Other errors bubble up unchanged so callers can distinguish a real
seq conflict from a real outage.

Greptile (review #PRR_kwDOKALCgc78u_NS — overly broad exception
catch in seq-collision retry).
2026-05-06 16:01:25 -07:00
Ishaan Jaffer
164afd4a18
fix(cleanup): drive session busy->ready after sweeper reaps stuck run
_sweep_stuck_runs marks idle-timeout runs as error but never called
refresh_session_status_from_runs, leaving the parent session
permanently busy. Every other run-terminal path (cancel_run,
daemon_append_event, /followup) calls the helper to flip
busy -> ready; the sweeper was the only path that skipped it.

After flipping each run to error, call refresh_session_status_from_runs
inside the loop so a session whose only active run was reaped here
transitions back to ready.

Greptile P1 (review #PRR_kwDOKALCgc78u_NS, inline comment line 172).
2026-05-06 16:01:16 -07:00
Ishaan Jaffer
29146f012b
feat(daemon): warm-mode SIGUSR1 hydrate handler — apply payload to disk 2026-05-06 15:53:18 -07:00
Ishaan Jaffer
5351e9e6dd
feat(proxy_server): start/stop WarmPoolManager on lifespan events 2026-05-06 15:53:18 -07:00
Ishaan Jaffer
76d7d27448
feat(sessions): wire warm-pool attach into POST /v2/sessions hot path 2026-05-06 15:53:18 -07:00
Ishaan Jaffer
402602a4f4
feat(warm-pool): race-safe attach via update_many CAS on state column 2026-05-06 15:53:12 -07:00
Ishaan Jaffer
ff59d2512b
feat(warm-pool): SSM RunCommand hydrate transport (B0 1700ms median) 2026-05-06 15:53:12 -07:00
Ishaan Jaffer
05d9906687
feat(warm-pool): transports package __init__ 2026-05-06 15:53:12 -07:00
Ishaan Jaffer
cf8f240386
feat(warm-pool): async maintenance loop refills + reaps team pools 2026-05-06 15:53:11 -07:00
Ishaan Jaffer
92e8047805
feat(warm-pool): hydrate payload builder (decrypts in-scope secrets) 2026-05-06 15:53:11 -07:00
Ishaan Jaffer
eb12042802
feat(warm-pool): package __init__ exposing manager, attach, builder 2026-05-06 15:53:11 -07:00
Ishaan Jaffer
a143191c85
feat(warm-pool): HydratePayload Pydantic schema (LIT-2890) 2026-05-06 15:53:11 -07:00
Ishaan Jaffer
070028bbb1
feat(warm-pool): add Prisma migration for LiteLLM_AgentVM warm-pool table 2026-05-06 15:53:02 -07:00
Ishaan Jaffer
7a23f04849
test(agent_session_endpoints): regression tests for session busy/ready oscillation
Walks the SDK-visible session.status across:
  * POST /v2/sessions/{sid}/runs        — ready -> busy
  * POST /v2/sessions/{sid}/runs/{rid}/cancel — busy -> ready
  * POST /v2/sessions/{sid}/followup    — ready -> busy via /followup
  * Cancellation via /followup-created run — busy -> ready

Plus two helper tests:
  * idempotent (no-op when no transition is needed)
  * quiet on missing session (race with cascade delete)

Greptile P1 regression coverage.
2026-05-06 15:52:06 -07:00
Ishaan Jaffer
79642036e6
test(cleanup_sweeper): assert provider.terminate called for dead-daemon sessions
Greptile P1 regression coverage: dead-daemon sweep must route through
_terminate_session_internal so provider.terminate gets called. Without
this assertion the regression silently returned (NoopVMProvider would
still mark rows correctly via update_many).
2026-05-06 15:51:58 -07:00
Ishaan Jaffer
a0015e8564
fix(agent_endpoints): use status check (not terminated_at) for cascade filter
delete_agent's cascade filter previously used 'terminated_at is None'
to find non-terminal sessions. The fix is safe in practice because
_terminate_session_internal has its own SESSION_TERMINAL_STATUSES guard,
but it's inconsistent with the rest of the module which uses
'status in/notin SESSION_TERMINAL_STATUSES' everywhere else.

Switch to the status-based check to match.

Greptile P3 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:52 -07:00
Ishaan Jaffer
b7e971032b
fix(cleanup): route dead-daemon sweep through _terminate_session_internal
_sweep_dead_daemons previously ran update_many directly on the session
row, skipping provider.terminate. With NoopVMProvider this was harmless,
but once Epic B swaps in a real VM provider it would orphan EC2
instances every time a daemon stopped heartbeating.

Mirror the pattern from _sweep_expired_sessions: call
_terminate_session_internal per-row so the provider is notified, then
explicitly downgrade status from 'terminated' to 'error' (both are
terminal — no further state transitions). Also drops the per-run
update loop since _terminate_session_internal already cancels active
runs and emits run_cancelled events.

Greptile P1 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:45 -07:00
Ishaan Jaffer
6ec39988f4
fix(session_endpoints): drive session busy state on /followup new-run path
When /followup creates a fresh queued run (terminal-or-absent latest_run
branch), call refresh_session_status_from_runs so the session moves
'ready' -> 'busy'. Match the same hook added to POST /runs.

Greptile P1 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:36 -07:00
Ishaan Jaffer
b007da3dc9
fix(run_endpoints): drive session busy<->ready oscillation on run create/cancel
Two call sites added:
  * After POST /v2/sessions/{sid}/runs creates a queued run, call
    refresh_session_status_from_runs so the parent session moves
    'ready' -> 'busy'.
  * After POST /v2/sessions/{sid}/runs/{rid}/cancel marks a run
    cancelled, call the same helper so the session moves
    'busy' -> 'ready' if no other active runs exist.

Greptile P1 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:30 -07:00
Ishaan Jaffer
f3101be1a1
fix(internal_endpoints): drive session busy<->ready oscillation from daemon callbacks
Two call sites added:
  * After _claim_next_queued_run flips a queued run to running, call
    refresh_session_status_from_runs so a session that was 'ready'
    transitions to 'busy'. Idempotent for already-busy sessions.
  * After daemon_append_event finalizes a terminal event (run_finished /
    run_cancelled / run_error), call refresh_session_status_from_runs so
    a session with no remaining active runs transitions back to 'ready'.

Without these hooks, session.status stayed permanently 'busy' after the
first run started — clients polling GET /v2/sessions/{id} always saw
'busy' regardless of run state.

Greptile P1 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:24 -07:00
Ishaan Jaffer
f68869071b
feat(agent_session_endpoints): add session_status helper for busy/ready oscillation
Pure-function logic for the session status state machine already lives
in state_machine.derive_session_status_from_runs. This module is the
I/O wrapper that reads the session row, counts active runs, and
persists the new status only when the helper says it should change.

Used by every code path that flips a run's status:
  * POST /v2/sessions/{sid}/runs (queued -> session busy)
  * POST /v2/sessions/{sid}/followup (new run -> same)
  * GET  /v2/sessions/{sid}/runs/next/internal/poll (queued -> running)
  * POST /v2/sessions/{sid}/runs/{rid}/cancel (terminal -> ready)
  * POST /v2/sessions/{sid}/runs/{rid}/events:append (terminal -> ready)

Greptile P1 (review #PRR_kwDOKALCgc78u9En).
2026-05-06 15:51:16 -07:00
oss-agent-shin
b318231fe9
Add Azure Sentinel audit log support (#27280)
* Add Azure Sentinel audit log callback support

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

* Fix Azure Sentinel audit log batching

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

* Fix Azure Sentinel CI checks

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:50:06 -07:00
Ishaan Jaffer
30963452d4
fix(vm_providers): adapter bridges A1 keyword-style provision API to B1 ProvisionContext 2026-05-06 15:45:33 -07:00