refactor(runtime): consolidate hook orchestration and cache executors#2523
Merged
dgageot merged 1 commit intodocker:mainfrom Apr 27, 2026
Conversation
Continue the hooks-extraction refactoring by pulling more orchestration out of pkg/runtime, making the hooks mechanism more powerful, and simplifying the runtime package. - Add hooks.NewAdditionalContextOutput helper and auto-fill Input.Cwd from the executor's working directory in Dispatch, removing repeated boilerplate at every callsite. - Move agent-flag to builtin auto-injection into pkg/hooks/builtins as AgentDefaults / ApplyAgentDefaults, with dedicated tests. - Introduce pkg/runtime/hooks.go with a cached per-agent hooksExec and a single dispatchHook helper. The nine executeXHooks methods now delegate to it, shrinking each to a few lines. - Rewire tool_dispatch.go's pre/post-tool paths through dispatchHook so they share the same dispatch + SystemMessage handling. - Update hooks_wiring_test.go to cover the executor cache and rename the test to TestHooksExecWiresAgentFlagsToBuiltins. Net effect: -189 lines across runtime + tool_dispatch, all hook code centralised in hooks.go, no behavior change. Tests pass with -race; golangci-lint reports zero issues. Assisted-By: docker-agent
rumpl
approved these changes
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continues the hooks-extraction refactoring: pulls more orchestration out of
pkg/runtime, makes thepkg/hooksmechanism more powerful, and significantly simplifies the runtime package.Net effect across
pkg/runtime: −189 lines, all hook code colocated in a singlehooks.go, no behaviour change.go test -raceandgolangci-lintboth clean.Changes
pkg/hooks— more ergonomic for builtin authors and embeddersExecutor.Dispatchnow auto-fillsInput.Cwdfrom the executor's working directory when callers leave it empty. Eliminates the per-callsiteCwd: r.workingDirplumbing across the runtime.hooks.NewAdditionalContextOutput(event, content)helper forBuiltinFuncimplementations that just want to contribute additional context. Returnsnilfor empty content.pkg/hooks/builtins— owns the agent-flag → builtin wiringAgentDefaultsstruct +ApplyAgentDefaults(cfg, defaults) *hooks.Config. Encodes the rules:AddDate→turn_start(recompute every turn)AddPromptFiles→turn_start(file may be edited mid-session)AddEnvironmentInfo→session_start(cwd / OS / arch are session-stable)nilwhen the resulting config is empty so the runtime can skip executor construction. Covered by three new tests.NewAdditionalContextOutput, dropping duplicatedOutputliteral construction.pkg/runtime— simpler and fasterpkg/runtime/hooks.goholds all hook orchestration:hooksExec(a)replacesgetHooksExecutorand caches the per-agent*hooks.Executor(including thenil"no hooks configured" sentinel) under anRWMutex. Per-turn dispatches no longer pay the matcher-compilation cost repeatedly.dispatchHook(ctx, agent, event, input, events)is the single shared dispatcher: resolves the cached executor, short-circuits on no-hook, dispatches, logs errors, and emitsWarningevents forSystemMessage.executeXHooksmethods shrink from 10–25 lines each to a handful of lines, all delegating todispatchHook.tool_dispatch.go:runToolno longer fetches the executor; pre/post-tool hooks now go throughdispatchHooktoo.newHooksInputis a package function and no longer setsCwd.Diffstat
```
pkg/config/latest/hooks_yaml_test.go | 4 +-
pkg/hooks/builtins/builtins.go | 65 +++++--
pkg/hooks/builtins/builtins_test.go | 54 ++++++
pkg/hooks/executor.go | 6 +-
pkg/hooks/types.go | 16 ++
pkg/runtime/hooks.go | 230 +++++++++++++++++++++++++
pkg/runtime/hooks_wiring_test.go | 20 ++-
pkg/runtime/runtime.go | 317 +----------------------------------
pkg/runtime/tool_dispatch.go | 71 ++++----
9 files changed, 412 insertions(+), 371 deletions(-)
```
Validation
Assisted-By: docker-agent