Skip to content

ACP mode does not implement session/close (sessionCapabilities.close never advertised) — ACP clients cannot release sessions #4113

Description

@DDKinger

Summary

When Copilot CLI runs as an ACP agent (copilot --acp --stdio), it does not
implement the ACP session/close request, and its initialize response does
not advertise the sessionCapabilities.close capability. As a result an ACP
client has no protocol-level way to tell Copilot that a session it created
via session/new is finished and can be torn down.

For a client that multiplexes many sessions over a single long-lived
copilot --acp process (Zed, Windows Terminal, other IDE integrations), every
session ever created stays resident for the lifetime of the Copilot process.
session/cancel only aborts the in-flight turn — it does not release the
session — so there is no clean way to reclaim per-session resources short of
killing the whole agent process.

This is the same class of gap as #3256 (ACP mode does not advertise
session.fork capability — slash /fork exists, ACP method missing
): the ACP
schema defines the method and a capability bit, but the Copilot ACP server
neither implements it nor advertises it.

Environment

  • GitHub Copilot CLI 1.0.71-0
  • Transport: copilot --acp --stdio
  • ACP schema reference: agent-client-protocol / agent-client-protocol-schema
    SessionCapabilities.close: Option<SessionCloseCapabilities> gates
    session/close; the doc states "only available if the agent advertises the
    sessionCapabilities.close capability."

Current behavior (reproduced)

Driving copilot --acp --stdio with a minimal newline-delimited JSON-RPC client:

1. initializesessionCapabilities advertises only list, no close:

{
  "loadSession": true,
  "mcpCapabilities": { "http": true, "sse": true },
  "promptCapabilities": { "image": true, "audio": false, "embeddedContext": true },
  "sessionCapabilities": { "list": {} }
}

2. session/new succeeds, returns e.g. sessionId: a95110c0-8f81-4933-94e6-75127090eb45.

3. session/close on that id is rejected as Method not found:

// --> {"jsonrpc":"2.0","id":5,"method":"session/close","params":{"sessionId":"a95110c0-..."}}
// <-- error:
{
  "code": -32601,
  "message": "\"Method not found\": session/close",
  "data": { "method": "session/close" }
}

(Side note observed during the repro: session/list returns on-disk history —
50 rows — and does not contain the just-created live sessionId, so
session/list cannot be used as a substitute to discover/close live in-memory
sessions.)

Expected behavior

  • initialize advertises agentCapabilities.sessionCapabilities.close (e.g.
    {}) when the build supports it.
  • session/close with { "sessionId": "<id>" } releases the live session
    (frees its in-memory state / handles) and returns a CloseSessionResponse
    ({} result).
  • After a successful session/close, using that sessionId again (e.g. a
    second session/close, session/prompt, session/set_mode) is rejected with
    a "session not found"–style error, so clients can confirm the release.

Why this matters

ACP was designed for a client to own the process lifetime while opening and
closing many sessions against it. Without session/close:

Reproduction

Minimal repro with any ndjson JSON-RPC driver over copilot --acp --stdio:

  1. Send initialize { "protocolVersion": 1, "clientCapabilities": {} }
    note sessionCapabilities has no close.
  2. Send session/new { "cwd": "<abs path>", "mcpServers": [] } → capture
    sessionId.
  3. Send session/close { "sessionId": "<id>" } → observe
    -32601 "Method not found": session/close.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:agentsSub-agents, fleet, autopilot, plan mode, background agents, and custom agentsarea:sessionsSession management, resume, history, session picker, and session state

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions