mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
Answer the structured-session support probe without installing the host (#18695)
* 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. * test(runtime): cover structured support probe parity --------- Co-authored-by: Merge Sim <sim@local>
This commit is contained in:
co-authored by
Merge Sim
parent
2e80972450
commit
86cd327749
@@ -3,6 +3,8 @@ 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 { supportsClaudeStructuredLocation } from '../claude/claude-structured-location-support'
|
||||
import { getStructuredAgentSessionHost } from '../native-chat/agent-session-wire/structured-agent-session-registry'
|
||||
import { resolveStructuredAgentSessionCreateSupport } from '../native-chat/structured-agent-session-create-support'
|
||||
import { LOCAL_EXECUTION_HOST_ID } from '../../shared/execution-host'
|
||||
@@ -51,13 +53,13 @@ export class OrcaRuntimeWithResolveRecoveredStructuredTuiTranscript extends Orca
|
||||
agent: 'claude' | 'codex'
|
||||
): Promise<{ supported: boolean; reason?: 'agent' | 'remote' | 'wsl' }> {
|
||||
const location = await this.resolveStructuredAgentSessionLocation(worktreeSelector)
|
||||
await this.ensureStructuredAgentSessionHost()
|
||||
// The verdict lives in a typechecked module; this file is @ts-nocheck.
|
||||
return resolveStructuredAgentSessionCreateSupport({
|
||||
agent,
|
||||
location,
|
||||
adapterSupportsCreate:
|
||||
getStructuredAgentSessionHost()?.supportsCreate(location, agent) === true,
|
||||
agent === 'claude'
|
||||
? supportsClaudeStructuredLocation(location)
|
||||
: supportsCodexStructuredLocation(location),
|
||||
getSettings: () => this.requireStore().getSettings()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
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 }
|
||||
}
|
||||
|
||||
type TestLocation = {
|
||||
executionHostId: string
|
||||
wslDistro: string | null
|
||||
workspaceKind?: 'folder' | 'git-worktree'
|
||||
}
|
||||
|
||||
type SupportResult = {
|
||||
supported: boolean
|
||||
reason?: 'agent' | 'remote' | 'wsl'
|
||||
}
|
||||
|
||||
function createRuntime(location: TestLocation): 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: location.workspaceKind ?? 'git-worktree'
|
||||
}))
|
||||
return runtime
|
||||
}
|
||||
|
||||
async function expectSupportWithoutInstall(input: {
|
||||
agent: 'claude' | 'codex'
|
||||
location: TestLocation
|
||||
expected: SupportResult
|
||||
repetitions?: number
|
||||
}): Promise<void> {
|
||||
const runtime = createRuntime(input.location)
|
||||
const { effects, ensure } = stubStructuredHostInstall(runtime)
|
||||
|
||||
const answers: SupportResult[] = []
|
||||
for (let index = 0; index < (input.repetitions ?? 1); index += 1) {
|
||||
answers.push(
|
||||
await runtime.getStructuredAgentSessionCreateSupport('id:workspace-1', input.agent)
|
||||
)
|
||||
}
|
||||
|
||||
expect(answers).toEqual(Array(input.repetitions ?? 1).fill(input.expected))
|
||||
expect(ensure).not.toHaveBeenCalled()
|
||||
expect(effects).toEqual({
|
||||
storeOpened: false,
|
||||
writeGateAttached: false,
|
||||
reaperStarted: false
|
||||
})
|
||||
expect(getStructuredAgentSessionHost()).toBeNull()
|
||||
}
|
||||
|
||||
describe('structured agent-session create-support probe', () => {
|
||||
afterEach(() => {
|
||||
setStructuredAgentSessionHost(null)
|
||||
agentSessionPtyWriteGate.detachRecordLookup()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it.each(['codex', 'claude'] as const)(
|
||||
'answers %s support repeatedly without installing the host',
|
||||
async (agent) => {
|
||||
await expectSupportWithoutInstall({
|
||||
agent,
|
||||
location: { executionHostId: 'local', wslDistro: null },
|
||||
expected: { supported: true },
|
||||
repetitions: 3
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['codex', 'claude'] as const)(
|
||||
'still reports an unsupported remote %s location without installing the host',
|
||||
async (agent) => {
|
||||
await expectSupportWithoutInstall({
|
||||
agent,
|
||||
location: { executionHostId: 'ssh-host-1', wslDistro: null },
|
||||
expected: { supported: false, reason: 'remote' }
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['codex', 'claude'] as const)(
|
||||
'still reports an unsupported WSL %s location without installing the host',
|
||||
async (agent) => {
|
||||
await expectSupportWithoutInstall({
|
||||
agent,
|
||||
location: { executionHostId: 'local', wslDistro: 'Ubuntu' },
|
||||
expected: { supported: false, reason: 'wsl' }
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['codex', 'claude'] as const)(
|
||||
'supports a local folder workspace for %s without installing the host',
|
||||
async (agent) => {
|
||||
await expectSupportWithoutInstall({
|
||||
agent,
|
||||
location: {
|
||||
executionHostId: 'local',
|
||||
wslDistro: null,
|
||||
workspaceKind: 'folder'
|
||||
},
|
||||
expected: { supported: true }
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
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