mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
fix(omp): publish owning session transcript paths
Adopt stablyai/orca#19529 on the child-session ownership fence. Preserve id-based resume and execution-host transcript boundaries. Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
This commit is contained in:
@@ -87,32 +87,40 @@ describe('resolveSessionFilePath on a Windows host with WSL', () => {
|
||||
expect(resolved).toBe(ROLLOUT_UNC)
|
||||
})
|
||||
|
||||
it('keeps an attested distro when another guest has the same transcript path', async () => {
|
||||
READABLE_WSL_UNC_PATHS.add(DEBIAN_ROLLOUT_UNC)
|
||||
it.each(['codex', 'omp'] as const)(
|
||||
'keeps an attested distro when another guest has the same transcript path (%s)',
|
||||
async (agent) => {
|
||||
READABLE_WSL_UNC_PATHS.add(DEBIAN_ROLLOUT_UNC)
|
||||
|
||||
const resolved = await resolveSessionFilePath('codex', 'wsl-sess', {
|
||||
transcriptPath: ROLLOUT_LINUX,
|
||||
wslDistro: 'Ubuntu',
|
||||
codexSessionsDirs: []
|
||||
})
|
||||
|
||||
expect(resolved).toBe(ROLLOUT_UNC)
|
||||
expect(vi.mocked(listWslDistrosAsync)).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(getWslHomeAsync)).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does not fall through to another guest when the attested path is missing', async () => {
|
||||
READABLE_WSL_UNC_PATHS.delete(ROLLOUT_UNC)
|
||||
READABLE_WSL_UNC_PATHS.add(DEBIAN_ROLLOUT_UNC)
|
||||
|
||||
await expect(
|
||||
resolveSessionFilePath('codex', 'wsl-sess', {
|
||||
const resolved = await resolveSessionFilePath(agent, 'wsl-sess', {
|
||||
transcriptPath: ROLLOUT_LINUX,
|
||||
wslDistro: 'Ubuntu',
|
||||
codexSessionsDirs: []
|
||||
})
|
||||
).resolves.toBeNull()
|
||||
})
|
||||
|
||||
expect(resolved).toBe(ROLLOUT_UNC)
|
||||
expect(vi.mocked(listWslDistrosAsync)).not.toHaveBeenCalled()
|
||||
expect(vi.mocked(getWslHomeAsync)).not.toHaveBeenCalled()
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['codex', 'omp'] as const)(
|
||||
'does not fall through to another guest when the attested path is missing (%s)',
|
||||
async (agent) => {
|
||||
READABLE_WSL_UNC_PATHS.delete(ROLLOUT_UNC)
|
||||
READABLE_WSL_UNC_PATHS.add(DEBIAN_ROLLOUT_UNC)
|
||||
scanned.hostRootHasRollout = true
|
||||
|
||||
await expect(
|
||||
resolveSessionFilePath(agent, 'wsl-sess', {
|
||||
transcriptPath: ROLLOUT_LINUX,
|
||||
wslDistro: 'Ubuntu',
|
||||
codexSessionsDirs: []
|
||||
})
|
||||
).resolves.toBeNull()
|
||||
expect(scanned.dirs).toEqual([])
|
||||
}
|
||||
)
|
||||
|
||||
it('does not return a UNC twin that no distro actually has', async () => {
|
||||
const resolved = await resolveSessionFilePath('codex', 'wsl-sess', {
|
||||
@@ -122,18 +130,21 @@ describe('resolveSessionFilePath on a Windows host with WSL', () => {
|
||||
expect(resolved).toBeNull()
|
||||
})
|
||||
|
||||
it('does not fall back by id from an unattested guest hook path', async () => {
|
||||
READABLE_WSL_UNC_PATHS.delete(ROLLOUT_UNC)
|
||||
scanned.hostRootHasRollout = true
|
||||
it.each(['codex', 'omp'] as const)(
|
||||
'does not fall back by id from an unattested guest hook path (%s)',
|
||||
async (agent) => {
|
||||
READABLE_WSL_UNC_PATHS.delete(ROLLOUT_UNC)
|
||||
scanned.hostRootHasRollout = true
|
||||
|
||||
await expect(
|
||||
resolveSessionFilePath('codex', 'wsl-sess', {
|
||||
transcriptPath: ROLLOUT_LINUX,
|
||||
codexSessionsDirs: ['C:\\host\\sessions']
|
||||
})
|
||||
).resolves.toBeNull()
|
||||
expect(scanned.dirs).toEqual([])
|
||||
})
|
||||
await expect(
|
||||
resolveSessionFilePath(agent, 'wsl-sess', {
|
||||
transcriptPath: ROLLOUT_LINUX,
|
||||
codexSessionsDirs: ['C:\\host\\sessions']
|
||||
})
|
||||
).resolves.toBeNull()
|
||||
expect(scanned.dirs).toEqual([])
|
||||
}
|
||||
)
|
||||
|
||||
it('does not fall back to a host id match for an unattested guest hook path', async () => {
|
||||
scanned.hostRootHasRollout = true
|
||||
|
||||
@@ -210,11 +210,12 @@ describe('getPiAgentStatusExtensionSource', () => {
|
||||
expect(
|
||||
harness.fetchMock.mock.calls.map(([_event, init]) => JSON.parse(String(init?.body)).payload)
|
||||
).toEqual([
|
||||
{ hook_event_name: 'agent_start', session_id: 'omp-session-8' },
|
||||
{ hook_event_name: 'agent_start', session_id: 'omp-session-8', session_file: '/tmp/s' },
|
||||
{
|
||||
hook_event_name: 'before_agent_start',
|
||||
prompt: 'hi',
|
||||
session_id: 'omp-session-9'
|
||||
session_id: 'omp-session-9',
|
||||
session_file: '/tmp/s'
|
||||
},
|
||||
{ hook_event_name: 'agent_end' }
|
||||
])
|
||||
@@ -240,7 +241,7 @@ describe('getPiAgentStatusExtensionSource', () => {
|
||||
let sessionId = 'omp-session-8'
|
||||
const sessionManager = {
|
||||
getSessionId: () => sessionId,
|
||||
getSessionFile: () => '/tmp/session.jsonl'
|
||||
getSessionFile: () => `/tmp/${sessionId}.jsonl`
|
||||
}
|
||||
await harness.callHook('agent_start', undefined, { sessionManager })
|
||||
sessionId = 'omp-session-9'
|
||||
@@ -258,9 +259,9 @@ describe('getPiAgentStatusExtensionSource', () => {
|
||||
hook_event_name: 'message_end',
|
||||
role: 'assistant',
|
||||
text: 'done',
|
||||
session_id: 'omp-session-9'
|
||||
session_id: 'omp-session-9',
|
||||
session_file: '/tmp/omp-session-9.jsonl'
|
||||
})
|
||||
expect(body.payload).not.toHaveProperty('session_file')
|
||||
expect(harness.fetchMock.mock.calls[1]?.[0]).toBe('http://127.0.0.1:4321/hook/omp')
|
||||
expect(harness.spawnMock).not.toHaveBeenCalled()
|
||||
finishDeliveries[1]?.()
|
||||
|
||||
@@ -19,7 +19,7 @@ import { getPiAgentStatusWslCurlSourceLines } from './agent-status-wsl-curl-sour
|
||||
export const ORCA_PI_AGENT_STATUS_EXTENSION_FILE = 'orca-agent-status.ts'
|
||||
|
||||
export function getPiAgentStatusExtensionSource(kind: PiAgentKind = 'pi'): string {
|
||||
// Why: OMP needs the file only to reject ephemeral sessions; disclose just its resume id.
|
||||
// OMP resumes by id; its persistent file path lets native chat skip discovery.
|
||||
const sessionMetadataSourceLines =
|
||||
kind !== 'omp'
|
||||
? [
|
||||
@@ -41,7 +41,7 @@ export function getPiAgentStatusExtensionSource(kind: PiAgentKind = 'pi'): strin
|
||||
' const sessionManager = (ctx as { sessionManager?: { getSessionId?: () => unknown; getSessionFile?: () => unknown } } | null)?.sessionManager',
|
||||
' const sessionId = sessionManager?.getSessionId?.()',
|
||||
' const sessionFile = sessionManager?.getSessionFile?.()',
|
||||
" runtimeOmpSessionMetadata = typeof sessionId === 'string' && sessionId && typeof sessionFile === 'string' && sessionFile ? { session_id: sessionId } : {}",
|
||||
" runtimeOmpSessionMetadata = typeof sessionId === 'string' && sessionId && typeof sessionFile === 'string' && sessionFile ? { session_id: sessionId, session_file: sessionFile } : {}",
|
||||
'}',
|
||||
'',
|
||||
'function getPostSessionMetadata(ompRuntime: boolean): Record<string, unknown> {',
|
||||
@@ -69,7 +69,7 @@ export function getPiAgentStatusExtensionSource(kind: PiAgentKind = 'pi'): strin
|
||||
' const sessionManager = (ctx as { sessionManager?: { getSessionId?: () => unknown; getSessionFile?: () => unknown } } | null)?.sessionManager',
|
||||
' const sessionId = sessionManager?.getSessionId?.()',
|
||||
' const sessionFile = sessionManager?.getSessionFile?.()',
|
||||
" sessionMetadata = typeof sessionId === 'string' && sessionId && typeof sessionFile === 'string' && sessionFile ? { session_id: sessionId } : {}",
|
||||
" sessionMetadata = typeof sessionId === 'string' && sessionId && typeof sessionFile === 'string' && sessionFile ? { session_id: sessionId, session_file: sessionFile } : {}",
|
||||
'}',
|
||||
'',
|
||||
'function updateRuntimeOmpSessionMetadata(ctx: unknown): void {',
|
||||
|
||||
@@ -50,6 +50,10 @@ describe('OMP session status ownership', () => {
|
||||
await settle()
|
||||
const bodies = harness.fetchMock.mock.calls.map((call) => JSON.parse(call[1].body))
|
||||
expect(bodies.map((body) => body.payload.session_id)).toEqual(['root', 'root'])
|
||||
expect(bodies.map((body) => body.payload.session_file)).toEqual([
|
||||
'/root.jsonl',
|
||||
'/root.jsonl'
|
||||
])
|
||||
expect(bodies.at(-1).payload.hook_event_name).toBe('agent_end')
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { extractAgentProviderSession, getAgentResumeArgv } from '../../shared/agent-session-resume'
|
||||
import type * as SessionScannerDiscovery from '../ai-vault/session-scanner-discovery'
|
||||
import { walkSessionFiles } from '../ai-vault/session-scanner-discovery'
|
||||
import { resolveSessionFilePath } from '../native-chat/session-file-resolver'
|
||||
import { createAgentStatusExtensionHarness } from './agent-status-extension-test-harness'
|
||||
|
||||
vi.mock('../ai-vault/session-scanner-discovery', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof SessionScannerDiscovery>()
|
||||
return { ...actual, walkSessionFiles: vi.fn(actual.walkSessionFiles) }
|
||||
})
|
||||
|
||||
let root: string
|
||||
beforeEach(async () => {
|
||||
root = await mkdtemp(join(tmpdir(), 'orca-omp-metadata-'))
|
||||
vi.mocked(walkSessionFiles).mockClear()
|
||||
})
|
||||
afterEach(async () => {
|
||||
await rm(root, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
describe.each([
|
||||
['dedicated OMP', { kind: 'omp' as const }],
|
||||
['Pi-routed OMP', { kind: 'pi' as const, title: 'omp' }]
|
||||
])('%s transcript metadata', (_name, args) => {
|
||||
it('resolves custom files without scanning and retains id-based resume across switches', async () => {
|
||||
const harness = createAgentStatusExtensionHarness(args)
|
||||
let id = ''
|
||||
let file = ''
|
||||
const sessionManager = { getSessionId: () => id, getSessionFile: () => file }
|
||||
for (const next of ['first', 'second']) {
|
||||
id = next
|
||||
file = join(root, `${id}.jsonl`)
|
||||
await writeFile(file, `${JSON.stringify({ type: 'session', id })}\n`)
|
||||
await harness.callHook('agent_start', undefined, {
|
||||
sessionManager
|
||||
})
|
||||
await vi.waitFor(() =>
|
||||
expect(harness.fetchMock).toHaveBeenCalledTimes(id === 'first' ? 1 : 2)
|
||||
)
|
||||
const payload = JSON.parse(String(harness.fetchMock.mock.lastCall?.[1]?.body)).payload
|
||||
const session = extractAgentProviderSession('omp', payload)
|
||||
expect(session).toEqual({ key: 'session_id', id, transcriptPath: file })
|
||||
expect(getAgentResumeArgv('omp', session!)).toEqual(['omp', '--resume', id])
|
||||
expect(getAgentResumeArgv('omp', session!, 'explicit.jsonl')).toEqual([
|
||||
'omp',
|
||||
'--resume',
|
||||
'explicit.jsonl'
|
||||
])
|
||||
await expect(
|
||||
resolveSessionFilePath('omp', id, {
|
||||
transcriptPath: session!.transcriptPath,
|
||||
ompSessionsDir: join(root, 'unused-default')
|
||||
})
|
||||
).resolves.toBe(file)
|
||||
}
|
||||
expect(walkSessionFiles).not.toHaveBeenCalled()
|
||||
expect(harness.fsMock.existsSync).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('publishes planned persistent paths, then resolves after delayed creation', async () => {
|
||||
const harness = createAgentStatusExtensionHarness(args)
|
||||
const file = join(root, 'delayed.jsonl')
|
||||
await harness.callHook('agent_start', undefined, {
|
||||
sessionManager: { getSessionId: () => 'delayed', getSessionFile: () => file }
|
||||
})
|
||||
const payload = JSON.parse(String(harness.fetchMock.mock.lastCall?.[1]?.body)).payload
|
||||
const session = extractAgentProviderSession('omp', payload)!
|
||||
expect(session.transcriptPath).toBe(file)
|
||||
const options = { transcriptPath: session.transcriptPath, ompSessionsDir: join(root, 'empty') }
|
||||
await expect(resolveSessionFilePath('omp', session.id, options)).resolves.toBeNull()
|
||||
expect(walkSessionFiles).toHaveBeenCalledTimes(1)
|
||||
await writeFile(file, '{}\n')
|
||||
vi.mocked(walkSessionFiles).mockClear()
|
||||
await expect(resolveSessionFilePath('omp', session.id, options)).resolves.toBe(file)
|
||||
expect(walkSessionFiles).not.toHaveBeenCalled()
|
||||
const controller = new AbortController()
|
||||
controller.abort()
|
||||
await expect(
|
||||
resolveSessionFilePath('omp', session.id, options, controller.signal)
|
||||
).rejects.toThrow()
|
||||
expect(walkSessionFiles).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it.each([undefined, '', 123])(
|
||||
'clears persistent metadata for ephemeral path %s',
|
||||
async (file) => {
|
||||
const harness = createAgentStatusExtensionHarness(args)
|
||||
let sessionFile: unknown = join(root, 'p.jsonl')
|
||||
const sessionManager = { getSessionId: () => 'same-owner', getSessionFile: () => sessionFile }
|
||||
await harness.callHook('agent_start', undefined, { sessionManager })
|
||||
sessionFile = file
|
||||
await harness.callHook('agent_end', undefined, { sessionManager })
|
||||
await vi.waitFor(() => expect(harness.fetchMock).toHaveBeenCalledTimes(2))
|
||||
const payload = JSON.parse(String(harness.fetchMock.mock.lastCall?.[1]?.body)).payload
|
||||
expect(payload).toEqual({ hook_event_name: 'agent_end' })
|
||||
expect(extractAgentProviderSession('omp', payload)).toBeNull()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('retains id-based discovery with an old extension and rejects malformed optional paths', async () => {
|
||||
const id = 'legacy-session'
|
||||
const file = join(root, `${id}.jsonl`)
|
||||
await writeFile(file, '{}\n')
|
||||
for (const session_file of [undefined, '', 123, '/bad\npath.jsonl']) {
|
||||
const session = extractAgentProviderSession('omp', { session_id: id, session_file })!
|
||||
expect(session).toEqual({ key: 'session_id', id })
|
||||
expect(getAgentResumeArgv('omp', session)).toEqual(['omp', '--resume', id])
|
||||
await expect(resolveSessionFilePath('omp', id, { ompSessionsDir: root })).resolves.toBe(file)
|
||||
}
|
||||
expect(walkSessionFiles).toHaveBeenCalledTimes(4)
|
||||
})
|
||||
@@ -224,10 +224,10 @@ export function extractAgentProviderSession(
|
||||
const id = readSessionId(payload, ['session_id', 'sessionId'])
|
||||
return id ? { key: 'session_id', id } : null
|
||||
}
|
||||
// Why: OMP's managed extension reports the authoritative CLI resume id.
|
||||
// OMP keeps id-based resume while optionally locating its native-chat transcript.
|
||||
case 'omp': {
|
||||
const id = readSessionId(payload, ['session_id'])
|
||||
return id ? { key: 'session_id', id } : null
|
||||
return id ? withTranscriptPath({ key: 'session_id', id }, payload, ['session_file']) : null
|
||||
}
|
||||
// Why: Copilot's hook `session_id` is also its `~/.copilot/session-state/<id>/`
|
||||
// directory name, so the same id is the CLI's resume locator.
|
||||
|
||||
@@ -20,10 +20,8 @@ export function isNativeChatSupportedAgent(agent: string | null | undefined): bo
|
||||
return agent != null && NATIVE_CHAT_SUPPORTED_AGENTS.has(agent)
|
||||
}
|
||||
|
||||
/** Agents whose hook discloses no transcript path (`extractAgentProviderSession`),
|
||||
* so native chat can only reach the session file by scanning a sessions root on
|
||||
* a disk THIS process can read. Under Model-A SSH that disk is the wrong host,
|
||||
* so the chat view must stay closed instead of loading forever. */
|
||||
/** Agents whose Model-A SSH transcript reader is not supported. A hook path alone
|
||||
* does not establish owning-host reads, so OMP remains gated even with metadata. */
|
||||
export function nativeChatRequiresLocalTranscript(agent: string | null | undefined): boolean {
|
||||
const transcriptAgent = resolveNativeChatTranscriptAgent(agent)
|
||||
return transcriptAgent === 'grok' || transcriptAgent === 'omp'
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// Run with Bun and a read-only OMP checkout path as the first argument.
|
||||
import assert from 'node:assert/strict'
|
||||
import { mkdtemp, mkdir, writeFile, rm } from 'node:fs/promises'
|
||||
import { createServer } from 'node:http'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { getPiAgentStatusExtensionSource } from '../../src/main/pi/agent-status-extension-source.ts'
|
||||
import {
|
||||
extractAgentProviderSession,
|
||||
getAgentResumeArgv
|
||||
} from '../../src/shared/agent-session-resume.ts'
|
||||
import { readNativeChatTranscript } from '../../src/main/native-chat/transcript-reader.ts'
|
||||
|
||||
const reference = process.argv[2]
|
||||
assert.ok(reference, 'Pass the read-only oh-my-pi source checkout path')
|
||||
const scratch = await mkdtemp(join(tmpdir(), 'orca-omp-transcript-'))
|
||||
process.env.HOME = join(scratch, 'home')
|
||||
process.env.USERPROFILE = process.env.HOME
|
||||
process.env.OMP_CODING_AGENT_DIR = join(scratch, 'agent')
|
||||
await mkdir(process.env.HOME, { recursive: true })
|
||||
const source = (path) =>
|
||||
pathToFileURL(join(resolve(reference), 'packages/coding-agent/src', path)).href
|
||||
const { loadExtensions } = await import(source('extensibility/extensions/loader.ts'))
|
||||
const { EventBus } = await import(source('utils/event-bus.ts'))
|
||||
const { SessionManager } = await import(source('session/session-manager.ts'))
|
||||
const posts = []
|
||||
const server = createServer(async (request, response) => {
|
||||
let body = ''
|
||||
for await (const chunk of request) {
|
||||
body += chunk
|
||||
}
|
||||
posts.push(JSON.parse(body).payload)
|
||||
response.writeHead(200).end()
|
||||
})
|
||||
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve))
|
||||
const managers = []
|
||||
try {
|
||||
process.env.ORCA_AGENT_HOOK_PORT = String(server.address().port)
|
||||
process.env.ORCA_AGENT_HOOK_TOKEN = 'test-token'
|
||||
delete process.env.ORCA_AGENT_HOOK_ENDPOINT
|
||||
delete process.env.ORCA_PI_STATUS_OWNED
|
||||
process.title = 'omp'
|
||||
for (const kind of ['omp', 'pi']) {
|
||||
process.env.ORCA_PANE_KEY = `transcript-${kind}`
|
||||
process.env.ORCA_AGENT_LAUNCH_TOKEN = `transcript-${kind}`
|
||||
const extensionPath = join(scratch, `${kind}-agent-status.ts`)
|
||||
await writeFile(extensionPath, getPiAgentStatusExtensionSource(kind))
|
||||
const load = async () => {
|
||||
const result = await loadExtensions([extensionPath], scratch, new EventBus())
|
||||
assert.deepEqual(result.errors, [])
|
||||
return result.extensions[0]
|
||||
}
|
||||
const root = SessionManager.create(scratch, join(scratch, `${kind}-custom-sessions`))
|
||||
const child = SessionManager.create(scratch, join(scratch, `${kind}-child-sessions`))
|
||||
managers.push(root, child)
|
||||
const emit = async (extension, type, manager) => {
|
||||
for (const handler of extension.handlers.get(type) ?? []) {
|
||||
await handler({ type }, { sessionManager: manager, hasUI: false })
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 60))
|
||||
}
|
||||
const extension = await load()
|
||||
await emit(extension, 'session_start', root)
|
||||
for (const phase of ['initial', 'new']) {
|
||||
if (phase === 'new') {
|
||||
await root.newSession()
|
||||
}
|
||||
assert.equal(root.isSessionOnDisk(), false)
|
||||
await emit(extension, 'agent_start', root)
|
||||
const session = extractAgentProviderSession('omp', posts.at(-1))
|
||||
assert.equal(session.transcriptPath, root.getSessionFile())
|
||||
assert.deepEqual(getAgentResumeArgv('omp', session), ['omp', '--resume', root.getSessionId()])
|
||||
const options = {
|
||||
transcriptPath: session.transcriptPath,
|
||||
ompSessionsDir: join(scratch, 'unused')
|
||||
}
|
||||
assert.equal((await readNativeChatTranscript('omp', session.id, options)).notFound, true)
|
||||
root.appendMessage({
|
||||
role: 'user',
|
||||
content: `Transcript proof ${kind} ${phase}`,
|
||||
timestamp: Date.now()
|
||||
})
|
||||
await root.ensureOnDisk()
|
||||
await root.flush()
|
||||
const transcript = await readNativeChatTranscript('omp', session.id, options)
|
||||
assert.ok('messages' in transcript, JSON.stringify(transcript))
|
||||
assert.equal(transcript.messages.length, 1)
|
||||
assert.ok(JSON.stringify(transcript.messages).includes(`Transcript proof ${kind} ${phase}`))
|
||||
const beforeChild = posts.length
|
||||
const childExtension = await load()
|
||||
await emit(childExtension, 'session_start', child)
|
||||
await emit(childExtension, 'agent_start', child)
|
||||
await emit(childExtension, 'agent_end', child)
|
||||
assert.equal(posts.length, beforeChild)
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
JSON.stringify({
|
||||
platform: process.platform,
|
||||
producers: ['omp', 'pi'],
|
||||
reports: posts.length,
|
||||
proof:
|
||||
'Actual OMP loader and persistent SessionManager, custom directory, lazy creation, new-session switch, HTTP metadata, Orca transcript reader, child suppression',
|
||||
modelCalls: 0,
|
||||
rendered: false
|
||||
})
|
||||
)
|
||||
} finally {
|
||||
for (const manager of managers) {
|
||||
await manager.close()
|
||||
}
|
||||
server.closeAllConnections()
|
||||
await new Promise((resolve) => server.close(resolve))
|
||||
await rm(scratch, { recursive: true, force: true })
|
||||
}
|
||||
Reference in New Issue
Block a user