From b6ee45b6c0850cd59c607c5dd3f8886f28e8a270 Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:09:21 -0700 Subject: [PATCH] Fix task ID parsing for normalized single-line dispatch prompts Splitting on newline alone left trailing text attached to the task ID once normalizeSingleLinePreview folded newlines to spaces, so getOrcaDispatchTaskId never matched in production status prompts. Delimit on the first whitespace instead, and add regression tests covering both the normalized and raw multi-line prompt shapes. --- .../src/lib/agent-row-primary-text.test.ts | 54 +++++++++++++++++++ .../src/lib/agent-row-primary-text.ts | 10 ++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/lib/agent-row-primary-text.test.ts b/src/renderer/src/lib/agent-row-primary-text.test.ts index b0360588c59..e6a0094a94a 100644 --- a/src/renderer/src/lib/agent-row-primary-text.test.ts +++ b/src/renderer/src/lib/agent-row-primary-text.test.ts @@ -1,7 +1,9 @@ import { describe, expect, it } from 'vitest' +import { normalizeAgentStatusPayload } from '../../../shared/agent-status-types' import { getAgentRowGeneratedTitleText, getAgentRowPrimaryText, + getOrcaDispatchTaskId, isOrcaDispatchPrompt } from './agent-row-primary-text' @@ -72,6 +74,58 @@ Keep the raw preamble out of the sidebar.` it('falls back to the raw prompt outside orchestration workers', () => { expect(getAgentRowPrimaryText({ prompt: 'Fix checkout race' })).toBe('Fix checkout race') }) + + // Why: production status prompts reach these helpers already folded to a + // single line and capped at 200 chars by normalizeAgentStatusPayload. Guard + // the real normalized shape — earlier tests only fed raw multi-line prompts, + // which hid that the task-id parser split on \n and never matched. + it('matches orchestration labels on a normalized single-line dispatch prompt', () => { + const normalized = normalizeAgentStatusPayload({ + state: 'working', + prompt: `You are working inside Orca, a multi-agent IDE. You are a dispatched worker. +Your coordinator's terminal handle is: term_parent +Your task ID is: task_9f3ab2 + +You talk to the coordinator only through the CLI commands below. + +=== TASK === +Fix the checkout race condition in payments` + }) + expect(normalized).not.toBeNull() + expect( + getAgentRowPrimaryText({ + prompt: normalized!.prompt, + orchestration: { + taskId: 'task_9f3ab2', + dispatchId: 'ctx-1', + taskTitle: 'Checkout race', + displayName: 'Fix checkout race' + } + }) + ).toBe('Fix checkout race') + }) +}) + +describe('getOrcaDispatchTaskId', () => { + it('extracts the id when the trailing newline was folded to a space', () => { + const normalized = normalizeAgentStatusPayload({ + state: 'working', + prompt: `You are working inside Orca, a multi-agent IDE. You are a dispatched worker. +Your task ID is: task_9f3ab2 + +=== TASK === +body` + }) + expect(getOrcaDispatchTaskId(normalized!.prompt)).toBe('task_9f3ab2') + }) + + it('extracts the id from a raw multi-line prompt', () => { + expect( + getOrcaDispatchTaskId( + `You are working inside Orca, a multi-agent IDE.\nYour task ID is: task_1\n\n=== TASK ===\nbody` + ) + ).toBe('task_1') + }) }) describe('isOrcaDispatchPrompt / getAgentRowGeneratedTitleText', () => { diff --git a/src/renderer/src/lib/agent-row-primary-text.ts b/src/renderer/src/lib/agent-row-primary-text.ts index 931dd1fbbdc..b75bfafb0b4 100644 --- a/src/renderer/src/lib/agent-row-primary-text.ts +++ b/src/renderer/src/lib/agent-row-primary-text.ts @@ -84,9 +84,13 @@ export function getOrcaDispatchTaskId(prompt: string): string | null { if (markerIndex === -1) { return null } - const afterMarker = scan.slice(markerIndex + ORCA_DISPATCH_TASK_ID_MARKER.length) - const lineEnd = afterMarker.search(/\r|\n/) - const idLine = (lineEnd === -1 ? afterMarker : afterMarker.slice(0, lineEnd)).trim() + // Why: delimit on the first whitespace, not just a newline. The task id is a + // whitespace-free token, and by the time this parses a live status prompt the + // trailing newline has been folded to a space by normalizeSingleLinePreview — + // splitting on \n alone would return the id plus the rest of the preamble. + const afterMarker = scan.slice(markerIndex + ORCA_DISPATCH_TASK_ID_MARKER.length).trimStart() + const idEnd = afterMarker.search(/\s/) + const idLine = idEnd === -1 ? afterMarker : afterMarker.slice(0, idEnd) return idLine || null }