From ab9cc35bcd751cd29deabe3849d2d644bdaf655c Mon Sep 17 00:00:00 2001 From: Serhii Vecherenko Date: Fri, 21 Aug 2026 13:22:09 -0700 Subject: [PATCH] fix(crossagentMcp): require descriptive labels for subagent runs - Clarify naming guidance and generated provider details - Test spawn and task label instructions --- src/supervisor/crossagentMcp/toolRegistry.test.ts | 13 +++++++++++++ src/supervisor/crossagentMcp/toolRegistry.ts | 7 ++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/supervisor/crossagentMcp/toolRegistry.test.ts b/src/supervisor/crossagentMcp/toolRegistry.test.ts index 5a54c9ace..dfb5c5a68 100644 --- a/src/supervisor/crossagentMcp/toolRegistry.test.ts +++ b/src/supervisor/crossagentMcp/toolRegistry.test.ts @@ -606,6 +606,19 @@ describe("subagent tool registration", () => { expect(byName.get("spawn_agent")!.description).toContain("never spawn before it"); }); + it("asks parents to give every spawned run a descriptive task label", () => { + expect(CROSSAGENT_MCP_INSTRUCTIONS_BASE).toContain("Always set name"); + expect(CROSSAGENT_MCP_INSTRUCTIONS_BASE).toContain("appends those automatically"); + const byName = new Map(TOOLS.map((tool) => [tool.name, tool])); + expect(byName.get("spawn_agent")!.inputSchema).toMatchObject({ + properties: { + name: { + description: expect.stringContaining("describing what this run does"), + }, + }, + }); + }); + it("returns an isError result (not a throw) for removed full-thread tools", async () => { const { ctx } = makeToolContext(); const result = await dispatchTool("create_thread", { prompt: "x" }, ctx); diff --git a/src/supervisor/crossagentMcp/toolRegistry.ts b/src/supervisor/crossagentMcp/toolRegistry.ts index eff8feef2..ca1435952 100644 --- a/src/supervisor/crossagentMcp/toolRegistry.ts +++ b/src/supervisor/crossagentMcp/toolRegistry.ts @@ -67,6 +67,7 @@ export const CROSSAGENT_MCP_INSTRUCTIONS_BASE = [ "Use ordered fallbacks to retry startup failures on another model or provider. Retrying after a dispatched turn requires retry_on='any-failure' because it may repeat side effects.", "Background runs also survive interruption of the current parent turn, but still stop when the parent thread closes.", "Give each subagent a self-contained prompt — it does not share your conversation context.", + "Always set name on spawn_agent and on every tasks=[...] entry: a short, specific label describing what that subagent will do (for example `Review runtime findings`). Users see this label in the thread; do not omit it or repeat provider/model/reasoning values there — Crossagents appends those automatically.", "For long-lived, first-class app threads the user sees in the sidebar (optionally in their own git worktree) — e.g. one ticket or feature per thread — use the always-on `poracode` MCP server's thread tools (create_thread, list_threads, get_thread, read_thread, send_to_thread, wait_for_thread, interrupt_thread, stop_thread) instead.", ].join(" "); @@ -119,7 +120,11 @@ const SUBAGENT_TASK_PROPERTIES = { ...SUBAGENT_SELECTION_PROPERTIES, prompt: { type: "string", description: "Self-contained task for the subagent." }, tags: TASK_TAGS_PROPERTY, - name: { type: "string", description: "Optional short label for the run." }, + name: { + type: "string", + description: + "Short specific label describing what this run does (its task or goal), shown to the user in the thread. Always provide one; provider/model details are appended automatically.", + }, fallbacks: { type: "array", maxItems: 3,