fix: inherit custom tools in subagents#330
Conversation
🦋 Changeset detectedLatest commit: b2e75bd The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b2e75bde1e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| const context = await prepareSystemPromptContext(child.kaos); | ||
| child.useProfile(profile, context); | ||
| child.tools.inheritUserTools(parent.tools); |
There was a problem hiding this comment.
Preserve read-only subagent tool restrictions
When the parent has an active side-effecting custom tool, this unconditional inheritance gives it to every subagent profile after child.useProfile(profile) has applied that profile's restricted tool list. That means explore and plan subagents, whose profiles intentionally omit write-capable tools and rely on read-only behavior, can still call parent user tools that mutate files or external state. Please filter inherited user tools by the child profile's allowed tools/capabilities or otherwise avoid adding arbitrary parent custom tools to read-only subagents.
Useful? React with 👍 / 👎.
| inheritUserTools(parent: ToolManager): void { | ||
| for (const tool of parent.userTools.values()) { | ||
| if (!parent.enabledTools.has(tool.name)) continue; | ||
| this.registerUserTool({ |
There was a problem hiding this comment.
Drop inherited tools when the parent disables them
Because inheritance registers a separate active copy on the child, a subagent keeps this custom tool even after the parent later calls unregisterTool or setActiveTools to remove it. In sessions where a subagent is resumed or still running in the background after the parent disables a desktop-provided tool, the LLM can still see and call the stale child copy, so tool availability no longer matches the parent’s current active tools. Please keep inherited user tools synchronized or avoid persisting an independent active registration on the child.
Useful? React with 👍 / 👎.
|
|
||
| const context = await prepareSystemPromptContext(child.kaos); | ||
| child.useProfile(profile, context); | ||
| child.tools.inheritUserTools(parent.tools); |
There was a problem hiding this comment.
Apply inherited custom tools when resuming subagents
This inheritance is only invoked from configureChild, which is used for new spawn calls, but resume() prepares an existing child by updating only its model. If the parent registers a desktop custom tool after the child was created, or the user resumes a pre-fix subagent from disk, that resumed subagent still won't see the parent's active custom tools even though newly spawned subagents do. Please run the same inheritance/realignment step on resume as well.
Useful? React with 👍 / 👎.
Related Issue
No linked issue; this fixes a subagent tool inheritance gap found while wiring desktop-provided custom tools through agent-core.
Problem
Desktop-side tools can be registered as user tools on the main agent, but newly spawned subagents did not inherit those tools. That meant a subagent could have the built-in and MCP tools from its profile while still being unable to use custom tools the parent agent already had available.
What changed
Subagent setup now inherits the active user tools from the parent after applying the subagent profile. The inheritance recreates the user tool registration on the child agent instead of reusing the parent's executable tool object, so tool calls are routed through the subagent's own RPC context. A regression test covers both tool visibility and child-scoped execution routing.
Validation
pnpm --filter @moonshot-ai/agent-core exec vitest run test/session/subagent-host.test.ts test/agent/tool.test.tspnpm --filter @moonshot-ai/agent-core exec tsc -p tsconfig.json --noEmitgit diff --checkChecklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update. No doc update is needed for this internal subagent tool inheritance fix.