blob: 9872b65f1d5c3d9d15835cba4a406e778379af56 [file]
import assert from 'node:assert/strict';
import test from 'node:test';
import type { RuntimeEvent } from '@maka/core/runtime-event';
import {
activeCompactionCoverageFromEntries,
buildActiveCompactionHeadAnchor,
buildActiveCompactionSourceIndex,
selectActiveCompactionSafeSpan,
validateActiveCompactionCoverageForSourceIndex,
} from '../active-compaction-kernel.js';
import type { ModelMessage } from '../model-protocol.js';
import {
ACTIVE_ARCHIVED_TOOL_RESULT_PLACEHOLDER_KIND,
type ActiveArchivedToolResultPlaceholder,
} from '../active-tool-result-prune.js';
import { ARCHIVED_TOOL_RESULT_REWRITE_VERSION } from '../tool-result-archive.js';
test('active compaction kernel selects only complete provider episodes after the head anchor', () => {
const messages = fixtureMessages();
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages,
stepNumber: 2,
charsPerToken: 1,
});
const selection = selectActiveCompactionSafeSpan({
index,
messages,
headAnchor: buildActiveCompactionHeadAnchor(messages, 0, 1),
policy: {
enabled: true,
minStepNumber: 1,
highWaterRatio: 0.1,
maxActiveEstimatedTokens: 1,
minSafePrefixEstimatedTokens: 0,
preserveRecentCompletedEpisodes: 1,
},
});
assert.equal(selection.decision, 'selected');
if (selection.decision !== 'selected') return;
assert.equal(selection.startMessageIndex, 1);
assert.equal(selection.endMessageIndex, 2);
assert.deepEqual(selection.coverage.toolCallIds, ['call-1']);
assert.equal(
validateActiveCompactionCoverageForSourceIndex(selection.coverage, index).valid,
true,
);
});
test('active compaction kernel fails closed on hash drift and split tool pairs', () => {
const messages = fixtureMessages();
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages,
});
const callEntry = index.entries.find((entry) => entry.contentKind === 'function_call');
assert.ok(callEntry);
const splitCoverage = activeCompactionCoverageFromEntries([callEntry]);
const splitValidation = validateActiveCompactionCoverageForSourceIndex(splitCoverage, index);
assert.equal(splitValidation.valid, false);
assert.ok(splitValidation.reasons.includes('tool_pair_split'));
const hashValidation = validateActiveCompactionCoverageForSourceIndex(
{ ...splitCoverage, bodySha256: ['not-the-source-hash'] },
index,
);
assert.equal(hashValidation.valid, false);
assert.ok(hashValidation.reasons.includes('source_hash_mismatch'));
});
test('active compaction kernel does not relabel a tool result from a call-only runtime match', () => {
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages: fixtureMessages(),
runtimeEvents: [
{
id: 'event-call-1',
invocationId: 'invocation-1',
runId: 'run-1',
sessionId: 'session-1',
turnId: 'turn-1',
ts: 1,
partial: false,
role: 'model',
author: 'agent',
content: {
kind: 'function_call',
id: 'call-1',
name: 'Read',
args: { path: 'README.md' },
},
} satisfies RuntimeEvent,
],
});
const resultEntry = index.entries.find((entry) => entry.messageIndex === 2);
assert.ok(resultEntry);
assert.equal(resultEntry.contentKind, 'tool_result');
assert.equal(resultEntry.runtimeEventId, undefined);
});
test('active compaction kernel binds runtime events by role exactly once', () => {
const sharedText = 'same provider-visible text';
const messages = [
{ role: 'user', content: sharedText },
{ role: 'assistant', content: sharedText },
{ role: 'assistant', content: sharedText },
] as ModelMessage[];
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages,
runtimeEvents: [
runtimeTextEvent('event-user', 'user', sharedText),
runtimeTextEvent('event-model', 'model', sharedText),
],
});
assert.equal(index.entries[0]?.runtimeEventId, 'event-user');
assert.equal(index.entries[1]?.runtimeEventId, 'event-model');
assert.equal(index.entries[2]?.runtimeEventId, undefined);
});
test('active compaction kernel leaves ambiguous runtime matches unbound', () => {
const sharedText = 'ambiguous model text';
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages: [{ role: 'assistant', content: sharedText }] as ModelMessage[],
runtimeEvents: [
runtimeTextEvent('event-model-1', 'model', sharedText),
runtimeTextEvent('event-model-2', 'model', sharedText),
],
});
assert.equal(index.entries[0]?.runtimeEventId, undefined);
});
test('active compaction kernel fails open on duplicate or missing tool identities', () => {
for (const messages of malformedToolEpisodes()) {
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages,
stepNumber: 2,
charsPerToken: 1,
});
const selection = selectActiveCompactionSafeSpan({
index,
messages,
headAnchor: buildActiveCompactionHeadAnchor(messages, 0, 1),
policy: {
enabled: true,
minStepNumber: 1,
highWaterRatio: 0.1,
maxActiveEstimatedTokens: 1,
minSafePrefixEstimatedTokens: 0,
},
});
assert.ok(selection.decision === 'failedOpen');
assert.equal(selection.reason, 'tool_pair_split');
}
});
test('active compaction kernel preserves archived placeholder provenance with archiveRequired', () => {
const placeholder = activePlaceholder();
const messages = [
{ role: 'user', content: 'inspect the archive' },
{
role: 'assistant',
content: [
{
type: 'tool-call',
toolCallId: placeholder.toolCallId,
toolName: placeholder.toolName,
input: { path: 'notes.md' },
},
],
},
{
role: 'tool',
content: [
{
type: 'tool-result',
toolCallId: placeholder.toolCallId,
toolName: placeholder.toolName,
output: { type: 'text', value: JSON.stringify(placeholder) },
},
],
},
] as ModelMessage[];
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages,
stepNumber: 2,
charsPerToken: 1,
runtimeEvents: [runtimeToolCallEvent(placeholder.toolCallId, placeholder.toolName)],
});
const archived = index.entries.find(
(entry) => entry.contentKind === 'active_archive_placeholder',
);
assert.ok(archived);
assert.equal(archived.archiveRef?.artifactId, placeholder.artifactId);
assert.equal(archived.archiveRef?.bodySha256, placeholder.bodySha256);
assert.equal(archived.archiveRef?.originalEstimatedTokens, placeholder.originalEstimatedTokens);
assert.equal(archived.archiveRef?.originalBytes, placeholder.originalBytes);
assert.equal(archived.toolCallId, placeholder.toolCallId);
const selection = selectActiveCompactionSafeSpan({
index,
messages,
headAnchor: buildActiveCompactionHeadAnchor(messages, 0, 1),
policy: {
enabled: true,
minStepNumber: 1,
highWaterRatio: 0.1,
maxActiveEstimatedTokens: 1,
minSafePrefixEstimatedTokens: 0,
archiveRequired: true,
},
});
assert.equal(selection.decision, 'selected');
});
test('active compaction kernel binds safe-span selection to the exact user head', () => {
const messages = fixtureMessages();
const headAnchor = buildActiveCompactionHeadAnchor(messages, 0);
const changedMessages: ModelMessage[] = [
{ role: 'user', content: 'changed request' } as ModelMessage,
...messages.slice(1),
];
const index = buildActiveCompactionSourceIndex({
sessionId: 'session-1',
turnId: 'turn-1',
messages: changedMessages,
});
const selection = selectActiveCompactionSafeSpan({
index,
messages: changedMessages,
headAnchor,
policy: { enabled: true, minStepNumber: 0 },
});
assert.equal(selection.decision, 'failedOpen');
assert.equal(selection.reason, 'head_anchor_mismatch');
});
function fixtureMessages(): ModelMessage[] {
return [
{ role: 'user', content: 'inspect the repository' },
{
role: 'assistant',
content: [
{
type: 'tool-call',
toolCallId: 'call-1',
toolName: 'Read',
input: { path: 'README.md' },
},
],
},
{
role: 'tool',
content: [
{
type: 'tool-result',
toolCallId: 'call-1',
toolName: 'Read',
output: { type: 'text', value: 'contents' },
},
],
},
{ role: 'assistant', content: 'The repository is ready.' },
] as ModelMessage[];
}
function runtimeTextEvent(id: string, role: RuntimeEvent['role'], text: string): RuntimeEvent {
return {
id,
invocationId: 'invocation-1',
runId: 'run-1',
sessionId: 'session-1',
turnId: 'turn-1',
ts: 1,
partial: false,
role,
author: role === 'user' ? 'user' : 'agent',
content: { kind: 'text', text },
};
}
function runtimeToolCallEvent(toolCallId: string, toolName: string): RuntimeEvent {
return {
id: 'event-call',
invocationId: 'invocation-1',
runId: 'run-1',
sessionId: 'session-1',
turnId: 'turn-1',
ts: 1,
partial: false,
role: 'model',
author: 'agent',
content: {
kind: 'function_call',
id: toolCallId,
name: toolName,
args: { path: 'notes.md' },
},
};
}
function activePlaceholder(): ActiveArchivedToolResultPlaceholder {
return {
kind: ACTIVE_ARCHIVED_TOOL_RESULT_PLACEHOLDER_KIND,
rewriteVersion: ARCHIVED_TOOL_RESULT_REWRITE_VERSION,
artifactId: 'artifact-tool-1',
turnId: 'turn-1',
toolCallId: 'call-archive-1',
toolName: 'Read',
bodySha256: 'a'.repeat(64),
originalEstimatedTokens: 123,
originalBytes: 456,
reason: 'active_current_turn_tool_result_pruned_before_next_step',
};
}
function malformedToolEpisodes(): ModelMessage[][] {
const head = { role: 'user', content: 'inspect' } as ModelMessage;
const call = (toolCallId?: string) =>
({
role: 'assistant',
content: [
{
type: 'tool-call',
...(toolCallId ? { toolCallId } : {}),
toolName: 'Read',
input: { path: 'README.md' },
},
],
}) as ModelMessage;
const result = (toolCallId: string) =>
({
role: 'tool',
content: [
{
type: 'tool-result',
toolCallId,
toolName: 'Read',
output: { type: 'text', value: 'contents' },
},
],
}) as ModelMessage;
return [
[head, call('duplicate'), call('duplicate'), result('duplicate')],
[head, call('duplicate'), result('duplicate'), result('duplicate')],
[head, call(), result('missing')],
];
}