test: align e2e clients with enqueue acknowledgements
This commit is contained in:
@@ -40,12 +40,9 @@ describe('headless-agent keyless smoke', () => {
|
|||||||
expect(JSON.stringify(toolResult)).toContain('CLI_TOOL_ROUND_TRIP')
|
expect(JSON.stringify(toolResult)).toContain('CLI_TOOL_ROUND_TRIP')
|
||||||
expect(result).toMatchObject({
|
expect(result).toMatchObject({
|
||||||
type: 'result',
|
type: 'result',
|
||||||
success: true,
|
|
||||||
turn: 1,
|
|
||||||
reason: { kind: 'completed' },
|
|
||||||
usage: { inputTokens: 18, outputTokens: 8, cacheReadTokens: 2, reasoningTokens: 1 },
|
usage: { inputTokens: 18, outputTokens: 8, cacheReadTokens: 2, reasoningTokens: 1 },
|
||||||
})
|
})
|
||||||
expect(String(result?.['result'])).toContain('CLI_TOOL_ROUND_TRIP')
|
expect(String(result?.['output'])).toContain('CLI_TOOL_ROUND_TRIP')
|
||||||
expect(persistedHeader).toMatchObject({ type: 'session' })
|
expect(persistedHeader).toMatchObject({ type: 'session' })
|
||||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ function waitForLine(
|
|||||||
|
|
||||||
describe('jsonrpc-agent keyless smoke', () => {
|
describe('jsonrpc-agent keyless smoke', () => {
|
||||||
it.each([
|
it.each([
|
||||||
{ label: 'accepts max-token results by default', envValue: undefined, expectedStatus: 'ok' },
|
{ label: 'reports max-token turns with the default mapping config', envValue: undefined },
|
||||||
{ label: 'accepts max-token results when enabled through env', envValue: 'true', expectedStatus: 'ok' },
|
{ label: 'reports max-token turns with mapping enabled through env', envValue: 'true' },
|
||||||
{ label: 'reports max-token results as errors when disabled through env', envValue: 'false', expectedStatus: 'error' },
|
{ label: 'reports max-token turns with mapping disabled through env', envValue: 'false' },
|
||||||
])('$label', async ({ envValue, expectedStatus }) => {
|
])('$label', async ({ envValue }) => {
|
||||||
const root = await mkdtemp(join(tmpdir(), 'dsh-jsonrpc-agent-smoke-'))
|
const root = await mkdtemp(join(tmpdir(), 'dsh-jsonrpc-agent-smoke-'))
|
||||||
const modelRequests: Record<string, unknown>[] = []
|
const modelRequests: Record<string, unknown>[] = []
|
||||||
const modelServer = createServer((request, response) => {
|
const modelServer = createServer((request, response) => {
|
||||||
@@ -120,18 +120,29 @@ describe('jsonrpc-agent keyless smoke', () => {
|
|||||||
method: 'session/prompt',
|
method: 'session/prompt',
|
||||||
params: { sessionId: 'main', contentBlocks: [{ type: 'text', text: 'inspect tools' }] },
|
params: { sessionId: 'main', contentBlocks: [{ type: 'text', text: 'inspect tools' }] },
|
||||||
})}\n`)
|
})}\n`)
|
||||||
const finished = await waitForLine(lines, value => value.method === 'session.finished', () => stderr)
|
const prompt = await waitForLine(lines, value => value.id === 2, () => stderr)
|
||||||
expect(finished).toMatchObject({
|
expect(prompt).toMatchObject({
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
method: 'session.finished',
|
id: 2,
|
||||||
|
result: { messageId: expect.any(String) as unknown },
|
||||||
|
})
|
||||||
|
const turnEnd = await waitForLine(lines, (value) => {
|
||||||
|
if (value.method !== 'session.event') return false
|
||||||
|
const params = value.params as Record<string, unknown> | undefined
|
||||||
|
const event = params?.event as Record<string, unknown> | undefined
|
||||||
|
return params?.sessionId === 'main' && event?.type === 'turn/end'
|
||||||
|
}, () => stderr)
|
||||||
|
expect(turnEnd).toMatchObject({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'session.event',
|
||||||
params: {
|
params: {
|
||||||
sessionId: 'main',
|
sessionId: 'main',
|
||||||
status: expectedStatus,
|
event: {
|
||||||
reason: { kind: 'max-tokens' },
|
type: 'turn/end',
|
||||||
|
data: { reason: { kind: 'max-tokens' } },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const prompt = await waitForLine(lines, value => value.id === 2, () => stderr)
|
|
||||||
expect(prompt).toMatchObject({ jsonrpc: '2.0', id: 2, result: { accepted: true } })
|
|
||||||
const tools = modelRequests[0]?.tools as { function?: { name?: string } }[]
|
const tools = modelRequests[0]?.tools as { function?: { name?: string } }[]
|
||||||
expect(modelRequests[0]?.max_tokens).toBe(1234)
|
expect(modelRequests[0]?.max_tokens).toBe(1234)
|
||||||
expect(tools.map(tool => tool.function?.name).sort()).toEqual([
|
expect(tools.map(tool => tool.function?.name).sort()).toEqual([
|
||||||
|
|||||||
@@ -161,14 +161,14 @@ describe.skipIf(!existsSync(cliBin))('dsh-cli-demo BUILT bin', () => {
|
|||||||
|
|
||||||
const json = await runBuiltBin(consumer, ['--config', './cordis.yml', '--output-format', 'json', 'json task'])
|
const json = await runBuiltBin(consumer, ['--config', './cordis.yml', '--output-format', 'json', 'json task'])
|
||||||
expect(JSON.parse(json.stdout)).toMatchObject({
|
expect(JSON.parse(json.stdout)).toMatchObject({
|
||||||
type: 'result', success: true, result: 'BUILT: json task', reason: { kind: 'completed' },
|
type: 'result', output: 'BUILT: json task',
|
||||||
usage: { inputTokens: 4, outputTokens: 2 },
|
usage: { inputTokens: 4, outputTokens: 2 },
|
||||||
})
|
})
|
||||||
|
|
||||||
const stream = await runBuiltBin(consumer, ['--config', './cordis.yml', '--output-format', 'stream-json', 'stream task'])
|
const stream = await runBuiltBin(consumer, ['--config', './cordis.yml', '--output-format', 'stream-json', 'stream task'])
|
||||||
const lines = stream.stdout.trimEnd().split('\n').map(line => JSON.parse(line) as Record<string, unknown>)
|
const lines = stream.stdout.trimEnd().split('\n').map(line => JSON.parse(line) as Record<string, unknown>)
|
||||||
expect(lines[0]).toMatchObject({ type: 'session_event', event: { type: 'turn/start' } })
|
expect(lines[0]).toMatchObject({ type: 'session_event', event: { type: 'turn/start' } })
|
||||||
expect(lines.at(-1)).toMatchObject({ type: 'result', success: true, result: 'BUILT: stream task' })
|
expect(lines.at(-1)).toMatchObject({ type: 'result', output: 'BUILT: stream task' })
|
||||||
const sessionsRoot = join(consumer, '.sessions')
|
const sessionsRoot = join(consumer, '.sessions')
|
||||||
const files = await readdir(sessionsRoot, { recursive: true })
|
const files = await readdir(sessionsRoot, { recursive: true })
|
||||||
const logs = files.filter(file => file.endsWith('.jsonl.zstd'))
|
const logs = files.filter(file => file.endsWith('.jsonl.zstd'))
|
||||||
@@ -205,7 +205,7 @@ describe.skipIf(!existsSync(cliBin))('dsh-cli-demo BUILT bin', () => {
|
|||||||
)
|
)
|
||||||
expect(result, JSON.stringify(result)).toMatchObject({ code, signal: null })
|
expect(result, JSON.stringify(result)).toMatchObject({ code, signal: null })
|
||||||
expect(result.stdout).toContain('"kind":"aborted"')
|
expect(result.stdout).toContain('"kind":"aborted"')
|
||||||
expect(result.stderr).toContain('turn 1 was aborted')
|
expect(result.stderr).toBe(`dsh-cli-demo: received ${signal}\n`)
|
||||||
}, 30_000)
|
}, 30_000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,10 +44,9 @@ describe('goal domain through a real cordis.yml and headless process', () => {
|
|||||||
const result = JSON.parse(stdout) as Record<string, unknown>
|
const result = JSON.parse(stdout) as Record<string, unknown>
|
||||||
expect(result).toMatchObject({
|
expect(result).toMatchObject({
|
||||||
type: 'result',
|
type: 'result',
|
||||||
success: true,
|
|
||||||
})
|
})
|
||||||
expect(result['result']).toBeTypeOf('string')
|
expect(result['output']).toBeTypeOf('string')
|
||||||
expect(result['result']).toContain('CLI tool round trip complete')
|
expect(result['output']).toContain('CLI tool round trip complete')
|
||||||
expect(events.filter(event => event.type === 'turn/end')).toHaveLength(1)
|
expect(events.filter(event => event.type === 'turn/end')).toHaveLength(1)
|
||||||
|
|
||||||
const contexts = events.filter(event => event.type === 'user/message'
|
const contexts = events.filter(event => event.type === 'user/message'
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ describe.skipIf(process.platform === 'win32')('semantic checkpoint hard-crash re
|
|||||||
expect(crashed.markerText).toBe('request-dispatched')
|
expect(crashed.markerText).toBe('request-dispatched')
|
||||||
const events = await load(crashed.root)
|
const events = await load(crashed.root)
|
||||||
expect(events.map(event => event.type)).toEqual([
|
expect(events.map(event => event.type)).toEqual([
|
||||||
|
'agent/inbox/spliced', 'agent/inbox/spliced',
|
||||||
'turn/start', 'user/message', 'step/start', 'request/header', 'step/end', 'turn/end',
|
'turn/start', 'user/message', 'step/start', 'request/header', 'step/end', 'turn/end',
|
||||||
])
|
])
|
||||||
expect(events.at(-1)).toMatchObject({
|
expect(events.at(-1)).toMatchObject({
|
||||||
|
|||||||
Reference in New Issue
Block a user