From 66a5ab6fabf4ff4b5111dadd112365116cce76bb Mon Sep 17 00:00:00 2001 From: "@daniel-lxs" <57051444+daniel-lxs@users.noreply.github.com> Date: Sat, 12 Sep 2026 08:06:08 +0000 Subject: [PATCH] fix: stop editing Telegram live task messages to Completed --- .../telegram-live-task-no-completed-edit.md | 6 +++ .../fixtures/telegram-live-task-message.txt | 5 -- .../telegram-live-task-message.test.ts | 4 -- .../src/telegram-live-task-message.ts | 3 -- .../lib/telegram-live-task-stream.test.ts | 49 +++++++++++++++---- .../server/lib/telegram-live-task-stream.ts | 14 ++++-- 6 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 .changeset/telegram-live-task-no-completed-edit.md diff --git a/.changeset/telegram-live-task-no-completed-edit.md b/.changeset/telegram-live-task-no-completed-edit.md new file mode 100644 index 000000000..1154dba6d --- /dev/null +++ b/.changeset/telegram-live-task-no-completed-edit.md @@ -0,0 +1,6 @@ +--- +'@roomote/communication': patch +'@roomote/sdk': patch +--- + +Telegram live coding-task messages no longer get edited to a "Completed." status when a task finishes successfully. The last live update stays visible as-is, and a resumed run keeps updating that same message with current progress. diff --git a/packages/communication/src/__tests__/fixtures/telegram-live-task-message.txt b/packages/communication/src/__tests__/fixtures/telegram-live-task-message.txt index a1a0cb086..23e5d5deb 100644 --- a/packages/communication/src/__tests__/fixtures/telegram-live-task-message.txt +++ b/packages/communication/src/__tests__/fixtures/telegram-live-task-message.txt @@ -10,11 +10,6 @@ Waiting for your input… Open in Roomote: https://roomote.example/sessions/session-1?task=task-1&utm_source=telegram -COMPLETED -Completed. - -Open in Roomote: https://roomote.example/sessions/session-1?task=task-1&utm_source=telegram - FAILED Task failed. diff --git a/packages/communication/src/__tests__/telegram-live-task-message.test.ts b/packages/communication/src/__tests__/telegram-live-task-message.test.ts index 06affc73b..b4d9341fb 100644 --- a/packages/communication/src/__tests__/telegram-live-task-message.test.ts +++ b/packages/communication/src/__tests__/telegram-live-task-message.test.ts @@ -30,7 +30,6 @@ describe('buildTelegramLiveTaskMessage', () => { it.each([ ['waiting', 'Waiting for your input…'], - ['completed', 'Completed.'], ['failed', 'Task failed.'], ['stopped', 'Stopped.'], ] as const)('formats %s as one compact line', (status, expected) => { @@ -73,9 +72,6 @@ describe('buildTelegramLiveTaskMessage', () => { 'WAITING', buildTelegramLiveTaskMessage({ status: 'waiting', taskUrl }).text, '', - 'COMPLETED', - buildTelegramLiveTaskMessage({ status: 'completed', taskUrl }).text, - '', 'FAILED', buildTelegramLiveTaskMessage({ status: 'failed', taskUrl }).text, '', diff --git a/packages/communication/src/telegram-live-task-message.ts b/packages/communication/src/telegram-live-task-message.ts index 69ccd5e4b..bb4ae599d 100644 --- a/packages/communication/src/telegram-live-task-message.ts +++ b/packages/communication/src/telegram-live-task-message.ts @@ -3,7 +3,6 @@ import { TELEGRAM_MAX_MESSAGE_LENGTH } from './telegram-format'; export type TelegramLiveTaskStatus = | 'running' | 'waiting' - | 'completed' | 'failed' | 'stopped'; @@ -49,8 +48,6 @@ function getStatusText(status: TelegramLiveTaskStatus): string { return 'Starting task…'; case 'waiting': return 'Waiting for your input…'; - case 'completed': - return 'Completed.'; case 'failed': return 'Task failed.'; case 'stopped': diff --git a/packages/sdk/src/server/lib/telegram-live-task-stream.test.ts b/packages/sdk/src/server/lib/telegram-live-task-stream.test.ts index 88abb2ec6..76d068bd2 100644 --- a/packages/sdk/src/server/lib/telegram-live-task-stream.test.ts +++ b/packages/sdk/src/server/lib/telegram-live-task-stream.test.ts @@ -124,20 +124,52 @@ describe('Telegram live task stream', () => { ); }); + it('leaves the live message untouched on completion and resumes editing it later', async () => { + await start(); + mocks.editMessageText.mockClear(); + mocks.createProvider.mockClear(); + + await expect( + renderTelegramLiveTaskStream({ + taskId: 'task-1', + status: 'complete', + output: 'Authoritative final response.', + }), + ).resolves.toEqual({ card: true, updated: true }); + + expect(mocks.createProvider).not.toHaveBeenCalled(); + expect(mocks.editMessageText).not.toHaveBeenCalled(); + + await renderTelegramLiveTaskStream({ + taskId: 'task-1', + status: 'in_progress', + details: 'A resumed run is working.', + }); + + expect(mocks.editMessageText).toHaveBeenCalledExactlyOnceWith( + expect.objectContaining({ + channelId: '-1001', + messageId: '88', + text: expect.stringMatching( + /^A resumed run is working\.\n\nOpen in Roomote:/, + ), + }), + ); + }); + it.each([ - ['complete', 'Authoritative final response.', 'Completed'], - ['error', 'Stopped because of an error.', 'Failed'], - ['error', 'Stopped.', 'Stopped'], + ['Stopped because of an error.', 'Failed'], + ['Stopped.', 'Stopped'], ] as const)( - 'renders %s as a terminal status-only edit', - async (status, output, label) => { + 'renders an error as a %s terminal status-only edit', + async (output, label) => { await start(); mocks.editMessageText.mockClear(); await renderTelegramLiveTaskStream({ taskId: 'task-1', - status, - ...(output ? { output } : {}), + status: 'error', + output, }); const edit = mocks.editMessageText.mock.calls[0]?.[0] as { @@ -146,10 +178,9 @@ describe('Telegram live task stream', () => { }; expect(edit.text).toMatch( new RegExp( - `^${label === 'Completed' ? 'Completed\\.' : label === 'Failed' ? 'Task failed\\.' : 'Stopped\\.'}\\n\\nOpen in Roomote:`, + `^${label === 'Failed' ? 'Task failed\\.' : 'Stopped\\.'}\\n\\nOpen in Roomote:`, ), ); - expect(edit.text).not.toContain('Authoritative final response.'); expect(edit.text).not.toContain('Stopped because of an error.'); }, ); diff --git a/packages/sdk/src/server/lib/telegram-live-task-stream.ts b/packages/sdk/src/server/lib/telegram-live-task-stream.ts index 27d847db3..9bc9ecb65 100644 --- a/packages/sdk/src/server/lib/telegram-live-task-stream.ts +++ b/packages/sdk/src/server/lib/telegram-live-task-stream.ts @@ -169,6 +169,12 @@ export async function renderTelegramLiveTaskStream(input: { const data = await getTelegramLiveTaskStreamData(input.taskId); if (!data) return { card: false, updated: false }; + // The owning Fast Session posts the successful result. Preserve the live + // message and its pointer so a resumed run can continue editing it. + if (input.status === 'complete') { + return { card: true, updated: true }; + } + const provider = await createTelegramCommunicationProviderFromRuntimeCredentials(); if (!provider) return { card: false, updated: false }; @@ -179,11 +185,9 @@ export async function renderTelegramLiveTaskStream(input: { ? input.details?.trim() === 'Waiting for your input…' ? 'waiting' : 'running' - : input.status === 'complete' - ? 'completed' - : input.output === 'Stopped.' - ? 'stopped' - : 'failed'; + : input.output === 'Stopped.' + ? 'stopped' + : 'failed'; await provider.editMessageText({ channelId: data.channelId, messageId: data.messageId,