mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 00:03:15 +00:00
Answer the structured-session support probe without installing the host
`getStructuredAgentSessionCreateSupport` called `ensureStructuredAgentSessionHost()` before answering, so a read-only "can you create a Codex session here?" question performed the create route's lifecycle work: the first install opens the durable agent-session record store, attaches the PTY write-gate record lookup and starts the orphan-child reaper. Ask the pure predicate instead. `supportsCreate` on the installed host resolves to `adapterSupportsCreate`, which for the Codex adapter is exactly `agent === 'codex' && supportsCodexStructuredLocation(location)` — no adapter instance is needed to answer it. Nothing is lost: the create/attach route still installs via `ensureStructuredHostInstalled`, and startup restoration still installs and reconciles when a store is already persisted.
This commit is contained in:
@@ -3,6 +3,7 @@ import { OrcaRuntimeWithStopStructuredSessionProcess } from './orca-runtime-stop
|
||||
import type { AgentSessionOwnerBinding } from '../../shared/agent-session-host-authority'
|
||||
import { agentSessionOwnerBindingsEqual } from '../../shared/claimed-agent-pty-owner-snapshot'
|
||||
import { resolvePinnedCodexRolloutProof } from '../codex/codex-tui-rollout-proof'
|
||||
import { supportsCodexStructuredLocation } from '../codex/codex-structured-location-support'
|
||||
import { getStructuredAgentSessionHost } from '../native-chat/agent-session-wire/structured-agent-session-registry'
|
||||
import { LOCAL_EXECUTION_HOST_ID } from '../../shared/execution-host'
|
||||
import type { AgentStatusIpcPayload } from '../../shared/agent-status-types'
|
||||
@@ -48,8 +49,10 @@ export class OrcaRuntimeWithResolveRecoveredStructuredTuiTranscript extends Orca
|
||||
agent: 'codex'
|
||||
): Promise<{ supported: boolean; reason?: 'agent' | 'remote' | 'wsl' }> {
|
||||
const location = await this.resolveStructuredAgentSessionLocation(worktreeSelector)
|
||||
await this.ensureStructuredAgentSessionHost()
|
||||
if (getStructuredAgentSessionHost()?.supportsCreate(location, agent)) {
|
||||
// Asking whether a create is possible must not perform the create's lifecycle work: installing
|
||||
// the host opens the durable record store, attaches the PTY write gate and starts the orphan
|
||||
// reaper. This is the predicate `supportsCreate` resolves to for the Codex adapter anyway.
|
||||
if (agent === 'codex' && supportsCodexStructuredLocation(location)) {
|
||||
return { supported: true }
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { OrcaRuntimeService } from './orca-runtime'
|
||||
import {
|
||||
getStructuredAgentSessionHost,
|
||||
setStructuredAgentSessionHost
|
||||
} from '../native-chat/agent-session-wire/structured-agent-session-registry'
|
||||
import { agentSessionPtyWriteGate } from './agent-session-pty-write-gate'
|
||||
|
||||
type InstallEffects = {
|
||||
storeOpened: boolean
|
||||
writeGateAttached: boolean
|
||||
reaperStarted: boolean
|
||||
}
|
||||
|
||||
/** Stands in for `install()` by performing the three effects it performs, so a probe that
|
||||
* reinstalls the host is caught by what the install *does*, not by a call count alone. */
|
||||
function stubStructuredHostInstall(runtime: OrcaRuntimeService): {
|
||||
effects: InstallEffects
|
||||
ensure: ReturnType<typeof vi.fn>
|
||||
} {
|
||||
const effects: InstallEffects = {
|
||||
storeOpened: false,
|
||||
writeGateAttached: false,
|
||||
reaperStarted: false
|
||||
}
|
||||
// `supportsCreate` answers as the real Codex adapter would, so a probe that reinstalls the host
|
||||
// still returns the right answer and fails on the install effects alone.
|
||||
const host = {
|
||||
reconcileRestartLeases: vi.fn(async () => {}),
|
||||
supportsCreate: (location: { executionHostId: string; wslDistro: string | null }) =>
|
||||
location.executionHostId === 'local' && location.wslDistro === null
|
||||
}
|
||||
const ensure = vi.fn(async () => {
|
||||
effects.storeOpened = true
|
||||
effects.reaperStarted = true
|
||||
agentSessionPtyWriteGate.attachRecordLookup(() => null)
|
||||
effects.writeGateAttached = true
|
||||
setStructuredAgentSessionHost(host as never)
|
||||
})
|
||||
vi.spyOn(runtime, 'ensureStructuredAgentSessionHost').mockImplementation(ensure)
|
||||
return { effects, ensure }
|
||||
}
|
||||
|
||||
function createRuntime(location: {
|
||||
executionHostId: string
|
||||
wslDistro: string | null
|
||||
}): OrcaRuntimeService {
|
||||
const runtime = new OrcaRuntimeService({ getSettings: () => ({}) } as never)
|
||||
const internal = runtime as unknown as {
|
||||
resolveStructuredAgentSessionLocation: () => Promise<unknown>
|
||||
}
|
||||
internal.resolveStructuredAgentSessionLocation = vi.fn(async () => ({
|
||||
executionHostId: location.executionHostId,
|
||||
wslDistro: location.wslDistro,
|
||||
workspaceId: 'workspace-1',
|
||||
workspaceKind: 'git-worktree' as const
|
||||
}))
|
||||
return runtime
|
||||
}
|
||||
|
||||
describe('structured agent-session create-support probe', () => {
|
||||
afterEach(() => {
|
||||
setStructuredAgentSessionHost(null)
|
||||
agentSessionPtyWriteGate.detachRecordLookup()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('answers repeatedly without installing the host', async () => {
|
||||
const runtime = createRuntime({ executionHostId: 'local', wslDistro: null })
|
||||
const { effects, ensure } = stubStructuredHostInstall(runtime)
|
||||
|
||||
const answers = [
|
||||
await runtime.getStructuredAgentSessionCreateSupport('id:workspace-1', 'codex'),
|
||||
await runtime.getStructuredAgentSessionCreateSupport('id:workspace-1', 'codex'),
|
||||
await runtime.getStructuredAgentSessionCreateSupport('id:workspace-1', 'codex')
|
||||
]
|
||||
|
||||
expect(answers).toEqual([{ supported: true }, { supported: true }, { supported: true }])
|
||||
expect(ensure).not.toHaveBeenCalled()
|
||||
expect(effects).toEqual({
|
||||
storeOpened: false,
|
||||
writeGateAttached: false,
|
||||
reaperStarted: false
|
||||
})
|
||||
expect(getStructuredAgentSessionHost()).toBeNull()
|
||||
})
|
||||
|
||||
it('still reports an unsupported location without installing the host', async () => {
|
||||
const runtime = createRuntime({ executionHostId: 'ssh-host-1', wslDistro: null })
|
||||
const { effects, ensure } = stubStructuredHostInstall(runtime)
|
||||
|
||||
await expect(
|
||||
runtime.getStructuredAgentSessionCreateSupport('id:workspace-1', 'codex')
|
||||
).resolves.toEqual({ supported: false, reason: 'remote' })
|
||||
expect(ensure).not.toHaveBeenCalled()
|
||||
expect(effects.storeOpened).toBe(false)
|
||||
expect(getStructuredAgentSessionHost()).toBeNull()
|
||||
})
|
||||
|
||||
it('still installs and reconciles on startup when a store is already persisted', async () => {
|
||||
const runtime = createRuntime({ executionHostId: 'local', wslDistro: null })
|
||||
const { effects, ensure } = stubStructuredHostInstall(runtime)
|
||||
const internal = runtime as unknown as {
|
||||
hasPersistedStructuredAgentSessionStore: () => boolean
|
||||
refreshMobileSessionPtyRecords: () => Promise<void>
|
||||
}
|
||||
internal.hasPersistedStructuredAgentSessionStore = () => true
|
||||
internal.refreshMobileSessionPtyRecords = vi.fn(async () => {})
|
||||
|
||||
await runtime.prepareStructuredAgentSessionStartupRestoration()
|
||||
|
||||
expect(ensure).toHaveBeenCalledTimes(1)
|
||||
expect(effects).toEqual({
|
||||
storeOpened: true,
|
||||
writeGateAttached: true,
|
||||
reaperStarted: true
|
||||
})
|
||||
expect(
|
||||
(getStructuredAgentSessionHost() as unknown as { reconcileRestartLeases: () => void })
|
||||
.reconcileRestartLeases
|
||||
).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user