Files
deepseek-harness/examples/headless-agent/tests/semantic-checkpoint.snapshot.ts
T
Yichen Jiang fee12f1af0 refactor(llm-deepseek)!: rename the provider route to deepseek-official
The native adapter's route was named deepseek, colliding with pi-ai's
catalog provider of the same name, so the two DeepSeek paths could never
be mounted side by side. The web settings page needs both configurable at
once. Compositions, fixtures, goldens, scaffolding defaults, and docs all
move together (pre-release, no shim); TUI/session-query-spill/
missing-credential goldens re-recorded through their keyless refresh
modes because provider-name length shifts box padding and spill
truncation points.
2026-07-29 16:36:07 +08:00

122 lines
5.0 KiB
TypeScript

import { readFile, writeFile } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { Context } from 'cordis'
import { normalizeSessionLog, scrubRequestHeaders, type NormalizeContext } from '@deepseek-ai/dsh-acp-snapshot'
import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke'
import { createUserMessage, CallId , createMessage } from '@deepseek-ai/dsh-llm'
import SessionStore, { SESSION_FORMAT_VERSION, SessionId, type SessionEvent, type SessionHeader } from '@deepseek-ai/dsh-session'
import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl'
import { describe, expect, it } from 'vitest'
const fixtureDir = join(dirname(fileURLToPath(import.meta.url)), 'semantic-checkpoint-snapshots/tool-outcome-unknown')
const replayFixture = join(fixtureDir, 'replay.jsonl')
const replayOverride = join(fixtureDir, 'replay.override.json')
const sessionExpected = join(fixtureDir, 'session.expected.jsonl')
const configPath = fileURLToPath(new URL('../semantic-checkpoint.cordis.snapshot.yml', import.meta.url))
const binScript = fileURLToPath(new URL('../../../packages/examples/cli-demo/src/bin.ts', import.meta.url))
const tsconfigPath = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
const sessionId = SessionId('semantic-checkpoint-unknown-outcome')
const refreshing = process.env.DSH_SNAPSHOT === 'refresh'
const task = 'Continue safely from the interrupted operation.'
async function seedInterruptedSession(root: string, cwd: string): Promise<string> {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
const meta: SessionHeader = {
version: SESSION_FORMAT_VERSION,
id: sessionId,
createdAt: 1,
cwd,
delegationDepth: 0,
}
const events: SessionEvent[] = [
{ type: 'turn/start', seq: 0, time: 10, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } },
{ type: 'user/message', seq: 1, time: 11, data: createUserMessage({
content: [{ type: 'text', text: 'Perform one side-effecting remote mutation.' }], source: { kind: 'user' },
}), surfaceOp: 'append' },
{ type: 'step/start', seq: 2, time: 12, data: { turn: 1, step: 1 } },
{
type: 'assistant/message',
seq: 3,
time: 13,
data: {
turn: 1,
step: 1,
message: createMessage({
role: 'assistant',
content: [{ type: 'tool-call', id: CallId('unknown-outcome-call'), name: 'write_remote', arguments: '{"value":1}' }],
source: {
kind: 'model',
...{ provider: 'deepseek-official', model: 'deepseek-v4-flash' },
},
}),
},
surfaceOp: 'append',
},
{
type: 'tool/call',
seq: 4,
time: 14,
data: {
turn: 1,
step: 1,
callId: CallId('unknown-outcome-call'),
name: 'write_remote',
arguments: '{"value":1}',
},
},
]
try {
await ctx.sessionPersistence.create(meta)
await ctx.sessionPersistence.append(sessionId, events)
const location = ctx.sessionPersistence.locate(meta)
if (location === undefined) throw new Error('JSONL backend did not locate the seeded session')
return location.path
} finally {
await ctx.fiber.dispose()
}
}
describe('semantic checkpoint recovery snapshot', () => {
it('resumes an unknown tool outcome through the headless stream-json app', async () => {
let cwd = ''
let sessionPath = ''
const result = await runLoaderSmoke({
label: 'semantic checkpoint headless stream-json snapshot',
tempDirPrefix: 'dsh-semantic-snapshot-',
binScript,
configPath,
binArgs: ['--config', configPath, '--output-format', 'stream-json', task],
tsconfigPath,
env: {
DSH_SNAPSHOT_FILE: replayFixture,
DSH_SNAPSHOT_OVERRIDE: replayOverride,
},
prepare: async (runCwd) => {
cwd = runCwd
sessionPath = await seedInterruptedSession(join(runCwd, '.sessions'), runCwd)
},
inspect: async () => {
const normalization: NormalizeContext = { sessionIds: [sessionId], cwd }
const session = scrubRequestHeaders(normalizeSessionLog(await readFile(sessionPath, 'utf8'), normalization))
if (refreshing) await writeFile(sessionExpected, session)
expect(session).toBe(await readFile(sessionExpected, 'utf8'))
expect(session).toContain('TOOL_OUTCOME_UNKNOWN')
expect(session).toContain('Do not retry blindly.')
},
})
expect(result.stderr).toBe('')
const records = result.stdout.trimEnd().split('\n').map(line => JSON.parse(line) as Record<string, unknown>)
expect(records.at(-1)).toMatchObject({
type: 'result',
success: true,
sessionId,
result: 'I will verify the external state before deciding whether to retry the side-effecting operation.',
reason: { kind: 'completed' },
})
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
})