fix(agent-builder): propagate runtime agent installs to fallback even when boot was chat-disabled#266
Merged
Merged
Conversation
… when boot was chat-disabled
The runtime plugin-(de)activation propagation closures (propagatePluginInstall/
propagatePluginUninstall + reconcileRuntimeDomainTool) were assigned only inside
the boot-time `if (orchestrator) { … }` guard. On a chat-DISABLED boot — no
ANTHROPIC_API_KEY at start, i.e. the Setup-Wizard / Docker path — they stayed
undefined, so the onInstalled hook's `propagatePluginInstall?.(agentId)` silently
no-op'd: an installed agent activated in the dynamicAgentRuntime but the fallback
Agent's agent_plugins enablement row was never written. Because
scopeDomainToolsToPlugins gates a domain tool on that row, the agent's query_*
tool was withheld from the fallback Agent — at install time AND on every later
restart (the missing DB row persists). Channels were unaffected because the
channel install hook activates them directly with no plugin-scoping, which is why
connectors appeared on a fresh session but specialist agents never did.
Define the closures unconditionally; they already resolve configStore /
orchestratorRegistry live from the serviceRegistry per call, so they take effect
the moment chat goes live via the wizard. Forward-ref lets become consts and the
now-redundant optional-chaining at call sites is dropped.
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.
Problem
After installing an agent plugin at runtime, its specialist sub-agent (
query_*domain tool) was not pulled into the fallback Agent — neither on a fresh chat session nor after a restart. Channel/connector installs, by contrast, showed up on a new session. That asymmetry was the reported bug.Root cause
The
onInstalledhook forkind: 'agent'activates the agent indynamicAgentRuntime, then callspropagatePluginInstall?.(agentId)to wire the new domain tool into the per-Agent orchestrators (including the fallback Agent).But
propagatePluginInstall/propagatePluginUninstall(andreconcileRuntimeDomainTool) were assigned only inside the boot-timeif (orchestrator) { … }guard. On a chat-disabled boot — noANTHROPIC_API_KEYat process start, i.e. the Setup-Wizard / Docker path —orchestratoris falsy at boot, so those closures stayedundefined. The optional-chained call then silently no-op'd:dynamicAgentRuntime, but the fallback Agent'sagent_pluginsenablement row was never written.scopeDomainToolsToPluginsgates each domain tool on that row → the tool was withheld from the fallback Agent.Channels are unaffected because the channel install hook activates them directly (
channelRegistryRef.activate) with no plugin-scoping / DB enablement — which is exactly why connectors appeared on a fresh session but specialist agents never did.Fix
Define the three closures unconditionally (hoisted out of the
if (orchestrator)boot guard). They already resolveconfigStore/orchestratorRegistrylive from theserviceRegistryon every call, so they take effect the moment chat goes live via the Setup Wizard — and the enablement row they write now survives restarts. Forward-reflets becomeconst, and the now-redundant optional chaining at the call sites is dropped.Pure code-motion + scope change; no behavioural change on the env-key (chat-enabled-at-boot) path.
Verification
npm run build✅ (full workspace, ends by compilingsrc/index.ts)eslint src/index.ts✅ (0 problems)tsc --noEmit✅ (0 errors)test/runtimeToolPropagation.test.ts+test/scopeDomainTools.test.ts✅ (10/10 pass)Remaining nuance (out of scope)
Installing an agent before the key is set (while
orchestratorRegistrydoesn't exist yet) still early-returns, but now self-heals on the next restart because the boot hydration reads enablement from the DB. The normal flow (set key → install agents) is fully fixed.