Skip to content

Decide what, if anything, Cockpit should do about the Agent Host Protocol #139

Description

@titan-ron

What AHP is, so the question is the right one

VS Code 1.129 moved Claude, Codex and Copilot into a separate agent-host process and talks to it over the Agent Host Protocol. It is worth being precise about what it is, because the name invites the wrong comparison:

  • It is not a rival to ACP. AHP is a coordination layer — a host holds authoritative state for N clients and speaks ACP down to the agent. Their own words: "AHP is a mutex over ACP". The ACP work in feat(acp): drive agents over the Agent Client Protocol #135 is unaffected and needs no rework.
  • Cockpit has no multi-client problem. One window, one client. The thing AHP solves is not a problem we have.

So "should Cockpit speak AHP?" is the wrong question. The right one is below.

The question that is actually open

The host keeps each session in its own store — agentSessionData/<uuid>/session.db — and for Claude drives a downloaded SDK over a proxy transport rather than the claude CLI. None of that reaches ~/.claude, ~/.codex or ~/.copilot, which are the only places SessionIndexer looks.

If that holds, every agent session started in VS Code is invisible to Cockpit, which contradicts the premise the product rests on: every agent session on this machine, wherever it ran.

It is not yet confirmed. The mechanism is confirmed (own store, proxy transport, no provider-store writes observed). The size of the gap is not: the only store on the machine this was found on has zero turns — the host GCs sessions nobody used — so there is no populated session to check against. One real VS Code agent session, then npm run probe:agent-host (#138), settles it.

The options, and what each is worth

1. Nothing. Defensible if nobody here runs agent sessions in VS Code. The risk is that this is a growing default rather than a niche — the host is the reference AHP implementation and ships to every VS Code user.

2. Index the store (session.db). Reads with VS Code closed, needs no protocol, and is architecturally the same move as provider-archived.ts already reading Copilot's data.db. This is the option that actually closes the gap. Blocked on one thing: the turns / local_turns payload shape, which only a real session produces.

3. Speak AHP as a client. Gains structured live state for those sessions — real turn boundaries, permission requests, no log-tail heuristics. Costs: it only works while VS Code is running, covers only VS Code's sessions, and the local discovery layout (local-endpoint/) is VS Code's private arrangement — not in the published transport spec, and already drifted once (metadata.json array at protocol 0.7.0 vs entries/ at 0.8.0). Strictly a complement to 2, never a substitute.

4. Be an AHP host. The inversion: Cockpit already holds authoritative session state and spawns turns, so a phone or web client could drive its sessions. Interesting long-term, a large scope jump (WS server, auth, reducers, reconciliation), and no second client is asking for it. Not now.

Recommendation

Answer the open question first — it is five minutes and it decides everything else. If the gap is real: option 2, and treat 3 as a separate decision taken later on its own merits. Option 4 is a product direction question, not a protocol one.

Related

  • feat(agent-host): measure what VS Code's agent host holds that the indexer cannot see #138 adds the reader, the coverage verdict and npm run probe:agent-host, plus a redacted capture of the store's shape so the parser for option 2 can be written without anyone's prompts landing in a fixture. It is instrumentation only — nothing in the running app calls it — and it is reasonable to close it unmerged if the answer above turns out to be "nothing".

Activity

  1. titan-ron commented on Sep 25, 2026

    @titan-ron
    CollaboratorAuthor

    Spike evidence: a real client against a real host

    Ran @microsoft/agent-host-protocol@0.9.0 against a local code agent host (VS Code 1.134). Six things worth recording, two of which change the issue above.

    It connects, and the client is dependency-free

    Full handshake, root state, listSessions. The npm client has zero dependencies — relevant given the standing preference against adding libraries.

    The protocol version is not stable enough to build on yet

    The bundled code agent ps was refused by the host it had just started:

    Client offered protocol versions [0.7.0] … server accepts ^0.9.0

    So the CLI client and the standalone host inside one VS Code install can't talk to each other. This sharpens the drift point above: editor windows publish schemaVersion 1 / 0.7.0 entries over unix sockets, the standalone host publishes schemaVersion 2 / 0.9.0 over TCP. A client wanting to see both kinds of host needs both transports and both versions.

    Correction: the host advertises Claude and Copilot, not Codex

    Root state listed exactly two agents:

    • claude — "Claude agent backed by the Anthropic Claude Agent SDK", lazily downloaded to agent-host/sdk-cache/claude/<version>
    • copilotcli — "Copilot SDK agent running in the local agent host process"

    No Codex. The issue body says VS Code moved all three into the host; on this install it's two.

    The open question is still open, and here's the blocker

    createSession fails before it starts:

    RPC error -32007: Authentication is required to use Claude

    …with RFC 9728 protected-resource metadata pointing at GitHub OAuth. The gate is the host's, not the CLI's — accounts.ts reads each CLI's own credential store and none of that transfers. So the "one real session, then probe it" plan needs an interactive sign-in to the agent host first; it isn't five minutes unless that's already done.

    Option 2 (index session.db) is harder than it looks

    Read the schema of the existing stores directly. Two findings that bear on the parser:

    • session_metadata holds only isRead and the project URI / display name. No title, no provider, no timestamps. turns, local_turns, turn_usage and file_edits were all empty — the populated tables are a client-state sidecar (drafts, reviewed files, checkpoint edits), not a session log.
    • Every store on the machine shared one identical size and mtime, rewritten when the host started. So mtime tracks host lifecycle, not session activity — the stat-cache and fs.watch design would read nothing useful from it, and updatedAt can't be derived from the file.

    That doesn't sink option 2, but it means the store alone can't populate SessionMeta: title, provider and timestamps live in the host process. A reader would get the cwd and isRead and little else until the turn payload shape is known.

    What option 3 would hand over for free

    Worth weighing when this is revisited, because it's more than "structured live state":

    • SessionStatus is an enum with InProgress, InputNeeded, IsRead and IsArchived — the three things liveness-core.ts, attention-core.ts and provider-archived.ts currently reconstruct by tailing logs and judging records.
    • SessionSummary carries title, createdAt, modifiedAt, provider, workingDirectories[] and a changes summary.
    • listSessions is cursor-paginated, most-recently-modified first — the same invariant this repo already enforces, arrived at independently.

    Suggested revisit trigger

    Nothing here argues for acting now: 0.9.0, one host implementation, and a version split inside a single VS Code release. Worth looking again when any of these is true:

    1. AHP reaches 1.0 with a stated compatibility guarantee, or the editor and the standalone host converge on one version;
    2. someone on the team actually runs agent sessions in VS Code (that's what makes the invisibility gap cost something);
    3. a second Cockpit client is wanted (phone/web), which is when option 4 stops being hypothetical.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions