Skip to content

feat(ahp): deliver Agent Hooks Protocol events at native seams - #267

Merged
danielkov merged 3 commits into
mainfrom
feat/ahp-hooks
Oct 12, 2026
Merged

danielkov merged 3 commits into
mainfrom
feat/ahp-hooks

Conversation

@danielkov

@danielkov danielkov commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Delivers Agent Hooks Protocol events to hooks registered in ~/.agents/hooks.json and <root>/.agents/hooks.json, using the agenthooksprotocol 0.4.1 SDK. Each event is emitted from a seam that already exists in Kit or agentkit. Every agentkit crate stays on its published version.

Motivation

This replaces the approach in #266, which hand-built event JSON, wrapped every tool individually, and depended on an unmerged agentkit fork.

Technical details

Where each event is emitted

Events Seam
session.start, model.request.before, model.response.after, model.error HookedAdapter, a ModelAdapter/ModelSession/ModelTurn decorator around SelectableAdapter
user.message.inbound PromptHook, a LoopMutator at AfterTurnEnded, where every turn's admitted prompt is already in the transcript. Removing a denied prompt ends the turn without a model call
tool.before, tool.after hooked_tools, one Tool decorator applied to the compose child registry in compose_with_jobs_and_mcp
context.compact.before, context.compact.after KitCompactionBackend::summarize
session.end The end of run_persistent/run_interruptible and the shared ACP clean_up_session

The SDK owns protocol behavior

Events are typed SDK inputs passed to the SDK's named Hooks methods. Outcomes come back as typed settled events. The SDK handles ordering, merging, timeouts, failure policy, content selection and transports.

Once a hooks file exists, Kit dispatches every event and the SDK skips routes that do not subscribe to it. Each tool's compiled input schema is cached until its spec changes.

Tool input edits

Edited input is validated against the tool's own input_schema through an SDK Contract. An edit that the hook does not also allow goes back through the tool's proposed_requests and the active permission checker. This is the same path BasicToolExecutor uses.

Failures

A dispatch failure denies the gating events: tool.before, user.message.inbound and model.request.before. Observation failures and compaction edit failures are logged and leave the operation unchanged.

An invalid registration disables hooks with a stderr warning rather than blocking startup.

Scope

Kit projects transcript items as text message parts. Media, files and reasoning are omitted.

These events are not emitted yet:

  • turn.*
  • model.switch.*
  • config.change.*
  • file.changed
  • the tool permission and progress events

They need hooks in the duplicated ACP v1/v2 config paths or inside individual tools, so they are left for follow-ups.

@kit-code-agent kit-code-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inbound prompt hooks are bypassed for media-only ACP prompts and A2A requests, and denied ACP attachments remain in history. Hook-provided empty compaction summaries discard usable context. Tool completion events omit supplied results and misreport pre-invocation failures as executed.

Comment thread src/ahp/prompt.rs Outdated
Comment thread src/ahp/prompt.rs
Comment thread src/runtime.rs
Comment thread src/compaction.rs
Comment thread src/ahp/tool.rs
Comment thread src/ahp/tool.rs Outdated

@kit-code-agent kit-code-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inbound prompt hooks are still bypassed for media-only ACP prompts and A2A requests, and denied ACP attachments remain in history. Hook-provided empty or whitespace-only compaction summaries discard usable context. Tool completion events still omit hook-supplied results and misreport pre-invocation failures as executed.

@kit-code-agent kit-code-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found. The changes look good to merge.

@danielkov
danielkov merged commit add35f7 into main Oct 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant