From 8c98ad9faf79e332c2854e112e3cc733a06a9030 Mon Sep 17 00:00:00 2001 From: Eyejoker Date: Mon, 23 Mar 2026 19:29:16 +0900 Subject: [PATCH] fix: intermediate text as standalone messages, preserve progress Add 'intermediate' phase for assistant text between tool calls. These are sent as separate Discord messages without finalizing or disrupting the active progress message. --- runners/agent-runner/src/index.ts | 6 ++++-- src/agent-runner.ts | 2 +- src/message-turn-controller.ts | 11 +++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/runners/agent-runner/src/index.ts b/runners/agent-runner/src/index.ts index 07a82db..a951ac2 100644 --- a/runners/agent-runner/src/index.ts +++ b/runners/agent-runner/src/index.ts @@ -32,7 +32,7 @@ interface ContainerInput { interface ContainerOutput { status: 'success' | 'error'; - phase?: 'progress' | 'final' | 'tool-activity'; + phase?: 'progress' | 'final' | 'tool-activity' | 'intermediate'; result: string | null; newSessionId?: string; error?: string; @@ -546,6 +546,7 @@ async function runQuery( if (message.type !== 'assistant' && pendingProgressText) { writeOutput({ status: 'success', + phase: 'intermediate', result: pendingProgressText, newSessionId, }); @@ -625,7 +626,7 @@ async function runQuery( log(`Discarding pending progress (matches result)`); pendingProgressText = null; } else if (pendingProgressText) { - writeOutput({ status: 'success', result: pendingProgressText, newSessionId }); + writeOutput({ status: 'success', phase: 'intermediate', result: pendingProgressText, newSessionId }); pendingProgressText = null; } log(`Result #${resultCount}: subtype=${message.subtype}${textResult ? ` text=${textResult.slice(0, 200)}` : ''}`); @@ -700,6 +701,7 @@ async function runQuery( if (pendingProgressText) { writeOutput({ status: 'success', + phase: 'intermediate', result: pendingProgressText, newSessionId, }); diff --git a/src/agent-runner.ts b/src/agent-runner.ts index 37bba21..b3a7b55 100644 --- a/src/agent-runner.ts +++ b/src/agent-runner.ts @@ -41,7 +41,7 @@ export interface AgentInput { export interface AgentOutput { status: 'success' | 'error'; result: string | null; - phase?: 'progress' | 'final' | 'tool-activity'; + phase?: 'progress' | 'final' | 'tool-activity' | 'intermediate'; newSessionId?: string; error?: string; } diff --git a/src/message-turn-controller.ts b/src/message-turn-controller.ts index 5b8e8fc..348f21a 100644 --- a/src/message-turn-controller.ts +++ b/src/message-turn-controller.ts @@ -105,6 +105,17 @@ export class MessageTurnController { ); } + if (result.phase === 'intermediate') { + // Send as standalone message without touching progress state + if (text) { + await this.options.channel.sendMessage(this.options.chatJid, text); + } + if (!this.poisonedSessionDetected) { + this.resetIdleTimer(); + } + return; + } + if (result.phase === 'tool-activity') { // Ensure a progress message exists for tool activity sub-lines if (!this.progressMessageId && !this.progressCreating) {