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