fix(coding-agent): fixed tool validation and branch-cache fallback handling

- Added a regression test for tool argument coercion that preserves quoted edit arrays while stripping optional null fields.
- Updated footer branch-watcher initialization to clear cached branch state when resolving git head fails.
- Set the report_tool_issue tool definition to non-strict mode for looser argument handling.
This commit is contained in:
can1357
2026-04-26 03:20:43 +02:00
parent c82df1367d
commit 17411f3a4b
3 changed files with 53 additions and 15 deletions
@@ -179,6 +179,38 @@ describe("Tool argument coercion", () => {
expect(result.edits).toEqual([{ target: "13#cf", new_content: "..." }]);
});
it("coerces quoted edit arrays before stripping optional null fields", () => {
const textSchema = Type.Union([Type.Array(Type.String()), Type.String()]);
const tool: Tool = {
name: "atom-like-edit",
description: "",
parameters: Type.Object({
path: Type.String(),
edits: Type.Array(
Type.Object({
loc: Type.String(),
set: Type.Optional(textSchema),
pre: Type.Optional(textSchema),
post: Type.Optional(textSchema),
sub: Type.Optional(Type.Tuple([Type.String(), Type.String()])),
}),
),
}),
};
const toolCall: ToolCall = {
type: "toolCall",
id: "call-atom-like-edit",
name: "atom-like-edit",
arguments: {
path: "orcid.ts",
edits: '[{"loc":"276ka-282vu","pre":null,"set":["line"],"post":null,"sub":null}]',
},
};
const result = validateToolArguments(tool, toolCall) as { edits: Array<Record<string, unknown>> };
expect(result.edits).toEqual([{ loc: "276ka-282vu", set: ["line"] }]);
});
it("coerces array strings with trailing wrapper braces from malformed nested JSON", () => {
const tool: Tool = {
name: "t16",
@@ -56,22 +56,27 @@ export class FooterComponent implements Component {
this.#gitWatcher = null;
}
git.head.resolve(getProjectDir()).then(head => {
if (!head) {
return;
}
void git.head
.resolve(getProjectDir())
.then(head => {
if (!head) {
return;
}
try {
this.#gitWatcher = fs.watch(head.headPath, () => {
this.#cachedBranch = undefined; // Invalidate cache
if (this.#onBranchChange) {
this.#onBranchChange();
}
});
} catch {
// Silently fail if we can't watch
}
});
try {
this.#gitWatcher = fs.watch(head.headPath, () => {
this.#cachedBranch = undefined; // Invalidate cache
if (this.#onBranchChange) {
this.#onBranchChange();
}
});
} catch {
// Silently fail if we can't watch
}
})
.catch(() => {
this.#cachedBranch = null;
});
}
/**
@@ -57,6 +57,7 @@ export function createReportToolIssueTool(session: ToolSession): AgentTool {
return {
name: "report_tool_issue",
label: "Report Tool Issue",
strict: false,
description: "Report unexpected tool behavior for automated QA tracking.",
parameters: ReportToolIssueParams,
async execute(_toolCallId, rawParams) {