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.
This commit is contained in:
Jinjing
2026-07-10 00:09:21 -07:00
parent 830024dc2e
commit b6ee45b6c0
2 changed files with 61 additions and 3 deletions
@@ -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', () => {
@@ -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
}