blob: 788bc68683eed05cbe6a15cb7248638098e019f0 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import {
decodeMessageContent,
hasMeaningfulMessageContent,
isCanonicalStorageRef,
messageContentsEqual,
normalizeMessageContent,
type SessionEvent,
} from '../events.js';
import { INTERACTION_ID_MAX_BYTES, INTERACTION_TOOL_NAME_MAX_BYTES } from '../interaction.js';
import {
decodeRuntimeEvent,
isTerminalRuntimeEvent,
MANAGED_MUTATION_EXECUTION_PROFILE_V1_DIGEST,
MANAGED_MUTATION_EXECUTION_PROFILE_V1_SPEC,
runtimeEventHasModelVisibleContent,
type RuntimeEvent,
type RuntimeEventActions,
} from '../runtime-event.js';
import { decodeCanonicalMessage } from '../session.js';
import { decodeTurnOrigin } from '../turn-origin.js';
/** Minimal valid RuntimeEvent; callers spread overrides on top. */
function baseEvent(overrides: Partial<RuntimeEvent> = {}): RuntimeEvent {
return {
id: 'evt-1',
invocationId: 'inv-1',
runId: 'run-1',
sessionId: 'sess-1',
turnId: 'turn-1',
ts: 100,
partial: false,
role: 'model',
author: 'agent',
...overrides,
};
}
test('Stored assistant reasoning parts survive recovery decoding', () => {
const parts = [
{
text: 'first summary',
providerOptions: {
openai: { itemId: 'rs_first', reasoningEncryptedContent: 'encrypted-first' },
},
},
{
text: 'second summary',
providerOptions: {
openai: { itemId: 'rs_second', reasoningEncryptedContent: 'encrypted-second' },
},
},
];
const stored = decodeCanonicalMessage({
type: 'assistant',
id: 'message-1',
turnId: 'turn-1',
ts: 1,
text: 'answer',
thinking: { text: 'first summarysecond summary', parts },
modelId: 'ark-code-latest',
});
assert.equal(stored.type, 'assistant');
if (stored.type !== 'assistant') throw new Error('unreachable');
assert.deepEqual(stored.thinking?.parts, parts);
});
test('decodes released Automation origins as read-only legacy provenance', () => {
const message = decodeCanonicalMessage({
type: 'user',
id: 'message-1',
turnId: 'turn-1',
ts: 1,
text: 'Run the Automation',
origin: { kind: 'automation', automationId: 'automation-1' },
});
assert.deepEqual(message.type === 'user' ? message.origin : undefined, {
kind: 'legacy_automation',
automationId: 'automation-1',
});
const event = decodeRuntimeEvent(
baseEvent({
content: {
kind: 'text',
text: 'Run the Automation',
origin: { kind: 'automation', automationId: 'automation-1' } as never,
},
}),
);
assert.deepEqual(event.content?.kind === 'text' ? event.content.origin : undefined, {
kind: 'legacy_automation',
automationId: 'automation-1',
});
});
test('shares one decoder across all TurnOrigin variants', () => {
const origins = [
{ kind: 'scheduled_task', scheduledTaskId: 'task-1' },
{ kind: 'goal', goalId: 'goal-1' },
{ kind: 'agent_graph', graphId: 'graph-1', wakeId: 'wake-1', attemptId: 'attempt-1' },
] as const;
for (const origin of origins) assert.deepEqual(decodeTurnOrigin(origin), origin);
assert.deepEqual(decodeTurnOrigin({ kind: 'automation', automationId: 'automation-1' }), {
kind: 'legacy_automation',
automationId: 'automation-1',
});
assert.equal(decodeTurnOrigin({ kind: 'goal', goalId: 'goal-1', extra: true }), undefined);
});
describe('continuation-start protocol', () => {
test('reads legacy and current replay projections but rejects unknown versions', () => {
const continuationStart = {
protocol: 'continuation_start_v2',
provenance: 'runtime_admission',
claimId: 'claim-1',
boundaryDigest: 'sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
immediateSource: {
sessionId: 'sess-1',
invocationId: 'inv-source',
runId: 'run-source',
turnId: 'turn-source',
highWater: 1,
prefixDigest: 'sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
},
replayManifestDigest:
'sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
providerProjectionVersion: 1,
providerReplayDigest:
'sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
} as const;
assert.deepEqual(
decodeRuntimeEvent(
baseEvent({
role: 'system',
author: 'system',
content: undefined,
actions: { continuationStart },
}),
).actions?.continuationStart,
continuationStart,
);
assert.equal(
decodeRuntimeEvent({
...baseEvent({ role: 'system', author: 'system', content: undefined }),
actions: {
continuationStart: { ...continuationStart, providerProjectionVersion: 2 },
},
}).actions?.continuationStart?.providerProjectionVersion,
2,
);
assert.throws(
() =>
decodeRuntimeEvent({
...baseEvent({ role: 'system', author: 'system', content: undefined }),
actions: {
continuationStart: { ...continuationStart, providerProjectionVersion: 3 },
},
}),
/RuntimeEvent schema/,
);
});
});
describe('RuntimeEvent content variants', () => {
test('recognizes canonical durable Session context references', () => {
assert.equal(
isCanonicalStorageRef({
kind: 'session_context',
sessionId: 'session-1',
refId: 'read-image:owner-1',
}),
true,
);
assert.equal(
isCanonicalStorageRef({
kind: 'session_context',
sessionId: 'session-1',
refId: '😀'.repeat(512),
}),
true,
);
for (const ref of [
{ kind: 'session_context', sessionId: 'bad/session', refId: 'ref-1' },
{ kind: 'session_context', sessionId: 'session-1', refId: '' },
{ kind: 'session_context', sessionId: 'session-1', refId: '😀'.repeat(513) },
{ kind: 'session_context', sessionId: 'session-1', refId: 'ref-1', extra: true },
]) {
assert.equal(isCanonicalStorageRef(ref), false);
}
});
test('preserves sent inline references as message identity', () => {
const inlineReferences = [
{ kind: 'skill', value: '/skill:writer', label: 'Writer', start: 8 },
{
kind: 'workspace_file',
value: '@packages/ui/src/chat turn.tsx',
label: 'chat turn.tsx',
start: 22,
},
] as const;
const decoded = decodeMessageContent({
text: 'Inspect /skill:writer @packages/ui/src/chat turn.tsx',
inlineReferences: [...inlineReferences],
});
assert.deepEqual(decoded.inlineReferences, inlineReferences);
assert.notEqual(decoded.inlineReferences, inlineReferences);
assert.notEqual(decoded.inlineReferences?.[0], inlineReferences[0]);
assert.equal(
messageContentsEqual(decoded, {
text: 'Inspect /skill:writer @packages/ui/src/chat turn.tsx',
inlineReferences: [...inlineReferences],
}),
true,
);
assert.equal(
messageContentsEqual(decoded, {
text: 'Inspect /skill:writer @packages/ui/src/chat turn.tsx',
inlineReferences: [
{ ...inlineReferences[0]!, label: 'Renamed Writer' },
inlineReferences[1]!,
],
}),
false,
);
});
test('rejects an empty sent inline-reference value before UI projection', () => {
assert.throws(
() =>
decodeMessageContent({
text: 'hello',
inlineReferences: [{ kind: 'skill', value: '', label: 'Writer', start: 0 }],
}),
/Invalid MessageContent/,
);
});
test('rejects sent inline references outside their bounded kind grammar', () => {
const invalidReferences = [
{ kind: 'skill', value: 'writer', label: 'Writer' },
{ kind: 'skill', value: `/skill:${'a'.repeat(4_090)}`, label: 'Writer' },
{ kind: 'workspace_file', value: '@../secret', label: 'secret' },
{ kind: 'workspace_file', value: '@src/a.ts', label: '' },
{ kind: 'workspace_file', value: '@src/a.ts', label: 'a'.repeat(201) },
];
for (const reference of invalidReferences) {
assert.throws(
() =>
decodeMessageContent({
text: reference.value,
inlineReferences: [{ ...reference, start: 0 }],
}),
/Invalid MessageContent/,
);
}
assert.throws(
() =>
decodeMessageContent({
text: 'hello',
inlineReferences: Array.from({ length: 33 }, () => ({
kind: 'skill',
value: '/skill:writer',
label: 'Writer',
start: 0,
})),
}),
/Invalid MessageContent/,
);
});
test('preserves the exact occurrence selected as an inline reference', () => {
const text = 'literal @docs/a.ts then selected @docs/a.ts';
const selectedStart = text.lastIndexOf('@docs/a.ts');
assert.deepEqual(
decodeMessageContent({
text,
inlineReferences: [
{
kind: 'workspace_file',
value: '@docs/a.ts',
label: 'a.ts',
start: selectedStart,
},
],
}).inlineReferences,
[
{
kind: 'workspace_file',
value: '@docs/a.ts',
label: 'a.ts',
start: selectedStart,
},
],
);
});
test('rejects missing, mismatched, or overlapping reference occurrences', () => {
const invalid = [
[{ kind: 'skill', value: '/skill:writer', label: 'Writer' }],
[{ kind: 'skill', value: '/skill:writer', label: 'Writer', start: 1 }],
[
{ kind: 'skill', value: '/skill:writer', label: 'Writer', start: 0 },
{ kind: 'skill', value: '/skill:writer', label: 'Writer', start: 0 },
],
];
for (const inlineReferences of invalid) {
assert.throws(
() => decodeMessageContent({ text: '/skill:writer', inlineReferences }),
/Invalid MessageContent/,
);
}
});
test('preserves an explicit empty reference projection as message identity', () => {
assert.deepEqual(normalizeMessageContent({ text: 'plain', inlineReferences: [] }), {
text: 'plain',
inlineReferences: [],
});
assert.equal(
messageContentsEqual({ text: 'plain', inlineReferences: [] }, { text: 'plain' }),
false,
);
});
test('owns canonical MessageContent decoding, copying, and equality', () => {
const attachments = [
{
kind: 'code' as const,
name: 'b.ts',
mimeType: 'text/typescript',
bytes: 2,
ref: { kind: 'workspace_file' as const, relativePath: 'b.ts' },
},
{
kind: 'code' as const,
name: 'a.ts',
mimeType: 'text/typescript',
bytes: 1,
ref: { kind: 'workspace_file' as const, relativePath: 'a.ts' },
},
{
kind: 'image' as const,
name: 'snapshot.png',
mimeType: 'image/png',
bytes: 8,
ref: {
kind: 'session_context' as const,
sessionId: 'session-1',
refId: 'read-image:owner-1',
},
},
];
const quotes = [
{ text: 'first', label: 'Assistant', sourceTurnId: 'turn-1' },
{ text: 'second', sourceTurnId: 'turn-2' },
];
assert.deepEqual(normalizeMessageContent({ text: 'model', displayText: 'model' }), {
text: 'model',
});
assert.deepEqual(normalizeMessageContent({ text: 'model', attachments: [] }), {
text: 'model',
});
assert.deepEqual(normalizeMessageContent({ text: 'model', quotes: [] }), {
text: 'model',
});
const decoded = decodeMessageContent({ text: 'model', attachments, quotes });
assert.deepEqual(decoded.attachments, attachments);
assert.deepEqual(decoded.quotes, quotes);
assert.notEqual(decoded.attachments, attachments);
assert.notEqual(decoded.attachments?.[0], attachments[0]);
assert.notEqual(decoded.attachments?.[0]?.ref, attachments[0]?.ref);
assert.notEqual(decoded.quotes, quotes);
assert.notEqual(decoded.quotes?.[0], quotes[0]);
assert.equal(messageContentsEqual(decoded, { text: 'model', attachments, quotes }), true);
assert.equal(
messageContentsEqual(decoded, {
text: 'model',
attachments: [...attachments].reverse(),
quotes,
}),
false,
);
assert.equal(
messageContentsEqual(decoded, { text: 'model', attachments, quotes: [...quotes].reverse() }),
false,
);
assert.equal(
messageContentsEqual(decoded, {
text: 'model',
attachments,
quotes: [{ ...quotes[0]!, sourceTurnId: 'turn-other' }, quotes[1]!],
}),
false,
);
assert.throws(() => decodeMessageContent({ text: 'model', extra: true }), TypeError);
assert.throws(
() =>
decodeMessageContent({
text: 'model',
attachments: [{ ...attachments[0]!, ref: { kind: 'workspace_file', relativePath: 1 } }],
}),
TypeError,
);
assert.throws(
() =>
decodeMessageContent({
text: 'model',
attachments: [{ ...attachments[0]!, bytes: 1.5 }],
}),
TypeError,
);
for (const quote of [
{ text: 1 },
{ text: 'excerpt', label: 1 },
{ text: 'excerpt', sourceTurnId: 1 },
{ text: 'excerpt', extra: true },
]) {
assert.throws(() => decodeMessageContent({ text: 'model', quotes: [quote] }), TypeError);
}
assert.deepEqual(
decodeRuntimeEvent(
baseEvent({
role: 'user',
author: 'user',
content: {
kind: 'text',
text: 'model',
displayText: 'model',
attachments: [],
quotes,
},
}),
).content,
{ kind: 'text', text: 'model', quotes },
);
const event = decodeRuntimeEvent(
baseEvent({ content: { kind: 'text', text: 'model', quotes } }),
);
assert.notEqual(
event.content && 'quotes' in event.content ? event.content.quotes : undefined,
quotes,
);
assert.notEqual(
event.content && 'quotes' in event.content ? event.content.quotes?.[0] : undefined,
quotes[0],
);
const stored = decodeCanonicalMessage({
type: 'user',
id: 'message-1',
turnId: 'turn-1',
ts: 1,
text: 'model',
displayText: 'model',
attachments: [],
quotes,
});
assert.deepEqual(stored, {
type: 'user',
id: 'message-1',
turnId: 'turn-1',
ts: 1,
text: 'model',
quotes,
});
assert.equal(stored.type, 'user');
if (stored.type !== 'user') throw new Error('unreachable');
assert.notEqual(stored.quotes, quotes);
assert.notEqual(stored.quotes?.[0], quotes[0]);
assert.throws(
() =>
decodeCanonicalMessage({
type: 'user',
id: 'message-1',
turnId: 'turn-1',
ts: 1,
text: 'model',
quotes: [{ text: 'excerpt', sourceTurnId: 1 }],
}),
/Invalid stored message schema/,
);
});
});
test('rejects a Tool Result projection that references another Session artifact', () => {
assert.throws(
() =>
decodeRuntimeEvent(
baseEvent({
role: 'tool',
author: 'tool',
content: {
kind: 'function_response',
id: 'call-1',
name: 'Read',
result: { kind: 'image' },
modelProjection: {
version: 1,
kind: 'content',
parts: [
{
kind: 'artifact',
mediaType: 'image/png',
ref: {
kind: 'session_context',
sessionId: 'another-session',
refId: 'image-1',
},
},
],
},
},
}),
),
/Invalid RuntimeEvent schema/,
);
});
describe('RuntimeEvent actions', () => {
test('binds the managed mutation digest to its canonical execution semantics', () => {
const canonicalProfile = JSON.stringify({
protocol: 'managed_mutation_execution_profile_v1',
toolNames: ['Write', 'Edit'],
transform: 'pure_frozen_args_only_v1',
objectFormat: 'sha1',
pathPolicyVersion: 3,
resultSnapshot: {
maxBytes: 1_048_576,
maxDepth: 64,
maxNodes: 65_536,
maxProperties: 65_536,
maxArrayLength: 65_536,
format: 'strict_json_v1',
},
terminalAuthority: 'owner_committed_exact_outcome_v1',
genericFallback: 'forbidden',
});
assert.equal(
MANAGED_MUTATION_EXECUTION_PROFILE_V1_DIGEST,
`sha256:${createHash('sha256').update(canonicalProfile).digest('hex')}`,
);
assert.equal(JSON.stringify(MANAGED_MUTATION_EXECUTION_PROFILE_V1_SPEC), canonicalProfile);
});
test('decodes only a platform-independent T1-frozen managed mutation identity', () => {
const managedMutation = {
protocol: 'managed_mutation_v2',
repositoryId: 'repository_11111111111111111111111111111111',
workspaceId: 'workspace_22222222222222222222222222222222',
workspaceEpochId: 'epoch_33333333333333333333333333333333',
workspaceInstanceId: 'instance_44444444444444444444444444444444',
objectFormat: 'sha1',
baseWorkspaceVersionId: 'version_55555555555555555555555555555555',
baseAcceptedEventId: 'baseline-event-1',
baseHeadRevision: 1,
baseCommitOid: '1'.repeat(40),
baseTreeOid: '2'.repeat(40),
expectedPath: 'src/a.ts',
pathPolicyVersion: 3,
executionProfileDigest: MANAGED_MUTATION_EXECUTION_PROFILE_V1_DIGEST,
} as const;
const toolDispatch = {
protocol: 't1_after_preflight_v1',
operationId: 'operation-1',
providerToolCallId: 'call-1',
toolName: 'Write',
canonicalArgsHash: `sha256:${'b'.repeat(64)}`,
recoveryMode: 'reconcile',
managedMutation,
} as const;
assert.deepEqual(
decodeRuntimeEvent(baseEvent({ role: 'system', author: 'system', actions: { toolDispatch } }))
.actions?.toolDispatch?.managedMutation,
managedMutation,
);
for (const invalid of [
{ ...managedMutation, expectedPath: 'src/../secrets.txt' },
{ ...managedMutation, expectedPath: 'NoDe_MoDuLeS/pkg/index.js' },
{ ...managedMutation, expectedPath: '.GiT/config' },
{ ...managedMutation, expectedPath: 'x'.repeat(4097) },
{ ...managedMutation, pathPolicyVersion: 2 },
{ ...managedMutation, executionProfileDigest: `sha256:${'a'.repeat(64)}` },
{ ...managedMutation, baseAcceptedEventId: 'event id with spaces' },
{ ...managedMutation, baseHeadRevision: 0 },
{ ...managedMutation, baseTreeOid: 'not-an-oid' },
{ ...managedMutation, extra: true },
]) {
assert.throws(() =>
decodeRuntimeEvent(
baseEvent({
role: 'system',
author: 'system',
actions: { toolDispatch: { ...toolDispatch, managedMutation: invalid } as never },
}),
),
);
}
});
test('permission, question, and form interactions are first-class actions', () => {
const actions: RuntimeEventActions = {
permissionRequest: {
kind: 'tool_permission',
requestId: 'pr-1',
toolUseId: 'tc-1',
toolName: 'Bash',
category: 'shell_unsafe',
reason: 'shell_dangerous',
args: { command: 'rm foo' },
rememberForTurnAllowed: true,
},
permissionDecision: { requestId: 'pr-1', decision: 'deny' },
permissionAnswerAccepted: { requestId: 'hosted-pr-1' },
userQuestionAnswerAccepted: { requestId: 'question-1' },
formRequest: {
requestId: 'form-1',
toolUseId: 'tc-1',
message: 'Choose settings',
requester: { name: 'deploy' },
fields: [{ kind: 'boolean', name: 'confirm', label: 'Confirm', required: true }],
},
formAnswerAccepted: { requestId: 'form-1' },
};
assert.strictEqual(actions.permissionRequest?.category, 'shell_unsafe');
assert.strictEqual(actions.permissionDecision?.decision, 'deny');
assert.deepEqual(decodeRuntimeEvent(baseEvent({ actions })).actions?.permissionDecision, {
requestId: 'pr-1',
decision: 'deny',
});
const decodedActions = decodeRuntimeEvent(baseEvent({ actions })).actions;
for (const [accepted, requestId] of [
[decodedActions?.permissionAnswerAccepted, 'hosted-pr-1'],
[decodedActions?.userQuestionAnswerAccepted, 'question-1'],
[decodedActions?.formAnswerAccepted, 'form-1'],
] as const) {
assert.deepEqual(accepted, { requestId });
assert.ok(accepted);
assert.equal(Object.hasOwn(accepted, 'requestId'), true);
assert.equal(Object.hasOwn(accepted, 'decision'), false);
}
for (const invalidAcceptedAction of [
{ permissionAnswerAccepted: { requestId: 'pr-1', extra: true } },
{ userQuestionAnswerAccepted: { requestId: 'question-1', extra: true } },
{ formAnswerAccepted: { requestId: 'form-1', extra: true } },
{ permissionAnswerAccepted: Object.create({ requestId: 'inherited-pr-1' }) },
{ userQuestionAnswerAccepted: { requestId: 'x'.repeat(257) } },
{
formRequest: {
...actions.formRequest,
fields: [
{ kind: 'boolean', name: 'confirm', label: 'Confirm', required: true, extra: true },
],
},
},
]) {
assert.throws(() =>
decodeRuntimeEvent({
...baseEvent(),
actions: invalidAcceptedAction,
}),
);
}
});
test('permission closure acknowledgement has a narrow durable shape', () => {
const sessionEvent: SessionEvent = {
type: 'permission_closure_ack',
id: 'evt-closure-1',
turnId: 'turn-1',
ts: 100,
requestId: 'hosted-pr-1',
toolUseId: 'tool-use-1',
reason: 'timed_out',
};
const decoded = decodeRuntimeEvent(
baseEvent({
actions: {
permissionClosureAccepted: {
requestId: sessionEvent.requestId,
reason: sessionEvent.reason,
},
},
}),
).actions?.permissionClosureAccepted;
assert.deepEqual(decoded, { requestId: 'hosted-pr-1', reason: 'timed_out' });
assert.ok(decoded);
for (const permissionClosureAccepted of [
{ requestId: 'pr-1', reason: 'timed_out', extra: true },
{ requestId: 'x'.repeat(INTERACTION_ID_MAX_BYTES + 1), reason: 'timed_out' },
{ requestId: 'pr-1', reason: 'cancelled' },
]) {
assert.throws(() =>
decodeRuntimeEvent(baseEvent({ actions: { permissionClosureAccepted } as never })),
);
}
const conflictingActions: RuntimeEventActions[] = [
{ permissionAnswerAccepted: { requestId: 'hosted-pr-1' } },
{
permissionRequest: {
kind: 'tool_permission',
requestId: 'hosted-pr-1',
toolUseId: 'tool-use-1',
toolName: 'Bash',
category: 'shell_unsafe',
reason: 'shell_dangerous',
args: { command: 'rm foo' },
rememberForTurnAllowed: true,
},
},
{ endInvocation: true },
];
for (const conflictingAction of conflictingActions) {
assert.throws(() =>
decodeRuntimeEvent(
baseEvent({
actions: {
permissionClosureAccepted: {
requestId: 'hosted-pr-1',
reason: 'timed_out',
},
...conflictingAction,
},
}),
),
);
}
});
test('permission decisions optionally retain a bounded tool name', () => {
const permissionDecision = {
requestId: 'pr-1',
decision: 'allow' as const,
rememberForTurn: true,
toolName: 'Bash',
};
assert.deepEqual(
decodeRuntimeEvent(baseEvent({ actions: { permissionDecision } })).actions
?.permissionDecision,
permissionDecision,
);
for (const invalidPermissionDecision of [
{ requestId: 'pr-1', decision: 'allow', toolName: '' },
{
requestId: 'pr-1',
decision: 'allow',
toolName: 'x'.repeat(INTERACTION_TOOL_NAME_MAX_BYTES + 1),
},
{ requestId: 'pr-1', decision: 'allow', toolName: 'Bash', extra: true },
]) {
assert.throws(() =>
decodeRuntimeEvent({
...baseEvent(),
actions: { permissionDecision: invalidPermissionDecision },
}),
);
}
});
});
describe('isTerminalRuntimeEvent', () => {
test('classifies terminal status and explicit invocation completion', () => {
assert.strictEqual(isTerminalRuntimeEvent(baseEvent({ status: 'completed' })), true);
assert.strictEqual(isTerminalRuntimeEvent(baseEvent({ status: 'streaming' })), false);
assert.strictEqual(
isTerminalRuntimeEvent(baseEvent({ actions: { endInvocation: false } })),
false,
);
assert.strictEqual(
isTerminalRuntimeEvent(baseEvent({ actions: { endInvocation: true } })),
true,
);
});
});
describe('runtimeEventHasModelVisibleContent', () => {
test('retains nested CodeMode identity while excluding its content from model replay', () => {
const event = decodeRuntimeEvent(
baseEvent({
origin: 'code_mode',
modelVisibility: 'hidden',
content: { kind: 'function_call', id: 'nested-1', name: 'Read', args: { path: 'a.ts' } },
refs: {
toolCallId: 'nested-1',
operationId: 'nested-op-1',
parentToolCallId: 'exec-1',
parentOperationId: 'exec-op-1',
},
}),
);
assert.equal(event.origin, 'code_mode');
assert.equal(event.modelVisibility, 'hidden');
assert.equal(event.refs?.parentToolCallId, 'exec-1');
assert.equal(event.refs?.parentOperationId, 'exec-op-1');
assert.equal(runtimeEventHasModelVisibleContent(event), false);
});
test('classifies model-visible content by semantic kind', () => {
const visible = [
baseEvent({ role: 'user', content: { kind: 'text', text: 'hi' } }),
baseEvent({ content: { kind: 'thinking', text: 'r' } }),
baseEvent({ content: { kind: 'function_call', id: '1', name: 'Read', args: {} } }),
baseEvent({
content: {
kind: 'function_response',
id: '1',
name: 'Bash',
result: 'boom',
isError: true,
},
}),
];
for (const event of visible)
assert.strictEqual(runtimeEventHasModelVisibleContent(event), true);
const hidden = [
baseEvent({ content: { kind: 'text', text: '' } }),
baseEvent({ content: { kind: 'error', message: 'upstream failed' } }),
baseEvent({ actions: { tokenUsage: { input: 1, output: 1 } } }),
baseEvent({ refs: { toolCallId: 'tc-1' } }),
];
for (const event of hidden)
assert.strictEqual(runtimeEventHasModelVisibleContent(event), false);
});
test('counts structured user context as model-visible with empty inline text (#4804)', () => {
const visible = [
baseEvent({
role: 'user',
content: { kind: 'text', text: '', quotes: [{ text: 'pasted reference-sized excerpt' }] },
}),
baseEvent({
role: 'user',
content: {
kind: 'text',
text: '',
attachments: [
{
kind: 'code',
name: 'a.ts',
mimeType: 'text/typescript',
bytes: 10,
ref: { kind: 'workspace_file', relativePath: 'a.ts' },
},
],
},
}),
];
for (const event of visible)
assert.strictEqual(runtimeEventHasModelVisibleContent(event), true);
assert.strictEqual(
runtimeEventHasModelVisibleContent(baseEvent({ content: { kind: 'text', text: '' } })),
false,
);
});
test('keeps whitespace-only persisted text model-visible, without trimming (#4815 review)', () => {
// Replay visibility must stay compatible with everything admission has
// ever accepted. Trimming here would re-read stored whitespace-only
// events as invisible and block replay on them — #4804's own failure.
// Surfaces that want the trimmed judgement trim at their own boundary.
assert.strictEqual(
runtimeEventHasModelVisibleContent(baseEvent({ content: { kind: 'text', text: ' ' } })),
true,
);
assert.strictEqual(hasMeaningfulMessageContent({ text: ' ' }), true);
assert.strictEqual(hasMeaningfulMessageContent({ text: '' }), false);
assert.strictEqual(hasMeaningfulMessageContent({ text: '', quotes: [{ text: 'q' }] }), true);
});
test('counts directory references as a content carrier (#4815 review)', () => {
assert.strictEqual(
runtimeEventHasModelVisibleContent(
baseEvent({
role: 'user',
content: {
kind: 'text',
text: '',
directoryReferences: [{ hostId: 'host-a', path: '/workspace/source' }],
},
}),
),
true,
);
assert.strictEqual(
hasMeaningfulMessageContent({
text: '',
directoryReferences: [{ hostId: 'host-a', path: '/workspace/source' }],
}),
true,
);
});
});
test('runtime errors reject malformed retry decisions at the durable boundary', () => {
for (const retry of [
{ decision: 'exhausted', attempts: 0 },
{ decision: 'exhausted', attempts: 1.5 },
{ decision: 'declined', because: 'guess' },
{ decision: 'declined', because: 'policy', rawError: 'secret' },
]) {
assert.throws(() =>
decodeRuntimeEvent({ ...baseEvent(), content: { kind: 'error', message: 'failed', retry } }),
);
}
});
describe('RuntimeEvent reference validation', () => {
test('accepts only canonical source message digests', () => {
const digest = `sha256:${'a'.repeat(64)}` as `sha256:${string}`;
const event = baseEvent({ refs: { sourceMessageDigest: digest } });
assert.strictEqual(decodeRuntimeEvent(event).refs?.sourceMessageDigest, digest);
assert.throws(() =>
decodeRuntimeEvent({
...event,
refs: { sourceMessageDigest: 'sha256:not-a-digest' },
}),
);
});
test('accepts a provider-request trace reference and rejects a non-string reference', () => {
const event = baseEvent({ refs: { providerRequestTraceId: 'provider-trace-1' } });
assert.strictEqual(decodeRuntimeEvent(event).refs?.providerRequestTraceId, 'provider-trace-1');
assert.throws(() =>
decodeRuntimeEvent({
...event,
refs: { providerRequestTraceId: 123 },
}),
);
});
});
test('Coordination Runtime receipts survive decoding and reject unrecognized results', () => {
const coordination = {
actionId: 'action',
userText: 'Which task?',
clarification: 'Name a task.',
result: { disposition: 'clarify' as const, coordinationTurnId: 'turn-1' },
};
const event = baseEvent({
role: 'system',
author: 'host',
modelVisibility: 'hidden',
actions: { coordination },
});
assert.deepEqual(decodeRuntimeEvent(event).actions?.coordination, coordination);
for (const result of [
{ disposition: 'clarify', coordinationTurnId: '../invalid' },
{ disposition: 'stop_work', outcome: 'stop_delivered', targetSessionId: 'target' },
{
disposition: 'stop_work',
outcome: 'cancelled_pending',
targetSessionId: 'target',
targetTurnId: 'turn',
},
{ disposition: 'resume_work', outcome: 'resume_started', targetSessionId: 'target' },
{
disposition: 'resume_work',
outcome: 'already_running',
targetSessionId: 'target',
targetTurnId: 'turn',
},
]) {
assert.throws(() =>
decodeRuntimeEvent({
...event,
actions: { coordination: { ...coordination, result } },
}),
);
}
assert.throws(() =>
decodeRuntimeEvent({
...event,
actions: { coordination: { ...coordination, result: { disposition: 'execute_anything' } } },
}),
);
assert.throws(() =>
decodeRuntimeEvent({
...event,
actions: { coordination: { ...coordination, executionStatus: 'completed' } },
}),
);
});