mirror of
https://github.com/Ryder-Sun/Meldwork.git
synced 2026-11-07 06:56:03 -10:00
Implement frozen concurrent responses, Agent-negotiated V4 discussion work, strict durable receipts and recovery, validated runtime phase UI, and the animated return-to-bottom control. Prepare the 0.1.2 prerelease metadata and documentation.\n\nChecks before commit: frontend 299/299; desktop 1270/1270; deterministic eval 6 cases/18 results; web and desktop renderer builds; desktop pack; staged and unstaged diff checks.
755 lines
29 KiB
JavaScript
755 lines
29 KiB
JavaScript
const test = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
|
|
const {
|
|
RunHarness,
|
|
evidenceCapsuleText,
|
|
nextSessionMeta,
|
|
normalizeOutcomeRefs,
|
|
normalizeRawEvent,
|
|
normalizeRunEvent,
|
|
normalizeTraceCapsule,
|
|
packContextEntries,
|
|
shouldRotateSession,
|
|
traceCapsuleFromAgentRun,
|
|
} = require('../../src/runs/run-harness.cjs')
|
|
|
|
function fixture(options = {}) {
|
|
let now = 1000
|
|
let id = 0
|
|
return new RunHarness({
|
|
runId: 'run-1',
|
|
groupId: 'group-1',
|
|
threadRootId: 'message-root',
|
|
targetKinds: ['codex', 'hermes'],
|
|
now: () => ++now,
|
|
createId: () => `agent-${++id}`,
|
|
...options,
|
|
})
|
|
}
|
|
|
|
test('normalizes bounded Outcome references independently from trace events', () => {
|
|
const artifactId = `artifact-${'a'.repeat(64)}`
|
|
const evidenceId = `evidence-${'b'.repeat(64)}`
|
|
const findingId = `reviewer-finding-${'c'.repeat(64)}`
|
|
const adoptionId = `adoption-${'d'.repeat(64)}`
|
|
assert.deepEqual(normalizeOutcomeRefs({
|
|
artifactIds: [artifactId, artifactId, '../artifact'],
|
|
evidenceIds: [evidenceId],
|
|
findingIds: [findingId, 'reviewer-finding-invalid'],
|
|
adoptionIds: [adoptionId],
|
|
}), {
|
|
artifactIds: [artifactId],
|
|
evidenceIds: [evidenceId],
|
|
findingIds: [findingId],
|
|
adoptionIds: [adoptionId],
|
|
})
|
|
|
|
const harness = fixture()
|
|
const started = harness.beginAgent('codex', 0, ['message-root'])
|
|
const finished = harness.finishAgent('codex', 0, 'completed', 'Done', {
|
|
outcomeRefs: { artifactIds: [artifactId], evidenceIds: [evidenceId] },
|
|
}, started.agentRunId)
|
|
|
|
assert.deepEqual(finished.capsule.context.outcomeRefs, {
|
|
artifactIds: [artifactId],
|
|
evidenceIds: [evidenceId],
|
|
})
|
|
assert.deepEqual(harness.snapshot()[0].context.outcomeRefs, finished.capsule.context.outcomeRefs)
|
|
assert.equal(finished.capsule.events.length, 0)
|
|
})
|
|
|
|
test('normalizes every Outcome reference field to its independent V4 boundary', () => {
|
|
const hashes = Array.from({ length: 64 }, (_value, index) => (
|
|
index.toString(16).padStart(64, '0')
|
|
))
|
|
const input = {
|
|
artifactIds: hashes.map(hash => `artifact-${hash}`),
|
|
evidenceIds: hashes.map(hash => `evidence-${hash}`),
|
|
findingIds: hashes.map(hash => `reviewer-finding-${hash}`),
|
|
reviewerFindingIds: hashes.map(hash => `reviewer-finding-${hash}`),
|
|
adoptionIds: hashes.map(hash => `adoption-${hash}`),
|
|
workflowOutcomeRefs: hashes.map(hash => ({
|
|
algorithm: 'sha256', hash, size: 1, mediaType: 'application/json',
|
|
})),
|
|
}
|
|
|
|
assert.deepEqual(normalizeOutcomeRefs(input), input)
|
|
})
|
|
|
|
test('strict V4 Outcome reference normalization rejects an over-cap field', () => {
|
|
const artifactIds = Array.from({ length: 65 }, (_value, index) => (
|
|
`artifact-${index.toString(16).padStart(64, '0')}`
|
|
))
|
|
|
|
assert.throws(
|
|
() => normalizeOutcomeRefs({ artifactIds }, { strict: true }),
|
|
{ message: 'RUN_HARNESS_V4_OUTCOME_REFS_INVALID' },
|
|
)
|
|
})
|
|
|
|
test('normalizes public events through an allowlist and redacts private diagnostics', () => {
|
|
assert.deepEqual(normalizeRawEvent({
|
|
id: 'tool-1',
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: 'Search',
|
|
summary: 'Read /Users/private/work and api_key=top-secret',
|
|
detail: 'Bearer abc.def.ghi',
|
|
command: 'rg secret /Users/private/work',
|
|
executable: '/tmp/codex',
|
|
}), {
|
|
id: 'tool-1',
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: 'Search',
|
|
summary: 'Read [path] and credential=[redacted]',
|
|
detail: 'Bearer [redacted]',
|
|
})
|
|
assert.equal(normalizeRawEvent({ type: 'raw_stdout', detail: 'private' }), null)
|
|
|
|
const credentials = normalizeRawEvent({
|
|
type: 'tool_result_summary',
|
|
detail: JSON.stringify({
|
|
env: {
|
|
AWS_ACCESS_KEY_ID: 'AKIA1234567890ABCDEF',
|
|
AWS_SECRET_ACCESS_KEY: 'aws-secret-value',
|
|
DATABASE_URL: 'postgres://dbuser:dbpass@localhost/db',
|
|
password: 'hunter2',
|
|
certificate: '-----BEGIN PRIVATE KEY-----\nprivate-material\n-----END PRIVATE KEY-----',
|
|
},
|
|
}),
|
|
})
|
|
assert.doesNotMatch(JSON.stringify(credentials), /AKIA|aws-secret-value|dbuser|dbpass|hunter2|private-material/)
|
|
assert.match(credentials.detail, /redacted/)
|
|
})
|
|
|
|
test('redacts standalone Google keys and JWTs from events and evidence capsules', () => {
|
|
const googleKey = 'AIza12345678901234567890123456789012345'
|
|
const googleKeyEndingHyphen = `AIza${'A'.repeat(34)}-`
|
|
const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
|
|
const jwtEndingHyphen = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.AAAAAAA-'
|
|
const shortPayloadJwt = 'eyJhbGciOiJIUzI1NiJ9.e30.nW29kPKsrNnRPYw3T6WOpOZKc_iPdNuxmiadRPzEhns'
|
|
const basicCredential = 'dXNlcjpwYXNz'
|
|
const legitimateText = 'Basic authentication is enabled. customer.platform.internal deadbeef.cafebabe.feedface'
|
|
const event = normalizeRawEvent({
|
|
type: 'warning',
|
|
summary: `Observed ${googleKey}, ${googleKeyEndingHyphen}, ${jwt}, ${jwtEndingHyphen}, ${shortPayloadJwt}, and Basic ${basicCredential}`,
|
|
})
|
|
const trace = traceCapsuleFromAgentRun({
|
|
agentRunId: 'agent-secret-redaction',
|
|
kind: 'codex',
|
|
round: 1,
|
|
status: 'failed',
|
|
output: `Conclusion ${googleKey} ${googleKeyEndingHyphen} ${jwt} ${jwtEndingHyphen} ${shortPayloadJwt} Basic ${basicCredential}`,
|
|
events: [{
|
|
type: 'warning',
|
|
status: 'failed',
|
|
summary: `${googleKey} ${googleKeyEndingHyphen} ${jwt} ${jwtEndingHyphen} ${shortPayloadJwt} Basic ${basicCredential}`,
|
|
}],
|
|
}, { runId: 'run-secret-redaction', status: 'failed' })
|
|
const evidence = evidenceCapsuleText({
|
|
senderName: 'Codex',
|
|
content: `Conclusion ${googleKey} ${googleKeyEndingHyphen} ${jwt} ${jwtEndingHyphen} ${shortPayloadJwt} Basic ${basicCredential}`,
|
|
trace,
|
|
})
|
|
|
|
for (const value of [JSON.stringify(event), JSON.stringify(trace), evidence]) {
|
|
for (const secret of [
|
|
googleKey,
|
|
googleKeyEndingHyphen,
|
|
jwt,
|
|
jwtEndingHyphen,
|
|
shortPayloadJwt,
|
|
basicCredential,
|
|
]) {
|
|
assert.doesNotMatch(value, new RegExp(secret.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
|
|
}
|
|
assert.match(value, /\[redacted\]/)
|
|
}
|
|
|
|
assert.equal(normalizeRawEvent({
|
|
type: 'warning',
|
|
summary: legitimateText,
|
|
}).summary, legitimateText)
|
|
})
|
|
|
|
test('revalidates enriched renderer events without executable or command fields', () => {
|
|
assert.deepEqual(normalizeRunEvent({
|
|
runId: 'run-1',
|
|
agentRunId: 'run-1:1:codex:agent-1',
|
|
groupId: 'group-1',
|
|
threadRootId: 'message-1',
|
|
agentKind: 'codex',
|
|
round: 1,
|
|
seq: 2,
|
|
timestamp: 1000,
|
|
id: 'tool-1',
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: 'search',
|
|
summary: 'Read /Users/private/work with token=private-value',
|
|
command: 'rg private',
|
|
executable: '/tmp/codex',
|
|
}), {
|
|
runId: 'run-1',
|
|
agentRunId: 'run-1:1:codex:agent-1',
|
|
groupId: 'group-1',
|
|
threadRootId: 'message-1',
|
|
agentKind: 'codex',
|
|
round: 1,
|
|
seq: 2,
|
|
timestamp: 1000,
|
|
status: 'completed',
|
|
id: 'tool-1',
|
|
type: 'tool_result_summary',
|
|
title: 'search',
|
|
summary: 'Read [path] with credential=[redacted]',
|
|
})
|
|
assert.equal(normalizeRunEvent({ type: 'status', status: 'running' }), null)
|
|
})
|
|
|
|
test('keeps Unicode group identifiers bounded without relaxing run identifiers', () => {
|
|
const groupId = '历史群聊 1'
|
|
const event = normalizeRunEvent({
|
|
runId: 'run-1',
|
|
agentRunId: 'run-1:1:codex:agent-1',
|
|
groupId,
|
|
agentKind: 'codex',
|
|
seq: 1,
|
|
type: 'status',
|
|
status: 'running',
|
|
})
|
|
assert.equal(event.groupId, groupId)
|
|
|
|
const harness = fixture({ groupId })
|
|
assert.equal(harness.beginAgent('codex', 1).groupId, groupId)
|
|
assert.throws(
|
|
() => fixture({ groupId: 'group\ninvalid' }),
|
|
{ message: 'RUN_HARNESS_ID_REQUIRED' },
|
|
)
|
|
assert.throws(
|
|
() => fixture({ runId: '运行-1', groupId }),
|
|
{ message: 'RUN_HARNESS_ID_REQUIRED' },
|
|
)
|
|
})
|
|
|
|
test('enriches events, appends bounded answer deltas, and upserts tool lifecycle events', () => {
|
|
const harness = fixture({ maxEventsPerAgent: 8, maxOutputChars: 1000 })
|
|
const started = harness.beginAgent('codex', 2, ['message-1'])
|
|
assert.equal(started.runId, 'run-1')
|
|
assert.equal(started.agentRunId, 'run-1:2:codex:agent-1')
|
|
assert.equal(started.seq, 1)
|
|
|
|
harness.ingest('codex', 2, { id: 'tool-1', type: 'tool_start', status: 'running', title: 'search' })
|
|
harness.ingest('codex', 2, {
|
|
id: 'tool-1', type: 'tool_result_summary', status: 'completed', title: 'search', summary: '3 matches',
|
|
})
|
|
harness.ingest('codex', 2, { type: 'answer_delta', delta: 'Hello ' })
|
|
harness.ingest('codex', 2, { type: 'answer_delta', delta: 'world' })
|
|
|
|
const run = harness.snapshot()[0]
|
|
assert.equal(run.output, 'Hello world')
|
|
assert.equal(run.events.filter(event => event.id === 'tool-1').length, 1)
|
|
assert.equal(run.events.find(event => event.id === 'tool-1').type, 'tool_result_summary')
|
|
assert.equal(run.sourceMessageIds[0], 'message-1')
|
|
})
|
|
|
|
test('rejects stale callbacks after a newer Agent run starts for the same kind and round', () => {
|
|
const harness = fixture()
|
|
const first = harness.beginAgent('codex', 1)
|
|
const second = harness.beginAgent('codex', 1)
|
|
|
|
assert.equal(harness.ingest('codex', 1, {
|
|
id: 'stale-tool', type: 'tool_start', status: 'running', title: 'search',
|
|
}, first.agentRunId), null)
|
|
assert.equal(harness.markSilent('codex', 1, first.agentRunId), null)
|
|
assert.throws(
|
|
() => harness.finishAgent('codex', 1, 'completed', 'stale', {}, first.agentRunId),
|
|
{ message: 'RUN_HARNESS_AGENT_NOT_FOUND' },
|
|
)
|
|
|
|
const current = harness.ingest('codex', 1, {
|
|
id: 'current-tool', type: 'tool_start', status: 'running', title: 'search',
|
|
}, second.agentRunId)
|
|
assert.equal(current.agentRunId, second.agentRunId)
|
|
assert.equal(harness.snapshot().at(-1).events.some(event => event.id === 'stale-tool'), false)
|
|
})
|
|
|
|
test('rejects Agent activity outside the declared target kinds', () => {
|
|
const harness = fixture({ targetKinds: ['codex'] })
|
|
|
|
assert.throws(
|
|
() => harness.beginAgent('hermes', 1),
|
|
{ message: 'RUN_HARNESS_AGENT_NOT_TARGETED' },
|
|
)
|
|
|
|
const codex = harness.beginAgent('codex', 1)
|
|
assert.equal(harness.ingest('hermes', 1, {
|
|
id: 'cross-target-tool', type: 'tool_start', status: 'running', title: 'search',
|
|
}, codex.agentRunId), null)
|
|
assert.deepEqual(harness.snapshot().map(run => run.kind), ['codex'])
|
|
assert.equal(harness.snapshot()[0].events.some(event => event.id === 'cross-target-tool'), false)
|
|
})
|
|
|
|
test('admits a replacement Agent only after an explicit target extension', () => {
|
|
const harness = fixture({ targetKinds: ['codex'] })
|
|
|
|
assert.equal(harness.addTargetKind('kimi'), true)
|
|
assert.equal(harness.addTargetKind('kimi'), false)
|
|
const started = harness.beginAgent('kimi', 1)
|
|
|
|
assert.equal(started.agentKind, 'kimi')
|
|
assert.deepEqual(harness.targetKinds, ['codex', 'kimi'])
|
|
assert.equal(Object.isFrozen(harness.targetKinds), true)
|
|
})
|
|
|
|
test('deduplicates identical live tool events without dropping lifecycle updates', () => {
|
|
const harness = fixture()
|
|
const started = harness.beginAgent('codex', 1)
|
|
const toolStarted = harness.ingest('codex', 1, {
|
|
id: 'tool-1', type: 'tool_start', status: 'running', title: 'search',
|
|
})
|
|
const duplicate = harness.ingest('codex', 1, {
|
|
id: 'tool-1', type: 'tool_start', status: 'running', title: 'search',
|
|
})
|
|
const richer = harness.ingest('codex', 1, {
|
|
id: 'tool-1', type: 'tool_start', status: 'running', title: 'search',
|
|
summary: 'Searching the workspace',
|
|
})
|
|
const completed = harness.ingest('codex', 1, {
|
|
id: 'tool-1', type: 'tool_result_summary', status: 'completed', title: 'search',
|
|
summary: '3 matches',
|
|
})
|
|
|
|
assert.equal(duplicate, null)
|
|
assert.equal(richer.seq, toolStarted.seq + 1)
|
|
assert.equal(completed.seq, richer.seq + 1)
|
|
const run = harness.snapshot()[0]
|
|
assert.deepEqual(run.seenSeqs, [started.seq, toolStarted.seq, richer.seq, completed.seq])
|
|
assert.equal(run.events.filter(event => event.id === 'tool-1').length, 1)
|
|
assert.equal(run.events.find(event => event.id === 'tool-1').status, 'completed')
|
|
assert.equal(run.events.find(event => event.id === 'tool-1').summary, '3 matches')
|
|
})
|
|
|
|
test('bounds the default live output and seen sequence snapshot', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('codex', 1)
|
|
for (let index = 0; index < 520; index += 1) {
|
|
harness.ingest('codex', 1, { type: 'answer_delta', delta: 'x'.repeat(40) })
|
|
}
|
|
|
|
const run = harness.snapshot()[0]
|
|
assert.equal(run.output.length, 20000)
|
|
assert.equal(run.seenSeqs.length, 501)
|
|
assert.equal(run.seenSeqs.at(-1), 501)
|
|
assert.equal(run.truncated, true)
|
|
})
|
|
|
|
test('keeps a bounded event ledger and marks the trace as truncated', () => {
|
|
const harness = fixture({ maxEventsPerAgent: 8 })
|
|
harness.beginAgent('codex', 1)
|
|
for (let index = 0; index < 20; index += 1) {
|
|
harness.ingest('codex', 1, {
|
|
id: `tool-${index}`,
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: 'tool',
|
|
summary: `result ${index}`,
|
|
})
|
|
}
|
|
const run = harness.snapshot()[0]
|
|
assert.equal(run.events.length, 8)
|
|
assert.equal(run.truncated, true)
|
|
assert.equal(run.events.at(-1).summary, 'result 19')
|
|
})
|
|
|
|
test('upserts repeated reasoning lifecycle events without evicting useful evidence', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('hermes', 1)
|
|
harness.ingest('hermes', 1, {
|
|
id: 'plan', type: 'plan', status: 'running', summary: 'Inspect both implementations.',
|
|
})
|
|
harness.ingest('hermes', 1, {
|
|
id: 'tool-1', type: 'tool_result_summary', status: 'completed',
|
|
title: 'search', summary: 'Found the routing boundary.',
|
|
})
|
|
for (let index = 0; index < 100; index += 1) {
|
|
harness.ingest('hermes', 1, {
|
|
id: 'reasoning', type: 'reasoning_summary', status: 'running', title: 'reasoning',
|
|
})
|
|
}
|
|
|
|
const live = harness.snapshot()[0]
|
|
assert.equal(live.events.filter(event => event.id === 'reasoning').length, 1)
|
|
assert.equal(live.events.some(event => event.summary === 'Found the routing boundary.'), true)
|
|
assert.equal(live.truncated, false)
|
|
|
|
const { capsule } = harness.finishAgent('hermes', 1, 'completed', 'Final answer')
|
|
assert.equal(capsule.events.some(event => event.type === 'reasoning_summary'), false)
|
|
assert.equal(capsule.events.some(event => event.summary === 'Found the routing boundary.'), true)
|
|
assert.equal(capsule.summary, 'Inspect both implementations.')
|
|
})
|
|
|
|
test('rebuilds tool indexes after a silence warning shifts a full ledger', () => {
|
|
const harness = fixture({ maxEventsPerAgent: 8 })
|
|
harness.beginAgent('codex', 1)
|
|
harness.ingest('codex', 1, {
|
|
id: 'tool-keep', type: 'tool_start', status: 'running', title: 'search',
|
|
})
|
|
for (let index = 0; index < 6; index += 1) {
|
|
harness.ingest('codex', 1, {
|
|
id: `reason-${index}`, type: 'reasoning_summary', summary: `step ${index}`,
|
|
})
|
|
}
|
|
|
|
const warning = harness.markSilent('codex', 1)
|
|
harness.ingest('codex', 1, {
|
|
id: 'tool-keep', type: 'tool_result_summary', status: 'completed',
|
|
title: 'search', summary: 'finished safely',
|
|
})
|
|
|
|
const run = harness.snapshot()[0]
|
|
assert.equal(run.events.filter(event => event.id === 'tool-keep').length, 1)
|
|
assert.equal(run.events.find(event => event.id === 'tool-keep').type, 'tool_result_summary')
|
|
assert.equal(run.events.find(event => event.id === 'tool-keep').summary, 'finished safely')
|
|
assert.equal(run.seenSeqs.includes(warning.seq), true)
|
|
})
|
|
|
|
test('bounds live Agent runs even when none have completed yet', () => {
|
|
const harness = fixture({ maxAgentRuns: 2 })
|
|
harness.beginAgent('codex', 1)
|
|
harness.beginAgent('hermes', 1)
|
|
harness.beginAgent('codex', 2)
|
|
|
|
assert.deepEqual(harness.snapshot().map(run => [run.kind, run.round]), [
|
|
['hermes', 1],
|
|
['codex', 2],
|
|
])
|
|
})
|
|
|
|
test('tracks answer delta sequences even though deltas stay outside the event ledger', () => {
|
|
const harness = fixture()
|
|
const started = harness.beginAgent('codex', 1)
|
|
const delta = harness.ingest('codex', 1, { type: 'answer_delta', delta: 'streamed' })
|
|
|
|
const run = harness.snapshot()[0]
|
|
assert.deepEqual(run.seenSeqs, [started.seq, delta.seq])
|
|
assert.equal(run.events.some(event => event.type === 'answer_delta'), false)
|
|
assert.equal(run.output, 'streamed')
|
|
})
|
|
|
|
test('replaces streamed output only for an explicit authoritative answer correction', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('hermes', 1)
|
|
harness.ingest('hermes', 1, {
|
|
type: 'answer_delta', status: 'running', delta: 'partial',
|
|
})
|
|
const correction = harness.ingest('hermes', 1, {
|
|
type: 'answer_delta', status: 'completed', delta: 'authoritative final', replace: true,
|
|
})
|
|
|
|
const run = harness.snapshot()[0]
|
|
assert.equal(run.output, 'authoritative final')
|
|
assert.equal(correction.replace, true)
|
|
assert.equal(run.events.some(event => event.type === 'answer_delta'), false)
|
|
assert.equal(normalizeRawEvent({
|
|
type: 'warning', status: 'running', summary: 'keep streaming', replace: true,
|
|
}).replace, undefined)
|
|
assert.equal(normalizeRawEvent({
|
|
type: 'answer_delta', status: 'completed', delta: 'replacement', replace: 'true',
|
|
}).replace, undefined)
|
|
})
|
|
|
|
test('hydrates the durable event cursor so post-restart sequences stay monotonic', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('codex', 1)
|
|
harness.ingest('codex', 1, { type: 'answer_delta', delta: 'first' })
|
|
const finalDelta = harness.ingest('codex', 1, { type: 'answer_delta', delta: 'second' })
|
|
const persisted = harness.snapshot()
|
|
|
|
assert.equal(persisted[0].eventCursor, finalDelta.seq)
|
|
assert.equal(Math.max(...persisted[0].events.map(event => event.seq)) < finalDelta.seq, true)
|
|
|
|
const restarted = fixture({ agentRuns: persisted })
|
|
const next = restarted.beginAgent('hermes', 1)
|
|
|
|
assert.equal(next.seq, finalDelta.seq + 1)
|
|
assert.equal(restarted.snapshot()[0].output, 'firstsecond')
|
|
})
|
|
|
|
test('repeated restart keeps event sequences monotonic and Agent run ids unique', () => {
|
|
const createId = () => 'reused-token'
|
|
const initial = fixture({ createId })
|
|
const first = initial.beginAgent('codex', 1)
|
|
const delta = initial.ingest('codex', 1, { type: 'answer_delta', delta: 'partial' })
|
|
const firstRestart = fixture({ createId, agentRuns: initial.snapshot() })
|
|
const second = firstRestart.beginAgent('codex', 1)
|
|
const secondRestart = fixture({ createId, agentRuns: firstRestart.snapshot() })
|
|
const third = secondRestart.beginAgent('hermes', 1)
|
|
|
|
assert.notEqual(second.agentRunId, first.agentRunId)
|
|
assert.notEqual(third.agentRunId, second.agentRunId)
|
|
assert.equal(second.seq, delta.seq + 1)
|
|
assert.equal(third.seq, second.seq + 1)
|
|
assert.deepEqual(secondRestart.snapshot().map(run => run.agentRunId), [
|
|
first.agentRunId,
|
|
second.agentRunId,
|
|
third.agentRunId,
|
|
])
|
|
})
|
|
|
|
test('finishes with the authoritative answer and persists only a compact capsule', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('hermes', 1, ['message-a', 'message-b'])
|
|
harness.ingest('hermes', 1, {
|
|
id: 'reason-1', type: 'reasoning_summary', summary: 'Compared the two implementations.',
|
|
})
|
|
for (let index = 0; index < 16; index += 1) {
|
|
harness.ingest('hermes', 1, {
|
|
id: `tool-${index}`,
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: 'read_file',
|
|
summary: `Evidence ${index}`,
|
|
detail: `Exit code: 0\nOutput: ${index + 1} lines, ${(index + 1) * 10} bytes`,
|
|
})
|
|
}
|
|
const { capsule } = harness.finishAgent('hermes', 1, 'completed', 'Authoritative final', {
|
|
includedCount: 5,
|
|
omittedCount: 2,
|
|
charCount: 9000,
|
|
contextMode: 'continuation',
|
|
promptChars: 4200,
|
|
sessionRotated: true,
|
|
externalRunRef: `ocr+${'a'.repeat(180)}`,
|
|
})
|
|
assert.equal(harness.snapshot()[0].output, 'Authoritative final')
|
|
assert.equal(harness.snapshot()[0].events.find(event => event.summary === 'Evidence 15')?.detail,
|
|
'Exit code: 0\nOutput: 16 lines, 160 bytes')
|
|
assert.equal(capsule.events.length, 12)
|
|
assert.equal(capsule.round, 1)
|
|
assert.equal(capsule.summary, 'Compared the two implementations.')
|
|
assert.deepEqual(capsule.sourceMessageIds, ['message-a', 'message-b'])
|
|
assert.equal(capsule.context.sessionRotated, true)
|
|
assert.equal(capsule.context.contextMode, 'continuation')
|
|
assert.equal(capsule.context.promptChars, 4200)
|
|
assert.equal(capsule.context.externalRunRef, `ocr+${'a'.repeat(180)}`)
|
|
assert.equal(capsule.events.at(-1).detail, 'Exit code: 0\nOutput: 16 lines, 160 bytes')
|
|
})
|
|
|
|
test('retains bounded Hermes ACP tool activity without results as partial evidence', () => {
|
|
const harness = fixture()
|
|
harness.beginAgent('hermes', 1, ['message-root'])
|
|
for (let index = 0; index < 14; index += 1) {
|
|
harness.ingest('hermes', 1, {
|
|
id: `tool-${index}`,
|
|
type: index % 2 === 0 ? 'tool_start' : 'tool_update',
|
|
status: ['running', 'waiting', 'completed'][index % 3],
|
|
title: 'search',
|
|
summary: `Operation ${index} targetKinds in /Users/private/work with token=private-value`,
|
|
command: 'rg targetKinds /Users/private/work',
|
|
rawInput: { token: 'private-value' },
|
|
})
|
|
}
|
|
|
|
const { capsule } = harness.finishAgent('hermes', 1, 'completed', 'Recovered without tool results')
|
|
assert.equal(capsule.events.length, 12)
|
|
assert.equal(capsule.events[0].summary.startsWith('Operation 2 targetKinds'), true)
|
|
assert.equal(capsule.events.some(event => event.type === 'tool_start'), true)
|
|
assert.equal(capsule.events.some(event => event.type === 'tool_update'), true)
|
|
assert.equal(capsule.events.every(event => event.status === 'partial'), true)
|
|
assert.deepEqual(Object.keys(capsule.events.at(-1)).sort(), [
|
|
'evidenceId', 'status', 'summary', 'title', 'type',
|
|
])
|
|
assert.doesNotMatch(JSON.stringify(capsule), /Users\/private|private-value|command|rawInput/)
|
|
|
|
const text = evidenceCapsuleText({
|
|
senderName: 'Hermes',
|
|
content: 'Recovered without tool results',
|
|
trace: capsule,
|
|
})
|
|
assert.match(text, /Operation 13 targetKinds/)
|
|
assert.doesNotMatch(text, /Users\/private|private-value/)
|
|
})
|
|
|
|
test('rebuilds an interrupted capsule from the last bounded Agent checkpoint', () => {
|
|
const capsule = traceCapsuleFromAgentRun({
|
|
agentRunId: 'run-9:2:codex:agent-1',
|
|
kind: 'codex',
|
|
round: 2,
|
|
status: 'running',
|
|
sourceMessageIds: ['message-1'],
|
|
context: { includedCount: 1, omittedCount: 4, charCount: 900 },
|
|
events: [
|
|
{ type: 'reasoning_summary', status: 'running', summary: 'Checked the routing boundary.' },
|
|
{
|
|
type: 'tool_result_summary', status: 'completed', title: 'search',
|
|
summary: 'Found /Users/private/work with token=private-value',
|
|
detail: 'Exit code: 0\nOutput: 3 lines, 120 bytes',
|
|
},
|
|
],
|
|
}, { runId: 'run-9', status: 'interrupted' })
|
|
|
|
assert.equal(capsule.status, 'interrupted')
|
|
assert.equal(capsule.summary, 'Checked the routing boundary.')
|
|
assert.deepEqual(capsule.sourceMessageIds, ['message-1'])
|
|
assert.equal(capsule.context.omittedCount, 4)
|
|
assert.match(capsule.events.at(-1).summary, /\[path\]|\[redacted\]/)
|
|
assert.doesNotMatch(JSON.stringify(capsule), /Users\/private|private-value/)
|
|
})
|
|
|
|
test('persists only result metadata in capsule details and rejects unrecognized fields', () => {
|
|
const capsule = normalizeTraceCapsule({
|
|
runId: 'run-2',
|
|
agentRunId: 'agent-run-2',
|
|
status: 'completed',
|
|
summary: 'Public summary',
|
|
events: [{
|
|
evidenceId: 'E-1', type: 'tool_result_summary', status: 'completed',
|
|
title: '/private/result', summary: 'token=secret-value',
|
|
detail: 'Output: 2 lines, 30 bytes\n/private/result token=secret-value',
|
|
}],
|
|
sourceMessageIds: ['message-1'],
|
|
executable: '/tmp/codex',
|
|
})
|
|
assert.deepEqual(capsule.events[0], {
|
|
evidenceId: 'E-1',
|
|
type: 'tool_result_summary',
|
|
status: 'completed',
|
|
title: '[path]',
|
|
summary: 'credential=[redacted]',
|
|
detail: 'Output: 2 lines, 30 bytes',
|
|
})
|
|
assert.equal('executable' in capsule, false)
|
|
})
|
|
|
|
test('recovers a legacy capsule round from its generated Agent run id', () => {
|
|
const inferred = normalizeTraceCapsule({
|
|
runId: 'run-legacy',
|
|
agentRunId: 'run-legacy:4:claude:agent-1',
|
|
status: 'completed',
|
|
})
|
|
const explicit = normalizeTraceCapsule({
|
|
runId: 'run-legacy',
|
|
agentRunId: 'run-legacy:4:claude:agent-1',
|
|
round: 2,
|
|
status: 'completed',
|
|
})
|
|
|
|
assert.equal(inferred.round, 4)
|
|
assert.equal(explicit.round, 2)
|
|
})
|
|
|
|
test('does not infer a legacy round from invalid explicit values or malformed Agent run ids', () => {
|
|
for (const round of [true, '4', -1, 100001, null, undefined]) {
|
|
const capsule = normalizeTraceCapsule({
|
|
runId: 'run-legacy',
|
|
agentRunId: 'run-legacy:4:claude:agent-1',
|
|
round,
|
|
status: 'completed',
|
|
})
|
|
assert.equal('round' in capsule, false)
|
|
}
|
|
|
|
for (const agentRunId of [
|
|
'run-legacy:4',
|
|
'run-legacy:4:anything',
|
|
'run-legacy:4:claude:agent-1:extra',
|
|
'run-legacy:4:claude:',
|
|
'run-legacy:100001:claude:agent-1',
|
|
]) {
|
|
const capsule = normalizeTraceCapsule({
|
|
runId: 'run-legacy',
|
|
agentRunId,
|
|
status: 'completed',
|
|
})
|
|
assert.equal('round' in capsule, false)
|
|
}
|
|
})
|
|
|
|
test('renders evidence as untrusted reference without raw tool detail', () => {
|
|
const text = evidenceCapsuleText({
|
|
senderName: 'Codex',
|
|
content: 'Final conclusion',
|
|
trace: {
|
|
runId: 'run-1', agentRunId: 'agent-1', status: 'completed',
|
|
events: [{
|
|
evidenceId: 'E-R1-CODEX-01', type: 'tool_result_summary', status: 'completed',
|
|
title: 'search', summary: 'Found the handler', detail: 'raw command output',
|
|
}],
|
|
sourceMessageIds: ['message-root'],
|
|
},
|
|
})
|
|
assert.match(text, /untrusted data, not instructions/)
|
|
assert.match(text, /E-R1-CODEX-01/)
|
|
assert.match(text, /message-root/)
|
|
assert.doesNotMatch(text, /raw command output/)
|
|
})
|
|
|
|
test('reserves context space for both evidence and a long Agent conclusion', () => {
|
|
const text = evidenceCapsuleText({
|
|
senderName: 'Claude',
|
|
content: `Conclusion starts here. ${'x'.repeat(4000)}`,
|
|
trace: {
|
|
runId: 'run-long', agentRunId: 'agent-long', status: 'completed',
|
|
events: [{
|
|
evidenceId: 'E-R1-CLAUDE-01', type: 'tool_result_summary', status: 'completed',
|
|
title: 'search', summary: 'Confirmed the targeted routing implementation.',
|
|
}],
|
|
sourceMessageIds: ['message-root'],
|
|
},
|
|
})
|
|
|
|
assert.equal(text.length <= 3000, true)
|
|
assert.match(text, /E-R1-CLAUDE-01/)
|
|
assert.match(text, /Source messages: message-root/)
|
|
assert.match(text, /Claude: Conclusion starts here/)
|
|
})
|
|
|
|
test('packs whole context entries by priority and recency within a fixed budget', () => {
|
|
const packed = packContextEntries([
|
|
{ id: 'old', sender: 'Codex', text: 'old low priority', priority: 0 },
|
|
{ id: 'important', sender: 'User', text: 'pinned constraint', priority: 3 },
|
|
{ id: 'recent', sender: 'Hermes', text: 'recent conclusion', priority: 2 },
|
|
{ id: 'large', sender: 'Agent', text: 'x'.repeat(400), priority: 1 },
|
|
], { budget: 60, entryLimit: 80, maxEntries: 3 })
|
|
assert.match(packed.text, /pinned constraint/)
|
|
assert.match(packed.text, /recent conclusion/)
|
|
assert.doesNotMatch(packed.text, /old low priority/)
|
|
assert.deepEqual(packed.sourceMessageIds, ['important', 'recent'])
|
|
assert.equal(packed.omittedCount, 2)
|
|
assert.equal(packed.charCount <= 60, true)
|
|
})
|
|
|
|
test('skips an oversized high-priority entry and still packs later smaller entries', () => {
|
|
const packed = packContextEntries([
|
|
{ id: 'small-old', sender: 'Codex', text: 'usable evidence', priority: 1 },
|
|
{ id: 'small-new', sender: 'Hermes', text: 'compact conclusion', priority: 2 },
|
|
{ id: 'oversized', sender: 'User', text: 'x'.repeat(200), priority: 3 },
|
|
], { budget: 35, entryLimit: 300, maxEntries: 3 })
|
|
|
|
assert.doesNotMatch(packed.text, /x{20}/)
|
|
assert.match(packed.text, /compact conclusion/)
|
|
assert.deepEqual(packed.sourceMessageIds, ['small-new'])
|
|
assert.equal(packed.omittedCount, 2)
|
|
})
|
|
|
|
test('rotates native sessions at bounded turns or estimated characters', () => {
|
|
assert.equal(shouldRotateSession({ turns: 17, estimatedChars: 100 }), false)
|
|
assert.equal(shouldRotateSession({ turns: 18, estimatedChars: 100 }), true)
|
|
assert.equal(shouldRotateSession({ turns: 1, estimatedChars: 48000 }), true)
|
|
assert.deepEqual(nextSessionMeta({ turns: 17, estimatedChars: 1000 }, {
|
|
promptChars: 500, replyChars: 250, rotated: false,
|
|
}), { turns: 18, estimatedChars: 1750 })
|
|
assert.deepEqual(nextSessionMeta({ turns: 20, estimatedChars: 90000 }, {
|
|
promptChars: 500, replyChars: 250, rotated: true,
|
|
}), { turns: 1, estimatedChars: 750 })
|
|
assert.deepEqual(nextSessionMeta({ turns: 2, estimatedChars: 1000, transport: 'acp' }, {
|
|
promptChars: 500, replyChars: 250,
|
|
}), { turns: 3, estimatedChars: 1750, transport: 'acp' })
|
|
assert.deepEqual(nextSessionMeta({ turns: 20, estimatedChars: 90000, transport: 'acp' }, {
|
|
promptChars: 500, replyChars: 250, rotated: true, transport: 'legacy',
|
|
}), { turns: 1, estimatedChars: 750, transport: 'legacy' })
|
|
})
|