From ca52d2c6c17c608fdba013a4bc9768b79d976aa6 Mon Sep 17 00:00:00 2001 From: Koshkoshinsk Date: Thu, 14 May 2026 10:59:06 +0000 Subject: [PATCH] fix(welcome): stop emitting the greeting twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The welcome skill told the agent to send the greeting via `send_message`, but the destinations system prompt also requires the final response to be wrapped in `` blocks (since 1d4d920). The agent followed both, sending the greeting once via the MCP tool and once via the wrapped final output. - welcome/SKILL.md: drop the mechanism — "send a short, warm greeting" lets the system prompt steer how it's delivered. - destinations.ts: reframe `` blocks and `send_message` as the same delivery surface, with the explicit note that each call/block lands as its own message — so they compose into a sequence rather than reading as additive duplicates of the same content. Co-Authored-By: Claude Opus 4.7 (1M context) --- container/agent-runner/src/destinations.test.ts | 12 ++++++------ container/agent-runner/src/destinations.ts | 12 ++++++------ container/skills/welcome/SKILL.md | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/container/agent-runner/src/destinations.test.ts b/container/agent-runner/src/destinations.test.ts index 807f0a623..61e5f4bb3 100644 --- a/container/agent-runner/src/destinations.test.ts +++ b/container/agent-runner/src/destinations.test.ts @@ -27,18 +27,18 @@ describe('buildSystemPromptAddendum — multi-destination routing guidance', () const prompt = buildSystemPromptAddendum('Casa'); - expect(prompt).toContain('Default routing'); + expect(prompt).toContain('default to addressing the destination it came `from`'); expect(prompt).toContain('from="name"'); expect(prompt).toContain('`casa`'); expect(prompt).toContain('`whatsapp-mg-17780`'); }); - it('requires explicit wrapping even for a single destination', () => { + it('describes message wrapping for a single destination', () => { seedDestination('casa', 'Casa', 'whatsapp', 'group-1@g.us'); const prompt = buildSystemPromptAddendum('Casa'); - expect(prompt).toContain('All output must be wrapped'); + expect(prompt).toContain('Wrap each delivered message'); expect(prompt).toContain(''); expect(prompt).toContain('`casa`'); }); @@ -47,7 +47,7 @@ describe('buildSystemPromptAddendum — multi-destination routing guidance', () const prompt = buildSystemPromptAddendum('Casa'); expect(prompt).toContain('no configured destinations'); - expect(prompt).not.toContain('Default routing'); + expect(prompt).not.toContain('default to addressing'); }); it('includes default-routing and wrapping instructions for single destination', () => { @@ -55,9 +55,9 @@ describe('buildSystemPromptAddendum — multi-destination routing guidance', () const prompt = buildSystemPromptAddendum('Casa'); - expect(prompt).toContain('All output must be wrapped'); + expect(prompt).toContain('Wrap each delivered message'); expect(prompt).toContain(''); - expect(prompt).toContain('Default routing'); + expect(prompt).toContain('default to addressing the destination it came `from`'); expect(prompt).toContain('`casa`'); }); }); diff --git a/container/agent-runner/src/destinations.ts b/container/agent-runner/src/destinations.ts index fec0b4e16..e68e9a962 100644 --- a/container/agent-runner/src/destinations.ts +++ b/container/agent-runner/src/destinations.ts @@ -115,16 +115,16 @@ function buildDestinationsSection(): string { } } lines.push(''); - lines.push('**All output must be wrapped.** Use `...` for content to send, or `...` for scratchpad.'); - lines.push('You can include multiple `` blocks in one response to send to multiple destinations.'); - lines.push('Bare text (outside of `` or `` blocks) is not allowed and will not be delivered.'); - lines.push(''); lines.push( - '**Default routing**: when replying to an incoming message, address the same destination the message came `from` — every inbound `` tag carries a `from="name"` attribute that names the origin destination. Only address a different destination when the request itself asks you to (e.g., "tell Laura that…").', + 'Wrap each delivered message in a `` block; include several blocks in one response to address several destinations. `` marks thinking you don\'t want sent — anything outside these tags is also treated as scratchpad.', ); lines.push(''); lines.push( - 'To send a message mid-response (e.g., an acknowledgment before a long task), call the `send_message` MCP tool with the `to` parameter set to a destination name.', + 'When replying to an incoming message, default to addressing the destination it came `from` (every inbound `` tag carries a `from="name"` attribute). Pick a different destination when the request asks for it (e.g., "tell Laura that…").', + ); + lines.push(''); + lines.push( + 'The `send_message` MCP tool is the same delivery, available mid-turn — handy for a quick acknowledgment ("on it") before a slow tool call. Each `send_message` call and each final-response `` block lands as its own message in the conversation, so they read as a sequence rather than as one combined reply.', ); return lines.join('\n'); } diff --git a/container/skills/welcome/SKILL.md b/container/skills/welcome/SKILL.md index c540e862b..063b794fe 100644 --- a/container/skills/welcome/SKILL.md +++ b/container/skills/welcome/SKILL.md @@ -9,7 +9,7 @@ You've just been connected to a new user. This your time to shine and make a str ## What to do -1. Send a short, warm greeting using `send_message` +1. Send a short, warm greeting 2. State your name (from your system prompt / CLAUDE.md) 3. Signal that you're capable of a lot — but don't list everything upfront. Be intriguing, not encyclopedic 4. Ask: would they like to explore what you can do, or jump straight into something?