From f0ddccff71f3bbda975cac8a86053a67c5d554f3 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 7 Nov 2026 19:56:13 -0600 Subject: [PATCH] fix(chat): ask which record is meant when a change matches several A chat request such as "Mark the landing-page task as high priority" with two accessible tasks of that title left the agent deliberating between picking one, changing both and asking, until the run was cancelled. Chat guidance now says to ask which candidate is meant, with links and the distinguishing detail, before changing any of them. Co-Authored-By: Claude Opus 5.5 --- server/src/__tests__/agent-conversations.test.ts | 8 ++++++++ server/src/services/agent-conversations.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/server/src/__tests__/agent-conversations.test.ts b/server/src/__tests__/agent-conversations.test.ts index 2a4ceafb6dc..eb0835c6738 100644 --- a/server/src/__tests__/agent-conversations.test.ts +++ b/server/src/__tests__/agent-conversations.test.ts @@ -994,6 +994,14 @@ describe("chat prompt policy", () => { expect(prompt).toContain("//agents/"); }); + it("asks which record is meant before changing one of several matches", () => { + expect(AGENT_CHAT_DIRECTIVE).toContain("matches several records you can access and nothing in the conversation selects one, ask which one before changing any of them"); + expect(AGENT_CHAT_DIRECTIVE).toContain("link each candidate"); + expect(AGENT_CHAT_DIRECTIVE).toContain("Do not pick the first match, change every match"); + const prompt = buildPaperclipTaskMarkdown({ issue: { id: "chat", identifier: null, title: "Chat", workMode: "ask", conversationAgentId: "agent" } }); + expect(prompt).toContain("ask which one before changing any of them"); + }); + it("preserves explicit plan approval while avoiding ritual confirmations for ordinary chat", () => { expect(AGENT_CHAT_DIRECTIVE).toContain("When the user asks to approve a plan before handoff"); expect(AGENT_CHAT_DIRECTIVE).toContain('interactionKind: "confirmation"'); diff --git a/server/src/services/agent-conversations.ts b/server/src/services/agent-conversations.ts index 84592ac13f4..c974dfbced3 100644 --- a/server/src/services/agent-conversations.ts +++ b/server/src/services/agent-conversations.ts @@ -88,7 +88,7 @@ export function isConversationReset(body: string): boolean { return body.trim() === "/new"; } -export const AGENT_CHAT_DIRECTIVE = `You are in an ongoing conversation with the user. Help them clarify the outcome they want. Ask focused questions when missing information materially affects the task; when the request is already clear, do not require a ritual confirmation. +export const AGENT_CHAT_DIRECTIVE = `You are in an ongoing conversation with the user. Help them clarify the outcome they want. Ask focused questions when missing information materially affects the task; when the request is already clear, do not require a ritual confirmation. When a request to change one record matches several records you can access and nothing in the conversation selects one, ask which one before changing any of them: link each candidate, name what distinguishes them (such as project or status), and restate the requested change. Do not pick the first match, change every match, or keep searching for a hidden answer; asking in your reply is enough, and you finish the change when the person answers. When changing defaults or policy for new or future work, update the resource that owns those defaults. Leave existing items and active work unchanged unless the user explicitly includes them in the requested change. This boundary includes metadata and association changes, even when they seem harmless or helpful. Do not broaden the request to align related existing items. Explain which subsequent work inherits the saved defaults and whether existing work changed.