Agent feature matrix

What every adopted source emits, at several granularities; derived from the conformance fixture corpus plus the reviewed capability record, regenerated by docs/gen-agents.js.

Coverage below is derived, not asserted: the per-type grids come from the conformance mapping fixtures that CI runs on every commit, and the capability columns come from the reviewed record behind this page (docs/data/agents.json). How each cell earned its place is the vendor surfaces page's job; the control side has its own control matrix.

Legend: fixture-pinned (the mapping table in conformance/fixtures/mappings/ asserts it) · shipped and documented at the component doc, not fixture-pinned · blank = not emitted by this source.

One reading note: the grids assert what each source's mapping tables pin: vendor moments landing on AEP types. The fixture fallback tables (how a wholly novel vendor moment would map) pin a mechanism, not feature span, so they are excluded. A blank family cell is itself feature-span information: it means the vendor surface exposes no moment of that family for the mapping to ride.

Coverage at a glance

19 rows
Source Class Channel Control loop Forms Validation Mapping fixture
Claude Code Agent adapter hooks: native http type or command shim answers permission (typed text follows the AEP-0008 receiver rule: an option word counts as that option, other free text is a deny WITH the text as the hook message, the vendor's own custom-reply path), form form (AEP-0006) live-validated claude-code.json
Codex Agent adapter hooks: command shim answers permission (typed text follows the AEP-0008 receiver rule: an option word counts as that option, other free text is a deny WITH the text as the decision message, the guidance path) n/a live-validated codex.json
Gemini CLI Agent adapter hooks: command shim n/a n/a fixture-proven gemini-cli.json
Qwen Code Agent adapter hooks: native http type (shimless) or command shim answers permission (typed text follows the AEP-0008 receiver rule: an option word counts as that option, other free text is a deny WITH the text as the decision message, the vendor's guidance path) n/a fixture-proven qwen-code.json
VS Code agent (Copilot) Agent adapter agent hooks (Preview): command shim answers permission (control opt-in: the held PreToolUse gate; an ask answer escalates to VS Code's own user-approval flow; typed text follows the AEP-0008 receiver rule: an option word incl. ask counts as that option, other free text denies with the text as the rendered reason) n/a fixture-proven vscode.json
Kimi Code CLI Agent adapter external hooks: command shim ([[hooks]] in the ONE global config.toml; strict four-field schema, no per-project hook file) answers permission (control opt-in: the held PreToolUse gate, binary allow/deny; typed text follows the AEP-0008 receiver rule: an option word counts as that option, other free text denies with the text as the rendered reason) n/a live-validated kimi-code.json
OpenCode Agent adapter plugin: runs inside the agent's Bun runtime answers permission (typed text follows the AEP-0008 receiver rule: an option word counts as that option; unmatched free text applies the refusing status; the hook output carries status only, so guidance stays stream-visible) n/a fixture-proven opencode.json
Kilo Code Agent adapter plugin: same shape as OpenCode (verified fork; runtime DIVERGED from the upstream at from 7.4.6) answers permission (dual surface; through 7.4.5: the held hook, typed text follows the AEP-0008 receiver rule, an option word counts as that option, unmatched free text applies the refusing status with guidance stream-visible only; from 7.4.6: options mirror the vendor reply enum once/always/reject verbatim and a reject's free text REACHES the vendor as the reply message), form (questions, from 7.4.6) form (AEP-0006) fixture-proven kilocode.json
Cline Agent adapter typed subprocess hooks (--hooks-dir) answers permission (hub opt-in) n/a fixture-proven cline.json
Hermes Agent adapter shell hooks: command shim answers permission (control opt-in: the held tool gate; typed text follows the AEP-0008 receiver rule: an option word counts as that option, other free text is a deny with the text as the reason; the vendor's own approval gate stays observed read-only in every posture) form (AEP-0006) fixture-proven hermes.json
Antigravity Agent adapter hooks: hooks.json command registration (event name as argv) n/a n/a fixture-proven antigravity.json
pi Agent adapter in-process extension (per-event subscription) answers permission (control opt-in: the held tool gate; a deny rides the vendor's own block result and the observed skip stays the pinned tool.failed, never recast) n/a fixture-proven pi.json
AG-UI Inbound bridge HTTP tee proxy in front of any AG-UI agent n/a n/a fixture-proven agui.json
ACP Inbound bridge stdio tee: the bridge IS the editor's agent command observes permission n/a fixture-proven acp.json
OpenHands Inbound bridge WebSocket observer on the agent server's events socket answers permission (control opt-in) n/a fixture-proven openhands.json
OTel inbound Inbound bridge OTLP/HTTP receiver (POST /v1/logs, JSON encoding) n/a n/a fixture-proven codex-otel.json
OpenCode SSE Inbound bridge SSE client on a running OpenCode server's event stream answers permission (control opt-in, primary mode) n/a fixture-proven opencode.json
Kilo Code SSE Inbound bridge SSE client on a running Kilo server's event stream (kilo serve) answers permission (control opt-in, primary mode) n/a fixture-proven kilocode.json
Kimi web (kap-server) Inbound bridge WS client on a running kap-server event stream (kimi web; REST /api/v1 + WS /api/v1/ws, bearer subprotocol) answers permission (control opt-in, primary mode: approvals only; question answering is deferred, reason recorded) n/a fixture-proven kimi-code.json

Event coverage

19 rows
Source session run tool attention progress delegation state error agent vendor x.*
Claude Code
Codex
Gemini CLI 3
Qwen Code
VS Code agent (Copilot)
Kimi Code CLI 14
OpenCode 5
Kilo Code 16
Cline 1
Hermes 2
Antigravity 1
pi 7
AG-UI 6
ACP 7
OpenHands 8
OTel inbound 7
OpenCode SSE 13
Kilo Code SSE 16
Kimi web (kap-server) 11
19 rows
Source session.started session.ended session.compacted run.started run.finished run.failed run.cancelled run.step.started run.step.finished
Claude Code
Codex
Gemini CLI
Qwen Code
VS Code agent (Copilot)
Kimi Code CLI
OpenCode
Kilo Code
Cline
Hermes
Antigravity
pi
AG-UI
ACP
OpenHands
OTel inbound
OpenCode SSE
Kilo Code SSE
Kimi web (kap-server)
19 rows
Source tool.requested tool.completed tool.failed tool.denied attention.requested attention.answered attention.resolved attention.timeout
Claude Code
Codex
Gemini CLI
Qwen Code
VS Code agent (Copilot)
Kimi Code CLI
OpenCode
Kilo Code
Cline
Hermes
Antigravity
pi
AG-UI
ACP
OpenHands
OTel inbound
OpenCode SSE
Kilo Code SSE
Kimi web (kap-server)
19 rows
Source progress.status progress.task.planned progress.task.completed delegation.subagent.started delegation.subagent.stopped state.snapshot state.delta error.raised agent.idle
Claude Code
Codex
Gemini CLI
Qwen Code
VS Code agent (Copilot)
Kimi Code CLI
OpenCode
Kilo Code
Cline
Hermes
Antigravity
pi
AG-UI
ACP
OpenHands
OTel inbound
OpenCode SSE
Kilo Code SSE
Kimi web (kap-server)

Vendor extension types, per source

Everything a source exposes beyond the core taxonomy rides its vendor namespace unchanged; the count is a feature-span signal, not noise.

Claude Code: 0 fixture-pinned extension types

No vendor extension types are fixture-pinned for this source (the fixture file pins the two structured-input (kind form) mappings at both capture ceilings; the remaining coverage below is documented at the component doc and validated live).

Codex: 0 fixture-pinned extension types

No vendor extension types are fixture-pinned for this source.

Gemini CLI: 3 fixture-pinned extension types
  • x.gemini-cli.session.after_model
  • x.gemini-cli.session.before_model
  • x.gemini-cli.session.before_tool_selection
Qwen Code: 0 fixture-pinned extension types

No vendor extension types are fixture-pinned for this source.

VS Code agent (Copilot): 0 fixture-pinned extension types

No vendor extension types are fixture-pinned for this source.

Kimi Code CLI: 14 fixture-pinned extension types
  • x.kimi-code.run.steer_submitted
  • x.kimi-code.session.permission_result
  • x.kimi-code.session.pre_compact
  • x.kimi-code.web.event.approval.requested
  • x.kimi-code.web.event.approval.resolved
  • x.kimi-code.web.event.question.answered
  • x.kimi-code.web.event.question.dismissed
  • x.kimi-code.web.event.question.requested
  • x.kimi-code.web.event.session.work_changed
  • x.kimi-code.web.session.meta.updated
  • x.kimi-code.web.tool.call.started
  • x.kimi-code.web.tool.result
  • x.kimi-code.web.turn.ended
  • x.kimi-code.web.turn.started
OpenCode: 5 fixture-pinned extension types
  • x.opencode.command.executed
  • x.opencode.file.edited
  • x.opencode.message.updated
  • x.opencode.server.connected
  • x.opencode.session.error
Kilo Code: 16 fixture-pinned extension types
  • x.kilocode.command.executed
  • x.kilocode.file.edited
  • x.kilocode.message.updated
  • x.kilocode.permission.asked
  • x.kilocode.permission.replied
  • x.kilocode.permission.updated
  • x.kilocode.question.asked
  • x.kilocode.question.replied
  • x.kilocode.server.connected
  • x.kilocode.session.compacted
  • x.kilocode.session.created
  • x.kilocode.session.deleted
  • x.kilocode.session.error
  • x.kilocode.session.idle
  • x.kilocode.session.status
  • x.kilocode.todo.updated
Cline: 1 fixture-pinned extension type
  • x.cline.prompt.submitted
Hermes: 2 fixture-pinned extension types
  • x.hermes.api.error
  • x.hermes.session.reset
Antigravity: 1 fixture-pinned extension type
  • x.antigravity.step.completed
pi: 7 fixture-pinned extension types
  • x.pi.agent.settled
  • x.pi.message.replied
  • x.pi.message.submitted
  • x.pi.model.select
  • x.pi.session.info
  • x.pi.session.tree
  • x.pi.thinking.select
AG-UI: 6 fixture-pinned extension types
  • x.agui.custom.event
  • x.agui.messages.snapshot
  • x.agui.raw.event
  • x.agui.reasoning.start
  • x.agui.text_message.end
  • x.agui.text_message.start
ACP: 7 fixture-pinned extension types
  • x.acp.current.mode.update
  • x.acp.fs.read.text.file
  • x.acp.initialize.event
  • x.acp.plan.updated
  • x.acp.session.cancel
  • x.acp.tool_call.update
  • x.acp.usage.updated
OpenHands: 8 fixture-pinned extension types
  • x.openhands.acp_tool.call
  • x.openhands.condensation.request
  • x.openhands.condensation.summary
  • x.openhands.interrupt.event
  • x.openhands.message.event
  • x.openhands.pause.event
  • x.openhands.system.prompt
  • x.openhands.user_reject.observation
OTel inbound: 7 fixture-pinned extension types
  • x.codex.otel.api_request
  • x.codex.otel.conversation_starts
  • x.codex.otel.sse_event
  • x.codex.otel.tool_decision
  • x.codex.otel.tool_result
  • x.codex.otel.user_prompt
  • x.codex.otel.websocket_event

Note: two vendor profiles ride one receiver: Codex's native OTel log export (codex-otel.json, the default) and the VS Code agent's copilot_chat.* LogRecord family (--vendor vscode, vscode-otel.json); one vendor per process, each with its own pure mapper.

OpenCode SSE: 13 fixture-pinned extension types
  • x.opencode.command.executed
  • x.opencode.file.edited
  • x.opencode.message.updated
  • x.opencode.permission.replied
  • x.opencode.permission.updated
  • x.opencode.server.connected
  • x.opencode.session.compacted
  • x.opencode.session.created
  • x.opencode.session.deleted
  • x.opencode.session.error
  • x.opencode.session.idle
  • x.opencode.session.status
  • x.opencode.todo.updated

Note: pinned by the sse_modes table in the OpenCode fixture file (companion and primary postures).

Kilo Code SSE: 16 fixture-pinned extension types
  • x.kilocode.command.executed
  • x.kilocode.file.edited
  • x.kilocode.message.updated
  • x.kilocode.permission.asked
  • x.kilocode.permission.replied
  • x.kilocode.permission.updated
  • x.kilocode.question.asked
  • x.kilocode.question.replied
  • x.kilocode.server.connected
  • x.kilocode.session.compacted
  • x.kilocode.session.created
  • x.kilocode.session.deleted
  • x.kilocode.session.error
  • x.kilocode.session.idle
  • x.kilocode.session.status
  • x.kilocode.todo.updated

Note: pinned by the sse_modes table in the Kilo Code fixture file (companion and primary postures; the OpenCode channel mirrored on x.kilocode.*; the bus union byte-identical at the re-verified pins).

Kimi web (kap-server): 11 fixture-pinned extension types
  • x.kimi-code.web.event.approval.requested
  • x.kimi-code.web.event.approval.resolved
  • x.kimi-code.web.event.question.answered
  • x.kimi-code.web.event.question.dismissed
  • x.kimi-code.web.event.question.requested
  • x.kimi-code.web.event.session.work_changed
  • x.kimi-code.web.session.meta.updated
  • x.kimi-code.web.tool.call.started
  • x.kimi-code.web.tool.result
  • x.kimi-code.web.turn.ended
  • x.kimi-code.web.turn.started

Note: pinned by the ws_modes table in the Kimi Code fixture file (companion and primary postures; lifecycle/approval shapes oracle-captured from the shipped 0.28.1, the question loop source-derived and labeled).

On this page