fix(agent-core): allow subagent cwd override for package-level AGENTS.md discovery#172
fix(agent-core): allow subagent cwd override for package-level AGENTS.md discovery#172thecannabisapp wants to merge 1 commit into
Conversation
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9814568692
ℹ️ 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 runtime = | ||
| options.cwd !== undefined | ||
| ? { ...parent.runtime, kaos: parent.runtime.kaos.withCwd(options.cwd) } |
There was a problem hiding this comment.
Resolve relative subagent cwd against the parent cwd
When the tool caller supplies a relative cwd such as packages/domain from a session rooted at /repo, this passes that string directly into withCwd. LocalKaos.withCwd stores relative values as-is instead of resolving them against the parent Kaos cwd, so AGENTS.md discovery and later tool execution are anchored to the server process cwd rather than the parent agent's working directory (and the subsequent config update can even try to chdir relative to that relative cwd). This makes the new cwd override unreliable for common monorepo package paths unless callers always know to pass an absolute path.
Useful? React with 👍 / 👎.
| const { id, agent } = await this.session.createAgent( | ||
| { type: 'sub', generate: parent.rawGenerate }, | ||
| { type: 'sub', generate: parent.rawGenerate, runtime }, |
There was a problem hiding this comment.
Persist the custom runtime for resumed subagents
When a custom-cwd subagent is saved and the session is later resumed, metadata only records the homedir/type/parent, so ensureResumeAgentInstantiated() reconstructs every agent with the shared session runtime instead of this overridden runtime. Replaying the child's recorded config.update({cwd: ...}) then calls chdir on that shared Kaos, so after kimi resume a package-scoped subagent can move the main agent's runtime cwd (and other agents' tool resolution) to the package directory even though their config.cwd still says the session root. The cwd/runtime override needs to be restored per agent on resume, not just applied at initial spawn.
Useful? React with 👍 / 👎.
| description: args.description, | ||
| runInBackground, | ||
| signal: backgroundController?.signal ?? foregroundDeadline?.signal ?? signal, | ||
| cwd: args.cwd, |
There was a problem hiding this comment.
Reject or honor cwd when resuming a subagent
If a caller sets both resume and cwd, this option is forwarded into the resume path, but SessionSubagentHost.resume() only realigns modelAlias and never updates the child's cwd/runtime or reloads AGENTS.md. In that scenario the tool accepts a package cwd while silently continuing in the old working directory, so follow-up prompts that rely on scoped paths or package-level instructions run against the wrong context. Either make cwd spawn-only with an explicit error on resume, or apply it during resume.
Useful? React with 👍 / 👎.
| const { id, agent } = await this.session.createAgent( | ||
| { type: 'sub', generate: parent.rawGenerate }, | ||
| { type: 'sub', generate: parent.rawGenerate, runtime }, |
There was a problem hiding this comment.
Run subagent hooks from the overridden cwd
For a subagent spawned with a package cwd, this still creates the child without a cwd-specific hookEngine, so it inherits the session-level engine that was constructed with the original session cwd. Tool and prompt hooks use that engine's cwd both in inputData.cwd and as the subprocess working directory, which means package-scoped hook commands (for example a PreToolUse/PostToolUse script that runs package-local checks) run from the repo root while the subagent tools run from the package directory. The custom cwd path should also be reflected in the child's hook engine.
Useful? React with 👍 / 👎.
|
Related upstream issue filed: #173 |
9814568 to
7edbada
Compare
|
Thanks for the review. Addressed in the latest push: P2 — Relative cwd resolution ✅ Fixed. P2 — cwd on resume ✅ Fixed. P1 — Persist custom runtime on resume Acknowledged. This requires storing the overridden runtime/cwd in per-agent metadata and restoring it in P2 — Hook engine cwd mismatch Acknowledged. The child inherits the session-level |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7edbada5cd
ℹ️ 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".
| resolvedCwd !== undefined | ||
| ? { ...parent.runtime, kaos: parent.runtime.kaos.withCwd(resolvedCwd) } | ||
| : undefined; |
There was a problem hiding this comment.
Inherit the parent runtime for nested subagents
When a cwd-scoped subagent later delegates without passing cwd, this leaves runtime undefined, so Session.createAgent() falls back to the session runtime instead of the parent subagent's cwd-scoped runtime. configureChild() still copies the parent cwd into the nested child config, which calls chdir on that shared session Kaos; in that nested-subagent scenario the main agent and other agents can have their runtime cwd moved to the package directory. Use the parent runtime when no new cwd override is requested, and only wrap it with withCwd when a different cwd is provided.
Useful? React with 👍 / 👎.
| description: args.description, | ||
| runInBackground, | ||
| signal: backgroundController?.signal ?? foregroundDeadline?.signal ?? signal, | ||
| cwd: args.cwd, |
There was a problem hiding this comment.
Require approval before escaping the parent cwd
When cwd is an absolute path outside the parent workspace, forwarding it unchecked lets the default-approved Agent tool create a child whose own config.cwd is that outside directory. I checked default-tool-approve.ts and Agent is auto-approved, while the write guard only asks for writes outside the child cwd; in another git worktree this means a subagent can auto-approve Write/Edit operations that would have required approval if the parent tried the same outside path directly. Constrain cwd to the parent cwd or surface the requested directory as a file access that must be approved.
Useful? React with 👍 / 👎.
….md discovery Subagents previously inherited the parent's Kaos instance and cwd, so package-level AGENTS.md files were never loaded for subagents. This broke monorepo workflows where subagents should operate with package-specific context. Changes: - Add optional "cwd" parameter to AgentToolInputSchema - Pass cwd through RunSubagentOptions to SessionSubagentHost.spawn() - Resolve relative cwd against parent.config.cwd before passing to withCwd(), so callers can use relative package paths - Create an isolated Kaos via withCwd() for the subagent when cwd is provided, so AGENTS.md discovery and path resolution use the target directory without mutating the parent agent's shared Kaos state - Allow config.runtime override in Session.instantiateAgent so the subagent can receive its isolated runtime - Update configureChild to use the custom cwd when provided - Reject cwd when combined with resume (silently ignored before) - Add unit and integration tests for cwd propagation, relative resolution, and resume rejection
7edbada to
7f3229a
Compare
Problem
Subagents inherit the parent agent's Kaos instance and working directory. In monorepos, this means subagents never discover package-level AGENTS.md files — they only see the session root AGENTS.md. This breaks workflows that worked in kimi-cli via scoped subagent YAMLs.
What changed
Checklist