Files
sim/apps/docs
Waleed 19b0312a04 feat(managed-agent): add session lifecycle operations (#6140)
* feat(managed-agent): add session lifecycle operations

Adds an operation selector to the Claude Managed Agents block, backed by
nine new tools alongside the existing run-session behavior:

- create session (non-blocking, seeds initial_events)
- send message to an existing session
- get session (surfaces tool calls awaiting approval)
- list events
- update session (title/metadata)
- interrupt session
- respond to tool confirmation (allow/deny)
- archive session
- delete session

Run Session stays the default, so blocks saved before the selector
existed keep their exact behavior and field layout.

* fix(managed-agent): address review findings on session lifecycle ops

- List Events kept the OLDEST slice when capped, dropping the agent's most
  recent reply. Paging is exhaustive again and the cap now keeps the newest
  N after ordering, with a `truncated` flag so callers know it is a tail.
- listPaginated returned whole pages past maxItems; it now trims to the
  exact cap.
- A whitespace-only title passed the update guard and would have cleared an
  existing session title. Blank is now treated as not provided.
- Interrupt had no request timeout and could hang; bounded at 15s while
  still honoring the workflow signal.
- Custom-tool gates were surfaced by Get Session but could not be answered,
  since they need user.custom_tool_result rather than a confirmation. Adds a
  Respond To Custom Tool operation and a `kind` on each pending gate so a
  workflow routes to the right one.
- Docs rendered a raw ${DEFAULT_EVENT_LIMIT} placeholder for the default.

* fix(managed-agent): correct truncation flag, gate lookup, custom tool result

- `truncated` was true whenever the history size equalled the limit, even
  though nothing was dropped. Event reads now report the untrimmed total and
  the flag compares against that.
- Pending-gate enrichment capped its read, which keeps the OLDEST events in
  page order — the opposite of where blocking gates live. It now filters to
  the ids being looked up as pages arrive, which is both correct regardless
  of page order and bounded by the id count. Paging continues on the raw
  page so a fully-filtered page is not mistaken for the end of the list.
- Respond To Custom Tool applied one result to every id, so multiple pending
  tools would all receive the same output. It now answers a single call per
  invocation.

* fix(managed-agent): stop fractional event limits reading unbounded

A limit below 1 passed the positivity check and then floored to 0, which
made `slice(-0)` hand back the ENTIRE history flagged as complete — the
opposite of the requested bound. The limit is now floored before it is
validated, so anything that does not resolve to a positive integer falls
back to the default.

Also hardened the library: a zero or negative cap short-circuits to an
empty result instead of falling through to `slice(-0)`, so no future
caller can hit the same trap.

* fix(managed-agent): stop gate lookup scanning the full tool history

The id filter keeps the collected array tiny, so `maxItems` never trips and
the walk continued to the end of a session's tool history even after every
blocking id had been found. `listPaginated` now takes a `stopWhen` predicate
and the gate lookup ends as soon as it has all the ids it came for.

Also makes a blocked-but-unnamed session observable: when a session reports
`requires_action` with no blocking event ids, `requiresAction` stays true —
reporting false would tell a workflow the session is fine while it is parked
indefinitely — and the dead end is logged and documented instead.

* fix(managed-agent): floor event cap and make metadata clearing explicit

- A `maxItems` between 0 and 1 slipped past the zero guard and became
  `slice(-0)` — the whole history — because slice truncates its index toward
  zero. The cap is now floored at the library boundary, so no caller can hit
  it whatever they pass.
- Update Session documented full metadata replacement but could not express
  a clear: an empty map normalizes to "absent". Inferring the clear from
  emptiness would be worse, since an untouched table is also empty and would
  wipe metadata on every title-only update. Adds an explicit `clearMetadata`
  instead, and corrects the parameter's documentation.

* test(managed-agent): pin the HTTP shape of every session endpoint

Method, URL, and beta header for all 11 calls, plus the SSE accept header,
the separate memory-store beta (combining the two is a documented 400), and
content-type only on requests that carry a body. These are the details types
cannot catch and that break silently when a path is "tidied".
2026-07-31 17:59:20 -07:00
..
2026-02-16 00:00:12 -08:00

docs

This is a Next.js application generated with Create Fumadocs.

Run development server:

bun run dev

Open http://localhost:3000 with your browser to see the result.

Learn More

To learn more about Next.js and Fumadocs, take a look at the following resources: