Files
obelisk/tests/session-live-patch.test.mjs
T

85 lines
3.3 KiB
JavaScript
Raw Normal View History

import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
applySessionPatch,
createSessionPatch,
createSessionPatchCursor,
} from '../app/src/shared/session-patch.mjs';
function snapshot(overrides = {}) {
return {
messages: [
{ uuid: 'message-1', timestamp: '2026-07-14T00:00:01Z', text: 'one' },
{ uuid: 'message-2', timestamp: '2026-07-14T00:00:02Z', text: 'two' },
],
toolCalls: [{ id: 'call-1', message_uuid: 'message-1', name: 'exec', input_json: '"return 1"' }],
toolResults: [{ tool_use_id: 'call-1', message_uuid: 'message-1', content: 'running', is_error: 0 }],
subagents: [],
workflows: [{ run_id: 'workflow-1', status: 'running', agents: [{ agent_id: 'agent-1', state: 'running' }] }],
summaries: [],
...overrides,
};
}
test('session patch returns only appended and updated rows, then reconstructs the new snapshot', () => {
const current = snapshot();
const cursor = createSessionPatchCursor(current);
const next = snapshot({
messages: [...current.messages, { uuid: 'message-3', timestamp: '2026-07-14T00:00:03Z', text: 'three' }],
toolResults: [{ ...current.toolResults[0], content: 'complete' }],
});
const patch = createSessionPatch(next, cursor);
assert.deepEqual(patch.changes.messages.map(row => row.uuid), ['message-3']);
assert.deepEqual(patch.changes.toolResults.map(row => row.tool_use_id), ['call-1']);
assert.deepEqual(patch.changes.toolCalls, []);
assert.deepEqual(patch.removed.messages, []);
assert.equal(patch.positions.messages['message-3'], 2);
assert.deepEqual(applySessionPatch(current, cursor, patch), {
snapshot: next,
cursor: createSessionPatchCursor(next),
});
});
test('session patch reports removals and nested workflow updates', () => {
const current = snapshot();
const cursor = createSessionPatchCursor(current);
const next = snapshot({
messages: [current.messages[1]],
workflows: [{ run_id: 'workflow-1', status: 'complete', agents: [{ agent_id: 'agent-1', state: 'complete' }] }],
});
const patch = createSessionPatch(next, cursor);
assert.deepEqual(patch.removed.messages, ['message-1']);
assert.deepEqual(patch.changes.workflows, next.workflows);
assert.deepEqual(applySessionPatch(current, cursor, patch).snapshot, next);
});
test('session patch repositions existing rows when their content is unchanged', () => {
const current = snapshot();
const cursor = createSessionPatchCursor(current);
const next = snapshot({
messages: [current.messages[1], current.messages[0]],
});
const patch = createSessionPatch(next, cursor);
assert.deepEqual(applySessionPatch(current, cursor, patch).snapshot, next);
});
test('session patch cursor is compact and never carries transcript content', () => {
const largeText = 'private transcript content '.repeat(1000);
const current = snapshot({
messages: [{ uuid: 'message-large', timestamp: '2026-07-14T00:00:00Z', text: largeText }],
toolResults: [{ tool_use_id: 'call-large', message_uuid: 'message-large', content: largeText, is_error: 0 }],
});
const cursor = createSessionPatchCursor(current);
const serializedCursor = JSON.stringify(cursor);
assert.equal(serializedCursor.includes('private transcript content'), false);
assert.ok(serializedCursor.length < JSON.stringify(current).length / 20);
});