Commit Graph
2 Commits
Author SHA1 Message Date
BaaRai 54ff51177d agent: guard prompt and wrap-up override hooks against concurrent access
PromptOverride, WrapupOverride, WrapupMaxTurnsOverride,
WrapupTaskTimeoutOverride and WrapupTaskTimeoutTurnsOverride are wired
in server.New while restored tasks may already render prompts and build
settlement configs on other goroutines. go test -race ./server reported
races between server.New (server.go:195/207/215) and agent.renderSystem /
resolveWrapup / resolveWrapupTurns.

Same treatment as the tool hooks: unexported variables behind a
sync.RWMutex (one for the prompt hook, one shared by the four wrap-up
hooks), Set* setters and getters, and readers that copy the function
value under the lock and call it outside. A nil hook still means the
built-in default.

TestAgentHooksConcurrentSwap now covers all eight hooks.
2026-11-14 14:19:13 +01:00
BaaRai 37f2573a53 agent: guard ToolAugment/ToolResolve hooks against concurrent access
server wiring (wireAgentAugment, wireTools) assigned the package-level
hooks agent.ToolAugment and agent.ToolResolve while restored tasks could
already be running AugmentTools on other goroutines. go test -race ./server
reported this as a DATA RACE between agent.AugmentTools and
server.wireAgentAugment.

Each hook is now an unexported variable behind a sync.RWMutex, with a
setter (SetToolAugment, SetToolResolve) and a getter (ToolAugment(),
ToolResolve()). AugmentTools copies the function value through the getter
and calls it outside the lock. A nil hook still means no augmentation /
no resolution, as before.

FindingTrafficBindingEnabled is wired in the same server/assembly.go code
and read on the same AugmentTools path, so it gets the same treatment.

Adds TestAugmentToolsHooksConcurrentSwap, which runs AugmentTools while
the setters swap the hooks, so -race catches an unsynchronised access
without depending on test ordering.
2026-11-14 13:46:03 +01:00