Files
deepseek-harness/examples/acp-agent/tests/subagent-product-providers.snapshot.ts
2026-08-04 16:25:38 +08:00

172 lines
6.4 KiB
TypeScript

/**
* Real-product Loader snapshots for fixed subagent providers.
*
* PR1 owns the Codex scenario. PR2 extends this file with the sibling Claude
* Code scenario and reruns both from its final stacked candidate.
*/
import { homedir } from 'node:os'
import { dirname, delimiter, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
import { describe, expect, it } from 'vitest'
import {
normalizeSessionLog,
normalizeStdout,
scrubSystemPrompts,
type NormalizeContext,
} from '@deepseek-ai/dsh-acp-snapshot'
import {
LOADER_SMOKE_TEST_TIMEOUT_MS,
runLoaderSmoke,
} from '@deepseek-ai/dsh-loader-smoke'
import { startResponsesFixture } from '../../../packages/subagent/subagent-codex/tests/responses-fixture.ts'
const testsDir = dirname(fileURLToPath(import.meta.url))
const repoRoot = fileURLToPath(new URL('../../..', import.meta.url))
const fixtureDir = join(testsDir, 'fixtures/subagent/subagent-codex')
const configPath = join(fixtureDir, 'cordis.yml')
const snapshotDir = join(testsDir, 'product-provider-snapshots/codex')
const sessionExpected = join(snapshotDir, 'session.expected.jsonl')
const evidenceExpected = join(snapshotDir, 'evidence.expected.json')
const cliBin = join(repoRoot, 'packages/examples/cli-demo/src/bin.ts')
const repoTsconfig = join(repoRoot, 'tsconfig.json')
const codexBinDir = join(
repoRoot,
'packages/subagent/subagent-codex/node_modules/.bin',
)
const refreshing = process.env.DSH_SNAPSHOT === 'refresh'
const CODEX_SENTINEL = 'REAL_CODEX_LOADER_SENTINEL_0_146_0'
const FAKE_KEY = 'dsh-fake-openai-loader-key'
interface PersistedSession {
readonly content: string
readonly header: {
readonly id: string
readonly cwd: string
}
}
async function onlySession(root: string): Promise<PersistedSession> {
const paths = (await readdir(root, { recursive: true }))
.filter(path => path.endsWith('.jsonl'))
expect(paths).toHaveLength(1)
const path = paths[0]
if (path === undefined) throw new Error('Codex Loader snapshot persisted no session')
const content = await readFile(join(root, path), 'utf8')
const header = JSON.parse(content.slice(0, content.indexOf('\n'))) as PersistedSession['header']
return { content, header }
}
function responseInputTexts(body: Record<string, unknown>): string[] {
if (!Array.isArray(body.input)) return []
return body.input.flatMap((item): string[] => {
if (item === null || typeof item !== 'object') return []
const content = (item as Record<string, unknown>).content
if (!Array.isArray(content)) return []
return content.flatMap((part): string[] => (
part !== null
&& typeof part === 'object'
&& typeof (part as Record<string, unknown>).text === 'string'
? [(part as Record<string, unknown>).text as string]
: []
))
})
}
describe('real product subagent providers through the Loader', () => {
it('pins the Codex tool, result, persisted Session, and process quiescence', async () => {
const codexHome = await mkdtemp(join(homedir(), '.dsh-subagent-codex-loader-'))
const responses = await startResponsesFixture([
{ kind: 'complete', text: CODEX_SENTINEL },
])
let session: PersistedSession | undefined
let quiescence: unknown
try {
const result = await runLoaderSmoke({
label: 'Codex subagent Loader snapshot',
tempDirPrefix: 'dsh-subagent-codex-loader-',
binScript: cliBin,
configPath,
binArgs: [
'--config',
configPath,
'--output-format',
'json',
'Delegate through Codex once.',
],
tsconfigPath: repoTsconfig,
processTimeoutMs: 45_000,
env: {
DSH_TEST_CODEX_HOME: codexHome,
DSH_TEST_OPENAI_API_KEY: FAKE_KEY,
PATH: `${codexBinDir}${delimiter}${process.env.PATH ?? ''}`,
},
async prepare(): Promise<void> {
await writeFile(join(codexHome, 'config.toml'), [
'model = "fixture-model"',
'model_provider = "fixture"',
'approval_policy = "on-request"',
'sandbox_mode = "read-only"',
'disable_response_storage = true',
'check_for_update_on_startup = false',
'',
'[model_providers.fixture]',
'name = "Fixture Responses"',
`base_url = "${responses.baseUrl}"`,
'env_key = "OPENAI_API_KEY"',
'wire_api = "responses"',
'requires_openai_auth = false',
'',
'[analytics]',
'enabled = false',
'',
].join('\n'))
},
async inspect(cwd): Promise<void> {
session = await onlySession(join(cwd, '.sessions'))
quiescence = JSON.parse(await readFile(join(cwd, '.codex-quiescence.json'), 'utf8'))
},
})
expect(result.stderr).toBe('')
expect(session).toBeDefined()
if (session === undefined) throw new Error('Codex Loader snapshot session was not inspected')
const context: NormalizeContext = {
sessionIds: [session.header.id],
cwd: session.header.cwd,
}
const normalizedSession = scrubSystemPrompts(normalizeSessionLog(session.content, context))
const request = responses.requests[0]
expect(request).toBeDefined()
if (request === undefined) throw new Error('Codex Loader snapshot made no Responses request')
const evidence = `${JSON.stringify({
stdout: JSON.parse(normalizeStdout(result.stdout, context)) as unknown,
request: {
method: request.method,
path: request.path,
authorization: request.headers.authorization,
taskObserved: responseInputTexts(request.body)
.includes('Return the Loader snapshot sentinel exactly.'),
},
quiescence,
}, null, 2)}\n`
if (refreshing) {
await mkdir(snapshotDir, { recursive: true })
await Promise.all([
writeFile(sessionExpected, normalizedSession),
writeFile(evidenceExpected, evidence),
])
}
expect(normalizedSession).toBe(await readFile(sessionExpected, 'utf8'))
expect(evidence).toBe(await readFile(evidenceExpected, 'utf8'))
} finally {
await Promise.all([
responses.close(),
rm(codexHome, { recursive: true, force: true }),
])
}
}, LOADER_SMOKE_TEST_TIMEOUT_MS + 30_000)
})