feat: implement PI-090 product tools

This commit is contained in:
brother7 committed 2026-08-23 15:14:50 +08:00
1 parent 77cdee7e73
commit 13ab383e53
32 files changed
+2035 -49

No files matched your search

+50
View File
@@ -104,6 +104,56 @@ describe('Pi event projector', () => {
}));
});
it('projects versioned product-tool details and suppresses unknown versions', async () => {
const projector = new PiEventProjector({ createId: () => 'unused' });
let snapshot = emptySnapshot();
snapshot.nodes.push({
kind: 'tool', id: 'tool-task-state', toolCallId: 'call-task-state', toolName: 'task_state',
title: 'task_state', inputText: '{}', status: 'running', output: [],
});
snapshot = apply(snapshot, await projector.project(snapshot, {
type: 'tool_execution_end',
toolCallId: 'call-task-state',
isError: false,
result: {
content: [{ type: 'text', text: 'done' }],
details: {
schema: 'task-state.v1',
tasks: [{ id: 'task-a', title: 'Implement product tools', status: 'complete' }],
},
},
}));
expect(snapshot.nodes).toContainEqual(expect.objectContaining({
kind: 'tool',
id: 'tool-task-state',
details: {
schema: 'task-state.v1',
tasks: [{ id: 'task-a', title: 'Implement product tools', status: 'complete' }],
},
}));
snapshot.nodes.push({
kind: 'tool', id: 'tool-browser', toolCallId: 'call-browser', toolName: 'agent_browser',
title: 'agent_browser', inputText: '{}', status: 'running', output: [],
});
snapshot = apply(snapshot, await projector.project(snapshot, {
type: 'tool_execution_end',
toolCallId: 'call-browser',
isError: false,
result: {
content: [{ type: 'text', text: 'RAW_BROWSER_OUTPUT' }],
details: { schema: 'agent-browser.v2', attachmentId: 'RAW_ATTACHMENT' },
},
}));
expect(JSON.stringify(snapshot)).not.toContain('RAW_BROWSER_OUTPUT');
expect(JSON.stringify(snapshot)).not.toContain('RAW_ATTACHMENT');
expect(snapshot.nodes).toContainEqual(expect.objectContaining({
kind: 'tool',
id: 'tool-browser',
output: [expect.objectContaining({ text: 'Tool details are unavailable for this version.' })],
}));
});
it('keeps one assistant UI identity while content-index deltas become an authoritative message', async () => {
const projector = new PiEventProjector({
createId: () => 'assistant-ui-a',