mirror of
https://github.com/stablyai/orca.git
synced 2026-10-13 08:02:52 +00:00
fix: prefer automation transcript output
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createAutomationRunOutputSnapshotBuffer } from './automation-run-output-snapshot'
|
||||
import {
|
||||
createAutomationRunOutputSnapshotBuffer,
|
||||
createAutomationRunOutputSnapshotFromText,
|
||||
selectAutomationRunOutputSnapshot
|
||||
} from './automation-run-output-snapshot'
|
||||
|
||||
describe('automation run output snapshot buffer', () => {
|
||||
beforeEach(() => {
|
||||
@@ -68,4 +72,26 @@ describe('automation run output snapshot buffer', () => {
|
||||
content: 'LoadingDone'
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a saved snapshot from agent transcript text', () => {
|
||||
expect(createAutomationRunOutputSnapshotFromText('\nFinal summary.\n')).toEqual({
|
||||
format: 'plain_text',
|
||||
content: 'Final summary.',
|
||||
capturedAt: new Date('2026-05-16T12:00:00Z').getTime(),
|
||||
truncated: false
|
||||
})
|
||||
})
|
||||
|
||||
it('prefers agent transcript text over raw terminal redraw output', () => {
|
||||
const rawTerminalSnapshot = createAutomationRunOutputSnapshotFromText(
|
||||
'q;\u2834 orca q\u2022Working q q'
|
||||
)
|
||||
|
||||
expect(selectAutomationRunOutputSnapshot('Posted to #releases.', rawTerminalSnapshot)).toEqual({
|
||||
format: 'plain_text',
|
||||
content: 'Posted to #releases.',
|
||||
capturedAt: new Date('2026-05-16T12:00:00Z').getTime(),
|
||||
truncated: false
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -17,6 +17,31 @@ export type AutomationRunOutputSnapshotBuffer = {
|
||||
snapshot: () => AutomationRunOutputSnapshot | null
|
||||
}
|
||||
|
||||
export function createAutomationRunOutputSnapshotFromText(
|
||||
content: string,
|
||||
truncated = false
|
||||
): AutomationRunOutputSnapshot | null {
|
||||
const trimmed = content.trim()
|
||||
if (!trimmed) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
format: 'plain_text',
|
||||
content: trimmed,
|
||||
capturedAt: Date.now(),
|
||||
truncated
|
||||
}
|
||||
}
|
||||
|
||||
export function selectAutomationRunOutputSnapshot(
|
||||
assistantMessage: string | null | undefined,
|
||||
terminalSnapshot: AutomationRunOutputSnapshot | null
|
||||
): AutomationRunOutputSnapshot | null {
|
||||
// Why: raw hidden-PTY captures include full-screen TUI redraws; hook
|
||||
// transcript text is the user-facing automation result when available.
|
||||
return createAutomationRunOutputSnapshotFromText(assistantMessage ?? '') ?? terminalSnapshot
|
||||
}
|
||||
|
||||
function stripTerminalControls(value: string): string {
|
||||
return value
|
||||
.replace(OSC_SEQUENCE_PATTERN, '')
|
||||
@@ -52,15 +77,7 @@ export function createAutomationRunOutputSnapshotBuffer(): AutomationRunOutputSn
|
||||
},
|
||||
snapshot() {
|
||||
const content = stripTerminalControls(chunks.join('')).trim()
|
||||
if (!content) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
format: 'plain_text',
|
||||
content,
|
||||
capturedAt: Date.now(),
|
||||
truncated
|
||||
}
|
||||
return createAutomationRunOutputSnapshotFromText(content, truncated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ import { launchAgentBackgroundSession } from '@/lib/launch-agent-background-sess
|
||||
import { useAppStore } from '@/store'
|
||||
import type { AutomationDispatchResult } from '../../../shared/automations-types'
|
||||
import { parsePaneKey } from '../../../shared/stable-pane-id'
|
||||
import { createAutomationRunOutputSnapshotBuffer } from '@/components/automations/automation-run-output-snapshot'
|
||||
import {
|
||||
createAutomationRunOutputSnapshotBuffer,
|
||||
selectAutomationRunOutputSnapshot
|
||||
} from '@/components/automations/automation-run-output-snapshot'
|
||||
|
||||
const AUTOMATIONS_CHANGED_EVENT = 'orca:automations-changed'
|
||||
|
||||
@@ -122,6 +125,9 @@ export function useAutomationDispatchEvents(): void {
|
||||
dispatchWorkspaceDisplayName = worktree.displayName
|
||||
|
||||
const outputSnapshotBuffer = createAutomationRunOutputSnapshotBuffer()
|
||||
let latestAssistantMessage: string | null = null
|
||||
const getOutputSnapshot = () =>
|
||||
selectAutomationRunOutputSnapshot(latestAssistantMessage, outputSnapshotBuffer.snapshot())
|
||||
let dispatchMarked = false
|
||||
let pendingExitCode: number | null = null
|
||||
let pendingDone = false
|
||||
@@ -138,7 +144,7 @@ export function useAutomationDispatchEvents(): void {
|
||||
status: 'completed',
|
||||
workspaceId: worktree.id,
|
||||
workspaceDisplayName: worktree.displayName,
|
||||
outputSnapshot: outputSnapshotBuffer.snapshot(),
|
||||
outputSnapshot: getOutputSnapshot(),
|
||||
error: null
|
||||
})
|
||||
}
|
||||
@@ -149,7 +155,7 @@ export function useAutomationDispatchEvents(): void {
|
||||
status: code === 0 ? 'completed' : 'dispatch_failed',
|
||||
workspaceId: worktree.id,
|
||||
workspaceDisplayName: worktree.displayName,
|
||||
outputSnapshot: outputSnapshotBuffer.snapshot(),
|
||||
outputSnapshot: getOutputSnapshot(),
|
||||
error: code === 0 ? null : `Automation process exited with code ${code}.`
|
||||
})
|
||||
}
|
||||
@@ -169,6 +175,7 @@ export function useAutomationDispatchEvents(): void {
|
||||
for (const [paneKey, entry] of Object.entries(agentStatusByPaneKey)) {
|
||||
const parsed = parsePaneKey(paneKey)
|
||||
if (parsed?.tabId === tabId && entry.state === 'done') {
|
||||
latestAssistantMessage = entry.lastAssistantMessage?.trim() || latestAssistantMessage
|
||||
handleAgentDone()
|
||||
return
|
||||
}
|
||||
@@ -189,6 +196,7 @@ export function useAutomationDispatchEvents(): void {
|
||||
outputSnapshotBuffer.append(chunk)
|
||||
},
|
||||
onAgentStatus: (payload) => {
|
||||
latestAssistantMessage = payload.lastAssistantMessage?.trim() || latestAssistantMessage
|
||||
if (payload.state !== 'done') {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user