Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/core/src/tools/agent/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,47 @@ describe('AgentTool', () => {
).toMatch(/working_dir/i);
});

it('accepts an empty working_dir with worktree isolation', () => {
expect(
agentTool.validateToolParams({
...validParams,
working_dir: '',
isolation: 'worktree',
}),
).toBeNull();
});

it('accepts a whitespace-only working_dir with worktree isolation', () => {
expect(
agentTool.validateToolParams({
...validParams,
working_dir: ' ',
isolation: 'worktree',
}),
).toBeNull();
});

it('normalizes an empty working_dir before creating an isolated invocation', () => {
const params = {
...validParams,
working_dir: '',
isolation: 'worktree' as const,
};

expect(agentTool.validateToolParams(params)).toBeNull();

const invocation = (
agentTool as AgentTool & {
createInvocation(params: AgentParams): {
params: AgentParams;
};
}
).createInvocation(params);

expect(invocation.params.working_dir).toBeUndefined();
expect(invocation.params.isolation).toBe('worktree');
});

it('accepts redundant worktree isolation when working_dir is set', () => {
expect(
agentTool.validateToolParams({
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/tools/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,14 @@ assistant: Uses the ${ToolNames.AGENT} tool to launch the test-runner agent
}
}

if (
params.isolation === 'worktree' &&
typeof params.working_dir === 'string' &&
params.working_dir.trim().length === 0
) {
params.working_dir = undefined;
}
Comment on lines +1048 to +1054

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] validateToolParams mutates its input (params.working_dir = undefined), and the getToolDescription path in agent-core.ts passes the live args object through build(args) β†’ validateToolParams. This means TOOL_CALL event emissions and pre-tool hooks silently see working_dir: undefined instead of the model-supplied "".

No functional breakage β€” the normalization is semantically correct β€” but event logs will differ from model output, which could confuse debugging (e.g. an investigator comparing model output to event logs would see an unexplained disappearance of the working_dir field).

Consider moving the normalization into createInvocation (and adjusting the validation block below to skip the empty-string check when isolation === 'worktree'), so validateToolParams stays a pure validator. Alternatively, structuredClone in getToolDescription would match the scheduler's hygiene.

β€” qwen3.7-max via Qwen Code /review


if (params.working_dir !== undefined) {
if (
typeof params.working_dir !== 'string' ||
Expand Down
Loading