feat(mcp): expose AI agent sessions on the MCP - #867
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe change adds a shared agent-session package, tenant-scoped warehouse reads, five MCP tools, AI span decoding, tool analytics, structured outputs, tests, documentation, and application integrations. ChangesAI agent observability
Agent tool analytics
Application integration
Priority: ➖ Normal Estimated code review effort: 5 (Critical) | ~90 minutes Change: Feature Merge Risk: 🟡 Moderate · up to Oversized sessions can lose useful span output or consume excessive worker memory, while some analytics output can be incomplete or malformed. The lint failure and material runtime concerns should be resolved before merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
57979e6 to
17a502c
Compare
17a502c to
aceed9e
Compare
There was a problem hiding this comment.
Devin Review found 2 potential issues.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
| const lines: string[] = [ | ||
| `## AI agent sessions (showing ${offset + 1}–${offset + sessions.length})`, |
There was a problem hiding this comment.
🟡 Full pages hide remaining sessions
When list_agent_sessions fills limit, its response provides no next offset or continuation signal. Agents cannot discover later matching sessions.
Learn more
The tool accepts offset and describes itself as paged, but its result only prints the current range. A full page is ambiguous because the list read returns at most limit rows and exposes no total. Other MCP list tools explicitly tell the agent when and how to continue.
Example: With limit=25 and 40 matches, the first response says showing 1–25 but never supplies offset=25. An agent can treat those 25 sessions as the complete result and omit the remaining 15.
Recommended fix: Fetch or expose enough paging metadata to detect another row, then append a continuation message containing offset + page.ranked. Keep the paging calculation based on ranked, matching the ListAiSessionsResponse contract.
Was this helpful? React with 👍 or 👎 to provide feedback.
| genAi[field] = Array.isArray(value) | ||
| ? keptMessages(value).map((message) => clipStrings(message, MESSAGE_TEXT_CHARS)) | ||
| : clipStrings(value, PAYLOAD_TEXT_CHARS) |
There was a problem hiding this comment.
🟡 Array payloads lose most entries
When any JSON payload is an array, clipSpanContent keeps only message-history entries. Tool results and other array payloads lose earlier entries.
Learn more
The JSON field catalog includes message histories and unrelated payloads such as toolCallResult, toolDefinitions, retrievalDocuments, and memoryRecords. keptMessages is valid only for message-history fields. Applying it based solely on Array.isArray changes the semantic shape of every other array payload before session findings run.
Example: A failed tool result captured as [{"error":"first failure"},{"retry":"also failed"}] becomes only {"retry":"also failed"}. The session report can omit the actual failure even though it was loaded.
Recommended fix: Apply keptMessages only to the catalog fields that represent message histories. Preserve every element of other JSON arrays and recursively clip their strings with the payload budget.
Was this helpful? React with 👍 or 👎 to provide feedback.
aceed9e to
1370556
Compare
0d3fb9e to
0e648f5
Compare
0e648f5 to
4590a84
Compare
Two read-only tools over the Agent Sessions page's model, plus an AI decode inside inspect_span: - list_agent_sessions: the ranked list with the page's filters, sort and paging. - get_agent_session: the Overview — verdict and findings, wall clock/active/idle, agent time and peak parallelism, tokens, cost, models, tools, failure groups, turns. Loads up to 10 000 spans with each span's captured content clipped (newest user message + last message, strings cut to 500 chars, tool payloads to 1 000 per string); past the cap or a 413 it says so and covers what loaded. - inspect_span decodes an AI span above its raw attributes: the messages it captured and the tool calls it made or executed, results resolved from the rest of its trace. The session derivations the page runs client-side (turns, summary, findings, transcript, span detail) move from apps/web/src/lib/agent-sessions into packages/agent-sessions so the API renders the same model the page does; the four formatters they bake into their output move to @maple/domain/format with @maple/ui and the web re-exporting them. Test-only span builders and the lab fixture ship behind a ./testing subpath. The browser-replay session tools now say so and point at list_agent_sessions.
4590a84 to
bbb4515
Compare
Summary
Second of three PRs splitting the original version of this PR. Stacked on #875 (the reads lift); tool health follows in #876.
Two read-only MCP tools over the Agent Sessions page's model, plus an AI decode inside the existing
inspect_span:list_agent_sessions— the ranked list with the page's filters (vendor/service/environment/model/agent/tool, id search, error/duration/cost/token/call ranges), sort and paging. Bounds accept numbers or numeric strings and reject out-of-range values as parameter errors;limit/offsetare clamped like every other tool; a full page says whichoffsetcontinues it. Each row's next-step line prints the padded windowget_agent_sessionshould be given.get_agent_session— the Overview: verdict and findings, wall clock/active/idle, agent time and peak parallelism, tokens, cost, models, tools, failure groups, turns. Reads the same padded window the page reads, so its numbers match the page. Loads up to 10 000 spans, clipping each span's captured content as it is mapped (message histories keep the newest user message and the last message, strings cut to 500 chars, tool payloads keep their shape with strings cut to 1 000). On a 413 it halves the page and retries down to 125 spans; if it still cannot load, it says which spans it has and prints the timestamp to resume from. Past the cap it says so.inspect_spandecodes an AI span above its raw attributes: the messages it captured and the tool calls it made or executed, results resolved from the rest of its trace. Atimestamphint skips the trace-window lookup and reads an hour back and a day ahead; a longer trace pages and says so. Decode failures are contained: the raw attributes are always returned.Both new tools return text only. No
__maple_uimirror: nothing renders one yet, and the mirror is a second copy of the answer in the model's context.How
packages/agent-sessions(@maple/agent-sessions): the session derivations the page runs client-side (turns, summary, findings, transcript, span detail, the read-window padding) lifted out ofapps/web/src/lib/agent-sessions/so the API renders the same model the page does. Move plus the lint conversionspackages/*requires (no non-null assertions, notry/catch); 225 package tests moved with it. Test-only span builders and the lab fixture ship behind a./testingsubpath.formatDuration,formatNumber,formatSessionDuration,formatCurrency) move to@maple/domain/format;@maple/uire-exports them and the web imports them directly. Locale handling is unchanged from main.list_agent_sessions.Dropped from the original version on review:
list_agent_session_spans(for trace-keyed sessions it wasinspect_tracewith a flat table; the other sessions are covered byget_agent_session+inspect_span), the retained-content budget and the exact-totals second read behind it, the structured mirrors and their 290 lines of domain types.Test plan
bun run --cwd packages/agent-sessions test(225)bun run --cwd apps/ai test src/mcp(418, includes registry invariants, theinspect_spandecode/containment regressions, cap and 413-retry cases throughget_agent_session)bun run --cwd packages/ui test src/lib/__tests__/format(33)bun run --cwd apps/web test src/components/agent-sessions src/lib/agent-sessions src/routes/agent-sessions src/lab src/hooks/use-session-spans.test.tsx(276)tsc --noEmitinapps/ai,packages/domain,packages/agent-sessionsmain)