fix(omp): load task prefill through the status extension

This commit is contained in:
Neil
2026-09-14 03:52:20 -07:00
parent b87a6c0f23
commit 681ec4bcbf
5 changed files with 92 additions and 8 deletions
@@ -0,0 +1,63 @@
import { describe, expect, it, vi } from 'vitest'
import { createAgentStatusExtensionHarness } from './agent-status-extension-test-harness'
describe('OMP prefill through the explicitly loaded status extension', () => {
it('sets a reasonless startup draft once without submitting', async () => {
const h = createAgentStatusExtensionHarness({
kind: 'omp',
env: { ORCA_OMP_PREFILL: 'Fix task\nKeep details' }
})
const setEditorText = vi.fn()
await h.callHook('session_start', {}, { ui: { setEditorText } })
expect(setEditorText).toHaveBeenCalledExactlyOnceWith('Fix task\nKeep details')
expect(h.processEnv.ORCA_OMP_PREFILL).toBeUndefined()
await h.callHook('session_start', {}, { ui: { setEditorText } })
h.reload()
await h.callHook('session_start', {}, { ui: { setEditorText } })
expect(setEditorText).toHaveBeenCalledTimes(1)
expect(h.fetchMock).not.toHaveBeenCalled()
})
it('preserves the draft until an editor is available', async () => {
const h = createAgentStatusExtensionHarness({ kind: 'omp', env: { ORCA_OMP_PREFILL: 'Draft' } })
await h.callHook('session_start', {}, {})
expect(h.processEnv.ORCA_OMP_PREFILL).toBe('Draft')
const noopEditor = vi.fn()
await h.callHook('session_start', {}, { hasUI: false, ui: { setEditorText: noopEditor } })
expect(noopEditor).not.toHaveBeenCalled()
expect(h.processEnv.ORCA_OMP_PREFILL).toBe('Draft')
const setEditorText = vi.fn()
await h.callHook('session_start', {}, { ui: { setEditorText } })
expect(setEditorText).toHaveBeenCalledExactlyOnceWith('Draft')
})
it('never consumes a Pi draft in an OMP process', async () => {
const h = createAgentStatusExtensionHarness({
kind: 'omp',
env: { ORCA_PI_PREFILL: 'Pi only' }
})
const setEditorText = vi.fn()
await h.callHook('session_start', {}, { ui: { setEditorText } })
expect(setEditorText).not.toHaveBeenCalled()
expect(h.processEnv.ORCA_PI_PREFILL).toBe('Pi only')
})
it('leaves the draft alone outside an Orca pane', async () => {
const h = createAgentStatusExtensionHarness({
kind: 'omp',
env: { ORCA_PANE_KEY: undefined, ORCA_OMP_PREFILL: 'Draft' }
})
const setEditorText = vi.fn()
await h.callHook('session_start', {}, { ui: { setEditorText } })
expect(setEditorText).not.toHaveBeenCalled()
expect(h.processEnv.ORCA_OMP_PREFILL).toBe('Draft')
})
it('does not let a nested process consume the owner draft', () => {
const h = createAgentStatusExtensionHarness({
kind: 'omp',
env: { ORCA_PI_STATUS_OWNED: '999', ORCA_OMP_PREFILL: 'Owner draft' }
})
expect(h.handlers.session_start).toBeUndefined()
expect(h.processEnv.ORCA_OMP_PREFILL).toBe('Owner draft')
})
})
@@ -6,6 +6,8 @@ import { vi } from 'vitest'
import { getPiAgentStatusExtensionSource } from './agent-status-extension-source'
export type HookContext = {
hasUI?: boolean
ui?: { setEditorText?: (text: string) => void }
isIdle?: () => boolean
sessionManager?: {
getSessionId?: () => unknown
@@ -1,3 +1,4 @@
import { getPiPrefillHandlerSourceLines } from './prefill-extension-source'
import type { PiAgentKind } from '../../shared/pi-agent-kind'
import { getPiAgentStatusUiPromptHandlerSourceLines } from './agent-status-ui-prompt-source'
@@ -115,6 +116,7 @@ export function getPiAgentStatusHandlerSourceLines(kind: PiAgentKind): string[]
' if (ownerPid && ownerPid !== selfPid && isStatusOwnerAlive(ownerPid)) return',
` process.env.${ownerEnv} = selfPid`,
...sessionStartHandler,
...(kind === 'omp' ? getPiPrefillHandlerSourceLines('omp') : []),
` pi.on('before_agent_start', (event${ctxParam}) => {`,
...captureSessionMetadata,
" post('before_agent_start', { prompt: event.prompt ?? '' })",
@@ -0,0 +1,14 @@
import { describe, expect, it } from 'vitest'
import { getPiPrefillExtensionSource } from './prefill-extension-source'
describe('getPiPrefillExtensionSource', () => {
it('accepts OMP session_start events without a reason field', () => {
const source = getPiPrefillExtensionSource('omp')
expect(source).toContain('process.env.ORCA_OMP_PREFILL')
expect(source).not.toContain("event.reason !== 'startup'")
})
it('keeps Pi startup reason filtering', () => {
expect(getPiPrefillExtensionSource('pi')).toContain("event.reason !== 'startup'")
})
})
+11 -8
View File
@@ -13,20 +13,23 @@ const PREFILL_ENV_VAR_BY_KIND: Record<PrefillAgentKind, string> = {
}
export function getPiPrefillExtensionSource(kind: PrefillAgentKind): string {
return ['export default function (pi) {', ...getPiPrefillHandlerSourceLines(kind), '}', ''].join(
'\n'
)
}
export function getPiPrefillHandlerSourceLines(kind: PrefillAgentKind): string[] {
const envVar = PREFILL_ENV_VAR_BY_KIND[kind]
return [
'export default function (pi) {',
" pi.on('session_start', async (event, ctx) => {",
' if (!process.env.ORCA_PANE_KEY) return',
" if (event.reason !== 'startup') return",
' if (!process.env.ORCA_PANE_KEY || ctx?.hasUI === false) return',
...(kind === 'pi' ? [" if (event.reason !== 'startup') return"] : []),
` const prefill = process.env.${envVar}`,
' if (!prefill) return',
" if (!prefill || typeof ctx?.ui?.setEditorText !== 'function') return",
` delete process.env.${envVar}`,
' try {',
' ctx.ui.setEditorText(prefill)',
' } catch {}',
' })',
'}',
''
].join('\n')
' })'
]
}