Commit graph

39048 commits

Author SHA1 Message Date
Ishaan Jaffer
f2d8d78027
fix(v2 managed agents): apply default_user fallback in events SSE stream 2026-05-07 13:28:23 -07:00
Ishaan Jaffer
ab24b21209
fix(v2 managed agents): apply default_user fallback in messages handlers 2026-05-07 13:28:23 -07:00
Ishaan Jaffer
4521837bcb
fix(v2 managed agents): apply default_user fallback to GET /v2/sessions/:id 2026-05-07 13:28:23 -07:00
Ishaan Jaffer
79d6b0df5d
fix(v2 managed agents): encrypt litellm_api_key at rest + DB-level 409 backstop 2026-05-07 13:28:17 -07:00
Ishaan Jaffer
56a068de71
refactor(v2 managed agents): update sub-router imports to new package path 2026-05-07 13:28:12 -07:00
Ishaan Jaffer
d46de49d9d
refactor(v2 managed agents): update import path for managed_agents_router 2026-05-07 13:28:07 -07:00
Ishaan Jaffer
25cf9ceb51
refactor(v2 managed agents): move endpoints package into proxy/ for FastAPI rule 2026-05-07 13:27:46 -07:00
Ishaan Jaffer
7e0e4f1dfc
fix(v2 managed agents ui): only treat assistant in_progress as active
User messages from opencode have no completed_at and normalize to status=in_progress,
which made hasInProgress always true → Stop button stuck on. Filter to assistant-only.
2026-05-07 13:04:09 -07:00
Ishaan Jaffer
07315c47e9
ui(v2 managed agents): live updates, sticky composer, Enter sends, queued state
- Sidebar: removed nav items (New Agent, Automations, Dashboard, Bugbot)
- Search placeholder: 'Search sessions ⌘K'
- Composer is sticky at the bottom (outside scroll container) so the thread scrolls cleanly
- Enter sends; Shift+Enter inserts a newline (Cmd+Enter no longer required)
- Optimistic user message renders with a 'queued' spinner badge until the server confirms
- Always poll /v2/sessions every 5s so externally-created sessions appear in the rail without reload
- Always poll /messages (5s when idle, 2s when in_progress) so externally-sent messages appear without reload
- Auto-scroll only triggers when user is already near the bottom (no hijacking)
2026-05-07 12:55:14 -07:00
Ishaan Jaffer
eefa44f702
ui(v2 managed agents): cursor-style sessions UI — Inter font, Tailwind, lucide icons
- Sidebar: hamburger + search input, nav items (New Agent/Automations/Dashboard/Bugbot), session groups (Today/This Week/This Month/Older), active item with blue tinted bg + dot, user footer with avatar
- MainPanel: breadcrumb header agent / repo, max-w-720 thread, user messages as quoted prompt blocks (gray bg rounded-xl), flowing assistant markdown, tool calls as expandable cards with emerald check icon
- Composer: large bordered rounded-xl input, model name on left, dark circular Send (ArrowUp) or Stop (Square) on right
- Inter + JetBrains Mono via Google Fonts
2026-05-07 12:49:20 -07:00
Ishaan Jaffer
2ed9408ed3
ui(v2 managed agents): polish sessions UI — left rail, refined typography, dev-tool aesthetic
- sessions list as left rail (was full-page list view)
- group sessions by Today/This Week/Last Week/Older
- active row uses subtle bg (was 2px border)
- status dots only render for non-ready states
- header shows agent name from agentNameById fallback
- composer in rounded bordered container with consolidated footer
- stop button is filled-dark SVG square (was bold ascii character)
- markdown sizes tightened (h1 17px, h2 15px, h3 13.5px, body 13.5/1.6)
- user messages render as bold quote-headers with hairline separator
- redirect /sessions to latest session
2026-05-07 12:35:22 -07:00
Ishaan Jaffer
3e86ce0680
test(v2 managed agents): cover OpencodeAdapter.abort 2026-05-07 12:19:47 -07:00
Ishaan Jaffer
c32fd21e00
test(v2 managed agents): cover POST /v2/sessions/:id/abort endpoint 2026-05-07 12:19:45 -07:00
Ishaan Jaffer
81585d1171
test(v2 managed agents): cover GET /v2/sessions global listing 2026-05-07 12:19:45 -07:00
Ishaan Jaffer
a87ec3ff81
feat(v2 managed agents): add POST /v2/sessions/:id/abort endpoint 2026-05-07 12:19:40 -07:00
Ishaan Jaffer
ea3310af66
feat(v2 managed agents): implement abort in OpencodeAdapter (best-effort POST /abort) 2026-05-07 12:19:40 -07:00
Ishaan Jaffer
7e077657fc
feat(v2 managed agents): add abort method to SandboxAdapter Protocol 2026-05-07 12:19:35 -07:00
Ishaan Jaffer
fbd73ff970
feat(v2 managed agents): add GET /v2/sessions global listing endpoint 2026-05-07 12:19:34 -07:00
Ishaan Jaffer
b1afebe9d1
feat(v2 managed agents): add list_sessions DB helper for global session listing 2026-05-07 12:19:30 -07:00
Ishaan Jaffer
3a38f8eddb
test(v2 managed agents): drop unused monkeypatch fixture from same-name test
test_create_agent_same_name_different_user_returns_200 requested monkeypatch
but only used app.dependency_overrides. Pyright flagged the parameter as
unaccessed; remove it.
2026-05-07 12:08:18 -07:00
Ishaan Jaffer
cd5febf03d
fix(v2 managed agents): satisfy pyright on _row_to_agent_response config access
Use getattr with a None default and isinstance narrowing instead of hasattr to
unwrap prisma.Json-style configs. Pyright was flagging .data access on the
dict branch of the union; this rewrites the path so the type narrows cleanly
without an Any cast.
2026-05-07 12:08:12 -07:00
Ishaan Jaffer
9379f7f206
test(v2 managed agents): cover GET /v2/agents/:agent_id/sessions listing
Adds 9 tests: agent_id scoping (no leakage from other agents), unknown
agent 404, other-user agent 404, defense-in-depth created_by scoping,
internal sandbox_url/sandbox_metadata stripped from listing, 4-record
pagination walk, status filter, invalid cursor 422, db-not-connected 500.
2026-05-07 12:01:36 -07:00
Ishaan Jaffer
f278696a87
test(v2 managed agents): cover GET /v2/agents listing
Adds 7 tests: caller scoping, api_key masking, 4-record pagination walk
via cursor, empty result, invalid cursor 422, db-not-connected 500.
2026-05-07 12:01:30 -07:00
Ishaan Jaffer
7015d5e7fa
feat(v2 managed agents): add GET /v2/agents/:agent_id/sessions listing endpoint
Verifies agent ownership before listing (404 for unknown/unowned agents).
Sessions are scoped by created_by independent of the agent check, so a
mis-owned session row cannot leak. Optional ?status= filter, same offset
cursor as GET /v2/agents. sandbox_url and sandbox_metadata stripped per
contract \xc2\xa76.2/\xc2\xa76.3.
2026-05-07 12:01:25 -07:00
Ishaan Jaffer
0701110091
feat(v2 managed agents): add GET /v2/agents listing endpoint
Newest-first, scoped to caller, simple offset cursor (decimal string).
litellm_api_key is masked on every row in the response.
2026-05-07 12:01:19 -07:00
Ishaan Jaffer
2370235e65
feat(v2 managed agents): add list_agents and list_sessions_for_agent db helpers
Both scoped by created_by, ordered by created_at desc, simple offset-based
pagination via take/skip. list_sessions_for_agent supports an optional
SessionStatus filter.
2026-05-07 12:01:14 -07:00
Ishaan Jaffer
ef9bfa6f68
feat(v2 managed agents): add AgentList and SessionList typed models
Used by the new GET /v2/agents and GET /v2/agents/:agent_id/sessions
listing endpoints. Each list response carries data + next_cursor + has_more
for simple offset-based pagination.
2026-05-07 12:01:09 -07:00
Ishaan Jaffer
e00a6e92b2
test(v2 managed agents): drop python smoke from QA script — http-only 2026-05-07 11:14:31 -07:00
Ishaan Jaffer
da2dbbb3a9
test(v2 managed agents): add runnable QA happy-path script (Flow 1/2/3) 2026-05-07 11:09:12 -07:00
Ishaan Jaffer
6500a4b5d8
test(v2 managed agents): adapter tests for model object split, stateful streaming, permission auto-grant
send_message:
  - assert {providerID, modelID} object body (not string)
  - 'openrouter/anthropic/claude-3' splits on first '/' only
  - models without '/' omit the field entirely
  - model=None omits the field

list_messages: assert {info, parts} envelopes normalize to MessageRow,
  with reasoning/step-start/step-finish filtered out of content and the
  combined providerID/modelID showing up as our model string.

stream_events: assert text deltas route through partID -> type tracking,
  the partID map persists across multiple message.part.updated events,
  session.idle is enriched with the tracked assistant message_id, and
  permission.asked triggers a fire-and-forget POST to
  /session/:sid/permissions/:per_id with {response:'once'}.
2026-05-07 10:48:36 -07:00
Ishaan Jaffer
56b6da5a2f
test(v2 managed agents): update normalization tests for real opencode wire shapes
Update fixtures to use the {info, parts} envelope, epoch-ms timestamps,
camelCase wire field names (providerID/modelID), and the message.part.delta
event shape. Add coverage for:
  - filtering step-start/step-finish/reasoning parts out of content
  - tool state.status branches (running/completed/error/pending)
  - the part_types map populated by message.part.updated
  - message.part.delta routing via part_types lookup (text vs reasoning,
    unknown partID drops)
  - message.updated -> message.completed when info.time.completed is set
  - session.error unwrapping the nested error.data.message string
  - server.heartbeat / session.created drop to None
2026-05-07 10:48:29 -07:00
Ishaan Jaffer
a00695114f
fix(v2 managed agents): opencode adapter — model object split, stateful events, permission auto-grant
send_message: opencode 1.14.41 rejects string-form model with 400; split
our '<provider>/<model>' on the first '/' into the {providerID, modelID}
object form. Omit the field entirely if there's no '/' so opencode falls
back to its default agent/model.

stream_events: maintain a per-stream partID -> type map populated from
message.part.updated events so message.part.delta events can be routed
to text/reasoning. Track the in-flight assistant message_id from
message.updated so session.idle events (which carry only sessionID in
real opencode) can be enriched before yielding message.completed.

permission gating: opencode emits permission.asked events that block
tool calls until granted. Auto-grant via fire-and-forget
POST /session/:sid/permissions/:per_id body {response:'once'} so MVP
tool calls don't hang. Will surface as a real event type once we expose
permission gating to v2 callers.
2026-05-07 10:48:20 -07:00
Ishaan Jaffer
fec3ca1436
fix(v2 managed agents): rewrite opencode normalization for real wire shapes
opencode messages are nested as {info, parts}, not flat. Field naming on
the wire is camelCase with capital-ID suffix (sessionID, messageID,
partID, callID, providerID, modelID). Timestamps are epoch ms ints.
Part types include text/reasoning/tool/step-start/step-finish — only
text parts go into content; only tool parts go into tools. Tool I/O
lives under part.state.input / part.state.output (or .error).

Streaming text deltas come via message.part.delta events with
{messageID, partID, field, delta} — the part type is NOT on the delta
event, so normalize_opencode_event now takes a part_types dict the
caller maintains across the stream. session.idle has no messageID in
real opencode payloads — emit message.completed with message_id=None
and let the adapter enrich it from tracked state. session.error
unwraps the nested error.data.message string.
2026-05-07 10:48:09 -07:00
Ishaan Jaffer
520c55cf8f
fix(v2 managed agents): add SandboxSpec validator tests
Cover idle_timeout_minutes <= timeout_minutes contract \xc2\xa76.2 invariant plus
existing timeout_minutes [1, 1440] bound. New test_types.py keeps typing
concerns separate from endpoint tests in test_agents.py.
2026-05-07 10:43:08 -07:00
Ishaan Jaffer
49fd3ed1ba
fix(v2 managed agents): enforce idle_timeout_minutes <= timeout_minutes on SandboxSpec
Per contract \xc2\xa76.2, idle_timeout_minutes must be in [1, timeout_minutes].
Previously only ge=1 was enforced, so idle=1440 with timeout=10 would pass.

Add a Pydantic v2 model_validator(mode="after") that raises ValueError when
idle_timeout_minutes > timeout_minutes; FastAPI surfaces it as a 422.
2026-05-07 10:43:03 -07:00
Ishaan Jaffer
cf454e38c2
fix(v2 managed agents): wire up sessions/messages/events sub-routers 2026-05-07 10:07:54 -07:00
Ishaan Jaffer
63fd2fb91c
test(v2 managed agents): three happy-path integration tests (Flow 1/2/3) 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
440211e54e
test(v2 managed agents): pytest fixtures (opencode lifecycle, fake row, app client) 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
22a8d86e02
test(v2 managed agents): unit tests for SSE events endpoint 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
e4432be886
test(v2 managed agents): unit tests for messages endpoints 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
0016942ce1
test(v2 managed agents): unit tests for GET /v2/sessions/:id 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
af4c6de05e
test(v2 managed agents): unit tests for POST /v2/agents 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
3da6049a9f
test(v2 managed agents): unit tests for OpencodeAdapter (respx-mocked) 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
f0272f65bb
test(v2 managed agents): unit tests for opencode normalization 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
adb6361746
test(v2 managed agents): adapter tests package init 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
def252a64d
test(v2 managed agents): tests package init 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
e22212e306
feat(v2 managed agents): register managed_agents_router in proxy_server 2026-05-07 10:06:56 -07:00
Ishaan Jaffer
e4e6d79d73
feat(v2 managed agents): aggregate endpoint routers 2026-05-07 10:06:55 -07:00
Ishaan Jaffer
111728915e
feat(v2 managed agents): add GET /v2/sessions/:id/events SSE handler 2026-05-07 10:06:55 -07:00
Ishaan Jaffer
c530197518
feat(v2 managed agents): add POST + GET /v2/sessions/:id/messages handlers 2026-05-07 10:06:55 -07:00