镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(unstable-v2): add background work to v2 - #2738

Merged
benbrandt merged 2 commits into
mainfrom
feat/v2-background-work
Oct 30, 2026
Merged

benbrandt merged 2 commits into
mainfrom
feat/v2-background-work

Conversation

@benbrandt

@benbrandt benbrandt commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Implements phase 1 of the v2 Background Work RFD: the schema changes from its "Schema" section and the draft docs. It's v2-only, so it's covered by unstable_protocol_v2 and has no feature flag of its own. The subagent list item and background on the unknown state also need unstable_subagents.

Schema

ToolCallStatus = "pending" | "in_progress" | "paused" | "completed" | "failed" | "cancelled" | string

ToolCallUpdate / TerminalUpdate {
  ...,
  capabilities?: { cancel?: { _meta? } | null, _meta? } | null   // patch: omitted = unchanged, null = clear
}

// client → agent, empty results
tool_call/cancel { sessionId, toolCallId, _meta? }
terminal/cancel  { sessionId, terminalId, _meta? }

// on running / requires_action / idle (and unknown) state snapshots
background?: BackgroundWork[] | null
BackgroundWork =
  | { type: "terminal",  terminalId, _meta? }
  | { type: "tool_call", toolCallId, _meta? }
  | { type: "subagent",  sessionId,  _meta? }   // unstable_subagents
  | { type: string, ... }                       // custom or future
  • paused: a new ToolCallStatus variant. Older v2 Clients receive it through the existing Other fallback. pending now means "hasn't started running yet", with scheduling as one example.
  • capabilities: follows the subagent capability pattern (SubagentSessionCapabilities), as the RFD specifies. The types are ToolCallCapabilities/ToolCallCancelCapabilities and TerminalCapabilities/TerminalCancelCapabilities. The RFD named the cancel types in the singular, but they're plural here to match every other capability type, including SessionCancelCapabilities. They're display hints, so a malformed value falls back to unsupported.
  • background:
    • Unknown items: the custom-item fallback (OtherBackgroundWork) rejects known type values, the same way OtherStateUpdate does. A malformed terminal or tool_call item can't fall through to it.
    • Malformed lists: following the RFD, the field is DefaultOnError with no per-item skipping, so a malformed list counts as not reported rather than as an empty list.
  • Accessor: StateUpdate::background() reads the list without matching on each state. It returns None for custom states.
  • Item type names: the RFD named the variants but not their types. They're BackgroundTerminal, BackgroundToolCall, BackgroundSubagent and OtherBackgroundWork. I added a revision history entry to the RFD saying so.

Docs

Each change is made in the stable v2 page and its draft/ copy. The subagent details only go in the draft copies, since only the draft pages describe subagents.

  • prompt-lifecycle:
    • New "Background work" section: what counts as background work, the background list and its rules, and what Clients learn from it.
    • Session states: points to the list.
    • Cancellation: listed work keeps running, preemptive marking skips it, and permission requests are told apart by subject.
    • Failures: listed work isn't part of the failed work.
  • tool-calls: the paused status and its display and transition guidance, a "Cancelling tool calls" section, a "Cancelling terminals" section, and the rule that permission requests for background work reference the listed item in subject.
  • cancellation: session/cancel only answers permission requests for foreground work.
  • session-setup: close stops listed work and tells the Client how to finalize it, resume restores the list after announcing each item, and (draft only) a fork starts with no background work.
  • migration: a sentence on the background list and the narrower cancel rule, and an update to the line saying terminals have no control semantics, since they now have opt-in cancellation.
  • RFDs:
    • Subagents RFD: optimistic cancellation skips listed work.
    • v2 overview RFD: the change list includes background work.
    • Background Work RFD: a phase 1 entry in its revision history.

Phases 2 and 3 of the RFD (adapters and a Client implementation, then adjustments) aren't part of this PR.

Implement phase 1 of the v2 Background Work RFD in the v2 schema:

- `ToolCallStatus::Paused`, and a broader `pending` definition that
  covers scheduled work
- `capabilities` on `ToolCallUpdate` and `TerminalUpdate`, with an
  opt-in `cancel` capability following the subagent capability pattern
- `tool_call/cancel` and `terminal/cancel` client-to-agent requests
- a `background` list on the `running`, `requires_action`, `idle`, and
  (with `unstable_subagents`) `unknown` state snapshots, made of
  `terminal`, `tool_call`, and `subagent` items plus a fallback for
  custom items that rejects known discriminators; a malformed list is
  treated as not reported

Document background work, the new status, both cancel methods, and the
narrower `session/cancel` permission rule in the v2 prompt lifecycle,
tool calls, cancellation, session setup, and migration pages and their
draft copies, and note the change in the subagents and v2 overview
RFDs.
@benbrandt
benbrandt requested a review from a team as a code owner October 30, 2026 21:28
…erns

- Add `StateUpdate::background()` so callers can read the list without
  matching on each state
- Rename `ToolCallCancelCapability` and `TerminalCancelCapability` to
  `*CancelCapabilities`, matching every other capability type including
  `SessionCancelCapabilities`
- Reword the capability docs, which the Client acts on rather than only
  displays, and rewrap the cancel request docs
- Note in the migration guide that terminals have one opt-in control,
  `terminal/cancel`
@benbrandt
benbrandt merged commit a965f1f into main Oct 30, 2026
14 checks passed
@benbrandt
benbrandt deleted the feat/v2-background-work branch October 30, 2026 21:49
@acp-release-bot acp-release-bot Bot mentioned this pull request Oct 30, 2026
benbrandt added a commit that referenced this pull request Nov 2, 2026
…FD (#2743)

* docs(schema): restore the v1 meaning of Implementation.title and the tool-call intro

The plain-language pass (#2730) changed two v1 passages beyond wording:

- `Implementation.title` said it "should be readable by people", which adds
  a should-statement to the stable v1 spec and schema. Restore the v1.14.0
  meaning ("optimized to be human-readable and easily understood") without
  the em dash. The v2 copy uses the same text.
- The v1 tool-calls intro said Agents may use Client capabilities "while
  running a tool call", which reads as a new timing limit. Drop the temporal
  clause and keep the original "or".

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(protocol): align v2 session/cancel text with the background-work rules

#2738 narrowed `session/cancel` so listed background work keeps running and
its permission requests stay open, but several v2 passages still stated the
old rule. Update them in the stable and draft pages and the v2 schema:

- prompt-lifecycle: add the missing "or" in the announce-before-listing
  rule (stable only, the draft already had it), scope "stop all tool call
  invocations" to the cancelled foreground work, put the `-32800` rule next
  to the prompts it covers, and state that a `subject` the Client does not
  recognize, such as a custom subject type, is answered with `cancelled`.
- tool-calls, cancellation, migration: answer pending permission requests
  for the cancelled foreground work, not every request in the session.
- Schema: `RequestPermissionOutcome::Cancelled`, the
  `session/request_permission` request and the `session/cancel`
  notification descriptions now state the narrowed rule and the custom
  subject case.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(unstable): reconcile session/status, auth/status and session/set_title with their RFDs

- session/status: keep `-32002` for sessions the Agent does not know, and
  state the RFD's exception in the schema, the draft error pages and the
  RFD's own error rule: an Agent that cannot cheaply tell a saved session
  from an unknown one may return `saved`, and the later resume or load gets
  `-32002`.
- auth/status: add it to the draft v2 list of requests that do not fail
  with `auth_required`, and put the RFD's MUST NOT in the schema.
- session/set_title: refusing a session the Agent cannot safely update
  returns `-32602`, as an explicit exception to retitling any listed
  session, in the schema, the draft error pages and the RFD.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(rfd): resolve proxy-chains ambiguities and match the reference conductor

Define, in the proxy-chains RFD and the proxy schema descriptions:

- Errors the conductor returns itself (before initialization, failed
  chain start, `proxy/initialize` from outside, misplaced `proxy/successor`,
  malformed envelopes, a component that exited), separate from the
  pass-through rule for wrapped results.
- Hop-local cancellation: `$/cancel_request` names a request on its own
  connection, is never forwarded, and each hop re-issues it.
- Envelope `_meta` is hop-local and not copied into the unwrapped message.
- Version selection along the chain, the proxy's obligation to forward
  `initialize` before answering, the proxy/initialize result built from the
  successor's (same `protocolVersion`), and repeated `proxy/initialize`.
- "Unchanged" results and errors mean the same JSON value.
- Wrapped `params` is an object, an array, or `null`.
- Forwarding of unknown requests and notifications and where `-32601`
  comes from.

Also link version negotiation for v1 and v2, replace the old
`sacp-conductor` name, drop crash-handling claims the reference conductor
does not implement, and add a revision-history entry.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(unstable): drop the saved-for-unknown and retitle-refusal exceptions

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(protocol): let the Agent cancel permission requests on session/cancel in v2

The Agent knows which work each permission request belongs to, so on
session/cancel it stops waiting for the cancelled work's requests and
cancels them with $/cancel_request, as it already does for elicitations.
Clients MAY answer them early. session/close cancels every pending
permission request the same way. This removes the subject-based rules
for which requests the Client answers.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant