Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 131 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tokio-tungstenite = { version = "=0.30.0", default-features = false, features =
a2a-protocol-client = "=0.11.0"
a2a-protocol-server = { version = "=0.11.0", default-features = false }
a2a-protocol-types = "=0.11.0"
agenthooksprotocol = { version = "=0.4.1", default-features = false, features = ["reqwest", "tokio-process"] }
agent-client-protocol = { package = "agentkit-acp-sdk", version = "=2.2.0", features = ["unstable_session_fork", "unstable_session_inject"] }
agent-client-protocol-schema = { package = "agentkit-acp-schema", version = "=1.9.1", features = ["unstable_session_notices", "unstable_session_compaction"] }
agent-client-protocol-http = { package = "agentkit-acp-http", version = "=2.2.0", default-features = false, features = ["server", "client"] }
Expand Down
74 changes: 74 additions & 0 deletions docs/user/agent-hooks-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Agent Hooks Protocol

Kit delivers [Agent Hooks Protocol](https://github.com/agenthooksprotocol/rust-sdk)
events to hook backends registered in `~/.agents/hooks.json` (global) and
`<root>/.agents/hooks.json` (project). When neither file exists, hooks are off.

## Configure hooks

Each file holds an AHP registration:

```json
{
"protocolVersion": "draft",
"hooks": [
{
"id": "org.example.policy",
"transport": {
"type": "stdio",
"command": "/usr/local/bin/policy-hook",
"lifecycle": "persistent"
},
"subscriptions": [
{
"events": ["tool.before"],
"mode": "intercept",
"timeoutMs": 3000,
"failurePolicy": "fail-closed",
"content": {"default": "body"}
}
]
}
]
}
```

Kit reads the global file, then the project file. A project hook replaces the
global hook with the same `id`; other hooks from both files stay active. Kit
skips an unreadable or malformed file with a warning. A subscription
selector that matches no event Kit emits disables hooks with a warning.

Hook backends run local processes or receive session content. Review both files
before you run Kit in a project you do not trust.

## Events

| Event | Where Kit emits it | Hook authority |
| --- | --- | --- |
| `session.start` | A session's model connection opens | Observe |
| `session.end` | A prompt run finishes or an ACP session closes | Observe |
| `user.message.inbound` | A new turn admits a user prompt | Deny, replace the prompt |
| `model.request.before` | Before each model call, with the transcript | Deny |
| `model.response.after` | A model call finishes, with its output | Observe |
| `model.error` | A model call fails | Observe |
| `tool.before` | Before a tool runs | Allow, deny, return a result, replace or merge input |
| `tool.after` | A tool finishes, with its output | Observe |
| `context.compact.before` | Before compaction summarizes the transcript | Return a summary, replace summarizer instructions |
| `context.compact.after` | Before the summary is installed | Replace the summary |

A denied prompt is removed, together with resources attached to it, and the
turn ends without a model call. A denied
model request fails the turn. A denied tool call returns a permission error to
the model.

Kit checks edited tool input against the tool's input schema before the tool
runs; an edit that does not match counts as a hook failure. An edit that the
hook does not also allow goes through Kit's permission policy again.

Tool events cover the tools that compose scripts call, such as `shell`, `edit`,
`read_file` and the MCP `tool` dispatcher. Kit projects text, structured data,
tool calls and tool results into message parts. It omits media, files and
reasoning.

Kit does not emit `turn.*`, `model.switch.*`, `config.change.*`, `file.changed`
or the tool permission and progress events yet.
2 changes: 2 additions & 0 deletions docs/user/getting-started-and-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ subdir = "agent-plugins/example"

`a2a` applies to `serve` and `tui`. Configured plugins can provide MCP servers without `mcp_config`; supported `stdio` and `streamable-http` declarations are registered, while `sse` declarations are skipped with a stderr diagnostic. MCP servers merge by name in this order: plugins, configured `mcp_config`, `<canonical-root>/.mcp.json`, then `--mcp-config`. Higher layers replace whole conflicts while preserving non-conflicting lower entries; live removal reveals the next lower layer. Plugin data is stored under `<config-directory>/plugin-data/<plugin-manifest-name>`. See [Agent Plugins](agent-plugins.md) for placeholders, collision rules, and ACP child behavior. `otel_endpoint` enables OTLP export of AgentKit's GenAI trace spans. `otel_protocol` accepts exactly `grpc`, `http/protobuf`, or `http/json`; gRPC is the default. For either HTTP protocol, Kit appends `/v1/traces` to a base endpoint unless it already ends with that path. `credential_store` selects one backend for OpenAI, Speakeasy, and MCP and defaults to `memory`; selecting `file` requires `credential_dir`, while a credential directory is invalid with `memory` or `keychain`. Memory credentials are process-local and are not shared with the TUI server process or nested Kit children. Standalone OpenAI and Speakeasy login requires persistent `keychain` or `file` storage. ACP profiles are direct executable-and-argument configurations, not shell command strings. `[subagent].harness` must name an available fully qualified profile such as `acp.review`; otherwise startup reports `unknown subagent ACP harness`. When no subagent harness is selected, the built-in `acp.kit` profile is used.

Agent hooks are configured in `~/.agents/hooks.json` and `<root>/.agents/hooks.json`. See [Agent Hooks Protocol](agent-hooks-protocol.md).

### Configuration precedence and built-in defaults

For settings exposed by a command, precedence is:
Expand Down
Loading
Loading