@dxos/assistant 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/lib/neutral/chunk-2TBLG3XY.mjs +1793 -0
- package/dist/lib/neutral/chunk-2TBLG3XY.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/extraction/index.mjs +219 -0
- package/dist/lib/neutral/extraction/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +537 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/testing/index.mjs +111 -0
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/conversation/context.d.ts +155 -0
- package/dist/types/src/conversation/context.d.ts.map +1 -0
- package/dist/types/src/conversation/context.test.d.ts +2 -0
- package/dist/types/src/conversation/context.test.d.ts.map +1 -0
- package/dist/types/src/conversation/index.d.ts +2 -1
- package/dist/types/src/conversation/index.d.ts.map +1 -1
- package/dist/types/src/conversation/session.d.ts +78 -0
- package/dist/types/src/conversation/session.d.ts.map +1 -0
- package/dist/types/src/conversation/session.test.d.ts.map +1 -0
- package/dist/types/src/diff.d.ts +17 -0
- package/dist/types/src/diff.d.ts.map +1 -0
- package/dist/types/src/diff.test.d.ts +2 -0
- package/dist/types/src/diff.test.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +67 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- package/dist/types/src/execution-graph.d.ts +85 -0
- package/dist/types/src/execution-graph.d.ts.map +1 -0
- package/dist/types/src/execution-graph.test.d.ts +2 -0
- package/dist/types/src/execution-graph.test.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts +0 -1
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction.d.ts +1066 -215
- package/dist/types/src/extraction/extraction.d.ts.map +1 -1
- package/dist/types/src/extraction/index.d.ts +0 -1
- package/dist/types/src/extraction/index.d.ts.map +1 -1
- package/dist/types/src/extraction/quotes.d.ts +3 -3
- package/dist/types/src/extraction/quotes.d.ts.map +1 -1
- package/dist/types/src/functions/index.d.ts +2 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/services.d.ts +17 -0
- package/dist/types/src/functions/services.d.ts.map +1 -0
- package/dist/types/src/functions.test.d.ts +2 -0
- package/dist/types/src/functions.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +7 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/service/AgentService.d.ts +75 -0
- package/dist/types/src/service/AgentService.d.ts.map +1 -0
- package/dist/types/src/service/AgentService.test.d.ts +2 -0
- package/dist/types/src/service/AgentService.test.d.ts.map +1 -0
- package/dist/types/src/service/agent-process.d.ts +21 -0
- package/dist/types/src/service/agent-process.d.ts.map +1 -0
- package/dist/types/src/service/index.d.ts +3 -0
- package/dist/types/src/service/index.d.ts.map +1 -0
- package/dist/types/src/session/artifact-diff.d.ts +27 -0
- package/dist/types/src/session/artifact-diff.d.ts.map +1 -0
- package/dist/types/src/session/error-handling.d.ts +4 -0
- package/dist/types/src/session/error-handling.d.ts.map +1 -0
- package/dist/types/src/session/format.d.ts +16 -0
- package/dist/types/src/session/format.d.ts.map +1 -0
- package/dist/types/src/session/format.test.d.ts +2 -0
- package/dist/types/src/session/format.test.d.ts.map +1 -0
- package/dist/types/src/session/index.d.ts +5 -1
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/observer.d.ts +23 -0
- package/dist/types/src/session/observer.d.ts.map +1 -0
- package/dist/types/src/session/request.d.ts +106 -0
- package/dist/types/src/session/request.d.ts.map +1 -0
- package/dist/types/src/session/request.test.d.ts +2 -0
- package/dist/types/src/session/request.test.d.ts.map +1 -0
- package/dist/types/src/session/session-ollama.test.d.ts +2 -0
- package/dist/types/src/session/session-ollama.test.d.ts.map +1 -0
- package/dist/types/src/session/toolkit.d.ts +16 -0
- package/dist/types/src/session/toolkit.d.ts.map +1 -0
- package/dist/types/src/session/version-pin.d.ts +5 -5
- package/dist/types/src/session/version-pin.d.ts.map +1 -1
- package/dist/types/src/templates/index.d.ts +2 -0
- package/dist/types/src/templates/index.d.ts.map +1 -0
- package/dist/types/src/templates/system.d.ts +17 -0
- package/dist/types/src/templates/system.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -2
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/layer.d.ts +40 -0
- package/dist/types/src/testing/layer.d.ts.map +1 -0
- package/dist/types/src/tracing.d.ts +223 -0
- package/dist/types/src/tracing.d.ts.map +1 -0
- package/dist/types/src/types/artifact.d.ts +28 -0
- package/dist/types/src/types/artifact.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +60 -29
- package/src/conversation/context.test.ts +52 -0
- package/src/conversation/context.ts +403 -0
- package/src/conversation/index.ts +2 -1
- package/src/conversation/session.test.ts +58 -0
- package/src/conversation/session.ts +300 -0
- package/src/diff.test.ts +74 -0
- package/src/diff.ts +93 -0
- package/src/errors.ts +15 -0
- package/src/execution-graph.test.ts +740 -0
- package/src/execution-graph.ts +509 -0
- package/src/extraction/extraction-ner-function/index.ts +0 -1
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +3 -1
- package/src/extraction/extraction.ts +44 -15
- package/src/extraction/index.ts +0 -1
- package/src/extraction/quotes.test.ts +3 -3
- package/src/extraction/quotes.ts +6 -7
- package/src/functions/index.ts +5 -0
- package/src/functions/services.ts +214 -0
- package/src/functions.conversations.json +1 -0
- package/src/functions.test.ts +88 -0
- package/src/index.ts +7 -5
- package/src/service/AgentService.conversations.json +1 -0
- package/src/service/AgentService.test.ts +169 -0
- package/src/service/AgentService.ts +184 -0
- package/src/service/agent-process.ts +364 -0
- package/src/service/index.ts +6 -0
- package/src/session/artifact-diff.ts +41 -0
- package/src/session/error-handling.ts +41 -0
- package/src/session/format.test.ts +132 -0
- package/src/session/format.ts +149 -0
- package/src/session/index.ts +5 -1
- package/src/session/observer.ts +62 -0
- package/src/session/request.conversations.json +1 -0
- package/src/session/request.test.ts +195 -0
- package/src/session/request.ts +344 -0
- package/src/session/session-ollama.test.ts +81 -0
- package/src/session/toolkit.ts +47 -0
- package/src/session/version-pin.ts +12 -12
- package/src/templates/index.ts +5 -0
- package/src/templates/instructions/format.tpl +57 -0
- package/src/templates/instructions/system.tpl +85 -0
- package/src/templates/system.ts +42 -0
- package/src/testing/index.ts +2 -8
- package/src/testing/layer.ts +236 -0
- package/src/tracing.ts +43 -0
- package/src/types/artifact.ts +89 -0
- package/src/types/index.ts +5 -0
- package/src/typings.d.ts +5 -0
- package/dist/lib/browser/index.mjs +0 -2019
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node-esm/index.mjs +0 -2021
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/types/bin/chat.d.ts +0 -2
- package/dist/types/bin/chat.d.ts.map +0 -1
- package/dist/types/src/blueprint/blueprint.d.ts +0 -41
- package/dist/types/src/blueprint/blueprint.d.ts.map +0 -1
- package/dist/types/src/blueprint/index.d.ts +0 -3
- package/dist/types/src/blueprint/index.d.ts.map +0 -1
- package/dist/types/src/blueprint/registry.d.ts +0 -7
- package/dist/types/src/blueprint/registry.d.ts.map +0 -1
- package/dist/types/src/context/binder.d.ts +0 -34
- package/dist/types/src/context/binder.d.ts.map +0 -1
- package/dist/types/src/context/binding.d.ts +0 -38
- package/dist/types/src/context/binding.d.ts.map +0 -1
- package/dist/types/src/context/index.d.ts +0 -3
- package/dist/types/src/context/index.d.ts.map +0 -1
- package/dist/types/src/conversation/conversation.d.ts +0 -44
- package/dist/types/src/conversation/conversation.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +0 -4
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +0 -2
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts +0 -2
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +0 -208
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +0 -2
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +0 -1
- package/dist/types/src/research/exa.d.ts +0 -7
- package/dist/types/src/research/exa.d.ts.map +0 -1
- package/dist/types/src/research/graph.d.ts +0 -41
- package/dist/types/src/research/graph.d.ts.map +0 -1
- package/dist/types/src/research/graph.test.d.ts +0 -2
- package/dist/types/src/research/graph.test.d.ts.map +0 -1
- package/dist/types/src/research/index.d.ts +0 -4
- package/dist/types/src/research/index.d.ts.map +0 -1
- package/dist/types/src/research/research.d.ts +0 -10
- package/dist/types/src/research/research.d.ts.map +0 -1
- package/dist/types/src/research/research.test.d.ts +0 -2
- package/dist/types/src/research/research.test.d.ts.map +0 -1
- package/dist/types/src/session/session.d.ts +0 -283
- package/dist/types/src/session/session.d.ts.map +0 -1
- package/dist/types/src/session/session.test.d.ts.map +0 -1
- package/dist/types/src/session/version-pin.test.d.ts +0 -2
- package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
- package/dist/types/src/summarization/summarization.test.d.ts +0 -2
- package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337321991.d.ts +0 -38
- package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337331526.d.ts +0 -37
- package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337344119.d.ts +0 -58
- package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +0 -1
- package/dist/types/src/types.d.ts +0 -3
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/blueprint/blueprint.ts +0 -75
- package/src/blueprint/index.ts +0 -6
- package/src/blueprint/registry.ts +0 -15
- package/src/context/binder.ts +0 -101
- package/src/context/binding.ts +0 -31
- package/src/context/index.ts +0 -6
- package/src/conversation/conversation.ts +0 -103
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +0 -95
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +0 -66
- package/src/extraction/extraction-llm-function/index.ts +0 -5
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +0 -115
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +0 -54
- package/src/research/exa.ts +0 -100
- package/src/research/graph.test.ts +0 -15
- package/src/research/graph.ts +0 -337
- package/src/research/index.ts +0 -7
- package/src/research/instructions-research.tpl +0 -97
- package/src/research/research.test.ts +0 -190
- package/src/research/research.ts +0 -90
- package/src/session/session.test.ts +0 -275
- package/src/session/session.ts +0 -582
- package/src/session/version-pin.test.ts +0 -26
- package/src/summarization/summarization.test.ts +0 -221
- package/src/testing/exa-search-1748337321991.ts +0 -131
- package/src/testing/exa-search-1748337331526.ts +0 -144
- package/src/testing/exa-search-1748337344119.ts +0 -133
- package/src/typedefs.d.ts +0 -8
- package/src/types.ts +0 -8
- /package/dist/types/src/{session → conversation}/session.test.d.ts +0 -0
- /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, expect, it } from '@effect/vitest';
|
|
6
|
+
|
|
7
|
+
import { AgentStatus } from '@dxos/ai';
|
|
8
|
+
import { Obj } from '@dxos/echo';
|
|
9
|
+
import { ObjectId } from '@dxos/keys';
|
|
10
|
+
import { log } from '@dxos/log';
|
|
11
|
+
import { type ContentBlock, Message } from '@dxos/types';
|
|
12
|
+
|
|
13
|
+
import { ExecutionGraph } from './execution-graph';
|
|
14
|
+
|
|
15
|
+
// Helper function to create valid object IDs for testing.
|
|
16
|
+
const createTestId = () => ObjectId.random();
|
|
17
|
+
|
|
18
|
+
const SKIP_BLOCKS: ContentBlock.Any['_tag'][] = [];
|
|
19
|
+
|
|
20
|
+
describe('ExecutionGraph', () => {
|
|
21
|
+
describe('basic functionality', () => {
|
|
22
|
+
it('should create an empty graph initially', () => {
|
|
23
|
+
const graph = new ExecutionGraph();
|
|
24
|
+
const result = graph.getGraph();
|
|
25
|
+
|
|
26
|
+
expect(result.branches).toEqual([]);
|
|
27
|
+
expect(result.commits).toEqual([]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should add a simple user message', () => {
|
|
31
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
32
|
+
const messageId = createTestId();
|
|
33
|
+
const message = Obj.make(Message.Message, {
|
|
34
|
+
id: messageId,
|
|
35
|
+
created: '2025-01-01T00:00:00Z',
|
|
36
|
+
sender: { role: 'user' },
|
|
37
|
+
blocks: [
|
|
38
|
+
{
|
|
39
|
+
_tag: 'text',
|
|
40
|
+
text: 'Hello, world!',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
properties: {},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
graph.addEvents([message]);
|
|
47
|
+
const result = graph.getGraph();
|
|
48
|
+
|
|
49
|
+
expect(result.branches).toEqual(['main']);
|
|
50
|
+
expect(result.commits).toHaveLength(1);
|
|
51
|
+
expect(result.commits[0]).toMatchObject({
|
|
52
|
+
id: `${messageId}_block_0`,
|
|
53
|
+
branch: 'main',
|
|
54
|
+
message: 'Processing request...',
|
|
55
|
+
parents: [],
|
|
56
|
+
tags: ['user'],
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should handle basic status & message processing', () => {
|
|
61
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
62
|
+
const status = Obj.make(AgentStatus, {
|
|
63
|
+
created: '2025-01-01T00:00:00Z',
|
|
64
|
+
message: 'Running Research',
|
|
65
|
+
});
|
|
66
|
+
const message = Obj.make(Message.Message, {
|
|
67
|
+
created: '2025-09-29T14:29:37.860Z',
|
|
68
|
+
sender: {
|
|
69
|
+
role: 'user',
|
|
70
|
+
},
|
|
71
|
+
blocks: [
|
|
72
|
+
{
|
|
73
|
+
_tag: 'text',
|
|
74
|
+
text: '{"id":"01K6AXZKK79H4E54RKP1YZDARK","@type":"dxn:type:org.dxos.type.organization:0.1.0","@meta":{"keys":[]},"name":"Blue Yard","website":"https://blueyard.com"}',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
properties: {},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
graph.addEvents([status, message]);
|
|
81
|
+
const result = graph.getGraph();
|
|
82
|
+
log.info('result', result);
|
|
83
|
+
|
|
84
|
+
expect(result.branches).toEqual(['main']);
|
|
85
|
+
expect(result.commits).toHaveLength(2);
|
|
86
|
+
expect(result.commits[0].branch).toEqual('main');
|
|
87
|
+
expect(result.commits[0].message).toEqual('Running Research');
|
|
88
|
+
expect(result.commits[0].parents).toEqual([]);
|
|
89
|
+
expect(result.commits[1].branch).toEqual('main');
|
|
90
|
+
expect(result.commits[1].message).toEqual('Processing request...');
|
|
91
|
+
expect(result.commits[1].parents).toEqual([status.id]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should add an assistant message with text', () => {
|
|
95
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
96
|
+
const messageId = createTestId();
|
|
97
|
+
const message = Obj.make(Message.Message, {
|
|
98
|
+
id: messageId,
|
|
99
|
+
created: '2025-01-01T00:00:00Z',
|
|
100
|
+
sender: { role: 'assistant' },
|
|
101
|
+
blocks: [
|
|
102
|
+
{
|
|
103
|
+
_tag: 'text',
|
|
104
|
+
text: 'Hello! How can I help you today?',
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
properties: {},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
graph.addEvents([message]);
|
|
111
|
+
const result = graph.getGraph();
|
|
112
|
+
|
|
113
|
+
expect(result.commits).toHaveLength(1);
|
|
114
|
+
expect(result.commits[0]).toMatchObject({
|
|
115
|
+
id: `${messageId}_block_0`,
|
|
116
|
+
branch: 'main',
|
|
117
|
+
message: 'Response (7 words)',
|
|
118
|
+
parents: [],
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('sequential chaining within messages', () => {
|
|
124
|
+
it('should chain blocks within a message', () => {
|
|
125
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
126
|
+
const messageId = createTestId();
|
|
127
|
+
const message = Obj.make(Message.Message, {
|
|
128
|
+
id: messageId,
|
|
129
|
+
created: '2025-01-01T00:00:00Z',
|
|
130
|
+
sender: { role: 'assistant' },
|
|
131
|
+
blocks: [
|
|
132
|
+
{
|
|
133
|
+
_tag: 'text',
|
|
134
|
+
text: 'First block',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
_tag: 'text',
|
|
138
|
+
text: 'Second block',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
_tag: 'text',
|
|
142
|
+
text: 'Third block',
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
properties: {},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
graph.addEvents([message]);
|
|
149
|
+
const result = graph.getGraph();
|
|
150
|
+
|
|
151
|
+
expect(result.commits).toHaveLength(3);
|
|
152
|
+
|
|
153
|
+
// First block has no parents
|
|
154
|
+
expect(result.commits[0]).toMatchObject({
|
|
155
|
+
id: `${messageId}_block_0`,
|
|
156
|
+
parents: [],
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Second block has first block as parent
|
|
160
|
+
expect(result.commits[1]).toMatchObject({
|
|
161
|
+
id: `${messageId}_block_1`,
|
|
162
|
+
parents: [`${messageId}_block_0`],
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Third block has second block as parent
|
|
166
|
+
expect(result.commits[2]).toMatchObject({
|
|
167
|
+
id: `${messageId}_block_2`,
|
|
168
|
+
parents: [`${messageId}_block_1`],
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should chain across multiple messages', () => {
|
|
173
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
174
|
+
|
|
175
|
+
// First message
|
|
176
|
+
const message1Id = createTestId();
|
|
177
|
+
const message1 = Obj.make(Message.Message, {
|
|
178
|
+
id: message1Id,
|
|
179
|
+
created: '2025-01-01T00:00:00Z',
|
|
180
|
+
sender: { role: 'user' },
|
|
181
|
+
blocks: [{ _tag: 'text', text: 'Hello' }],
|
|
182
|
+
properties: {},
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Second message
|
|
186
|
+
const message2Id = createTestId();
|
|
187
|
+
const message2 = Obj.make(Message.Message, {
|
|
188
|
+
id: message2Id,
|
|
189
|
+
created: '2025-01-01T00:01:00Z',
|
|
190
|
+
sender: { role: 'assistant' },
|
|
191
|
+
blocks: [{ _tag: 'text', text: 'Hi there!' }],
|
|
192
|
+
properties: {},
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
graph.addEvents([message1, message2]);
|
|
196
|
+
const result = graph.getGraph();
|
|
197
|
+
|
|
198
|
+
expect(result.commits).toHaveLength(2);
|
|
199
|
+
|
|
200
|
+
// First message block has no parents
|
|
201
|
+
expect(result.commits[0]).toMatchObject({
|
|
202
|
+
id: `${message1Id}_block_0`,
|
|
203
|
+
parents: [],
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Second message block has first message block as parent
|
|
207
|
+
expect(result.commits[1]).toMatchObject({
|
|
208
|
+
id: `${message2Id}_block_0`,
|
|
209
|
+
parents: [`${message1Id}_block_0`],
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe('tool calls and results', () => {
|
|
215
|
+
it('should handle tool calls and results with proper parent relationships', () => {
|
|
216
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
217
|
+
|
|
218
|
+
const message1Id = createTestId();
|
|
219
|
+
const message2Id = createTestId();
|
|
220
|
+
const statusId = createTestId();
|
|
221
|
+
const toolCallId = 'tool1';
|
|
222
|
+
|
|
223
|
+
// Assistant message with tool call
|
|
224
|
+
const toolCallMessage = Obj.make(Message.Message, {
|
|
225
|
+
id: message1Id,
|
|
226
|
+
created: '2025-01-01T00:00:00Z',
|
|
227
|
+
sender: { role: 'assistant' },
|
|
228
|
+
blocks: [
|
|
229
|
+
{
|
|
230
|
+
_tag: 'text',
|
|
231
|
+
text: 'I will help you with that.',
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
_tag: 'toolCall',
|
|
235
|
+
toolCallId,
|
|
236
|
+
name: 'test_tool',
|
|
237
|
+
input: '{"param": "value"}',
|
|
238
|
+
providerExecuted: false,
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
properties: {},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// User message with tool result
|
|
245
|
+
const toolResultMessage = Obj.make(Message.Message, {
|
|
246
|
+
id: message2Id,
|
|
247
|
+
created: '2025-01-01T00:01:00Z',
|
|
248
|
+
sender: { role: 'user' },
|
|
249
|
+
blocks: [
|
|
250
|
+
{
|
|
251
|
+
_tag: 'toolResult',
|
|
252
|
+
toolCallId,
|
|
253
|
+
name: 'test_tool',
|
|
254
|
+
result: '{"result": "success"}',
|
|
255
|
+
providerExecuted: false,
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
properties: {},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// AgentStatus event
|
|
262
|
+
const agentStatus = Obj.make(AgentStatus, {
|
|
263
|
+
id: statusId,
|
|
264
|
+
created: '2025-01-01T00:02:00Z',
|
|
265
|
+
parentMessage: message1Id,
|
|
266
|
+
toolCallId,
|
|
267
|
+
message: 'Processing tool call...',
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
graph.addEvents([toolCallMessage, toolResultMessage, agentStatus]);
|
|
271
|
+
const result = graph.getGraph();
|
|
272
|
+
|
|
273
|
+
expect(result.commits).toHaveLength(4);
|
|
274
|
+
|
|
275
|
+
// Text block
|
|
276
|
+
expect(result.commits[0]).toMatchObject({
|
|
277
|
+
id: `${message1Id}_block_0`,
|
|
278
|
+
parents: [],
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Tool call block
|
|
282
|
+
expect(result.commits[1]).toMatchObject({
|
|
283
|
+
id: `${message1Id}_toolCall_${toolCallId}`,
|
|
284
|
+
parents: [`${message1Id}_block_0`],
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
// Tool result should have two parents: AgentStatus and tool call
|
|
288
|
+
expect(result.commits[2]).toMatchObject({
|
|
289
|
+
id: `${message2Id}_toolResult_${toolCallId}`,
|
|
290
|
+
parents: [statusId, `${message1Id}_toolCall_${toolCallId}`],
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// AgentStatus
|
|
294
|
+
expect(result.commits[3]).toMatchObject({
|
|
295
|
+
id: statusId,
|
|
296
|
+
parents: [`${message1Id}_toolCall_${toolCallId}`],
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should handle tool errors with proper parent relationships', () => {
|
|
301
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
302
|
+
|
|
303
|
+
const message1Id = createTestId();
|
|
304
|
+
const message2Id = createTestId();
|
|
305
|
+
const statusId = createTestId();
|
|
306
|
+
const toolCallId = 'tool1';
|
|
307
|
+
|
|
308
|
+
// Assistant message with tool call
|
|
309
|
+
const toolCallMessage = Obj.make(Message.Message, {
|
|
310
|
+
id: message1Id,
|
|
311
|
+
created: '2025-01-01T00:00:00Z',
|
|
312
|
+
sender: { role: 'assistant' },
|
|
313
|
+
blocks: [
|
|
314
|
+
{
|
|
315
|
+
_tag: 'toolCall',
|
|
316
|
+
toolCallId,
|
|
317
|
+
name: 'test_tool',
|
|
318
|
+
input: '{"param": "value"}',
|
|
319
|
+
providerExecuted: false,
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
properties: {},
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// User message with tool error
|
|
326
|
+
const toolErrorMessage = Obj.make(Message.Message, {
|
|
327
|
+
id: message2Id,
|
|
328
|
+
created: '2025-01-01T00:01:00Z',
|
|
329
|
+
sender: { role: 'user' },
|
|
330
|
+
blocks: [
|
|
331
|
+
{
|
|
332
|
+
_tag: 'toolResult',
|
|
333
|
+
toolCallId,
|
|
334
|
+
name: 'test_tool',
|
|
335
|
+
error: 'Tool execution failed',
|
|
336
|
+
providerExecuted: false,
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
properties: {},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// AgentStatus event
|
|
343
|
+
const agentStatus = Obj.make(AgentStatus, {
|
|
344
|
+
id: statusId,
|
|
345
|
+
created: '2025-01-01T00:02:00Z',
|
|
346
|
+
parentMessage: message1Id,
|
|
347
|
+
toolCallId,
|
|
348
|
+
message: 'Tool execution failed',
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
graph.addEvents([toolCallMessage, toolErrorMessage, agentStatus]);
|
|
352
|
+
const result = graph.getGraph();
|
|
353
|
+
|
|
354
|
+
expect(result.commits).toHaveLength(3);
|
|
355
|
+
|
|
356
|
+
// Tool call block
|
|
357
|
+
expect(result.commits[0]).toMatchObject({
|
|
358
|
+
id: `${message1Id}_toolCall_${toolCallId}`,
|
|
359
|
+
parents: [],
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Tool error should have two parents: AgentStatus and tool call
|
|
363
|
+
expect(result.commits[1]).toMatchObject({
|
|
364
|
+
id: `${message2Id}_toolResult_${toolCallId}`,
|
|
365
|
+
parents: [statusId, `${message1Id}_toolCall_${toolCallId}`],
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// AgentStatus
|
|
369
|
+
expect(result.commits[2]).toMatchObject({
|
|
370
|
+
id: statusId,
|
|
371
|
+
parents: [`${message1Id}_toolCall_${toolCallId}`],
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
describe('different processing orders', () => {
|
|
377
|
+
it('should handle AgentStatus processed after tool result', () => {
|
|
378
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
379
|
+
|
|
380
|
+
const message1Id = createTestId();
|
|
381
|
+
const message2Id = createTestId();
|
|
382
|
+
const statusId = createTestId();
|
|
383
|
+
const toolCallId = 'tool1';
|
|
384
|
+
|
|
385
|
+
// Tool call message
|
|
386
|
+
const toolCallMessage = Obj.make(Message.Message, {
|
|
387
|
+
id: message1Id,
|
|
388
|
+
created: '2025-01-01T00:00:00Z',
|
|
389
|
+
sender: { role: 'assistant' },
|
|
390
|
+
blocks: [
|
|
391
|
+
{
|
|
392
|
+
_tag: 'toolCall',
|
|
393
|
+
toolCallId,
|
|
394
|
+
name: 'test_tool',
|
|
395
|
+
input: '{}',
|
|
396
|
+
providerExecuted: false,
|
|
397
|
+
},
|
|
398
|
+
],
|
|
399
|
+
properties: {},
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// Tool result message
|
|
403
|
+
const toolResultMessage = Obj.make(Message.Message, {
|
|
404
|
+
id: message2Id,
|
|
405
|
+
created: '2025-01-01T00:01:00Z',
|
|
406
|
+
sender: { role: 'user' },
|
|
407
|
+
blocks: [
|
|
408
|
+
{
|
|
409
|
+
_tag: 'toolResult',
|
|
410
|
+
toolCallId,
|
|
411
|
+
name: 'test_tool',
|
|
412
|
+
result: '{"result": "success"}',
|
|
413
|
+
providerExecuted: false,
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
properties: {},
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// AgentStatus event (processed after tool result)
|
|
420
|
+
const agentStatus = Obj.make(AgentStatus, {
|
|
421
|
+
id: statusId,
|
|
422
|
+
created: '2025-01-01T00:00:00Z',
|
|
423
|
+
parentMessage: message1Id,
|
|
424
|
+
toolCallId,
|
|
425
|
+
message: 'Processing...',
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
graph.addEvents([toolCallMessage, toolResultMessage, agentStatus]);
|
|
429
|
+
const result = graph.getGraph();
|
|
430
|
+
|
|
431
|
+
// Tool result should be updated to point to AgentStatus
|
|
432
|
+
const toolResult = result.commits.find((c) => c.id === `${message2Id}_toolResult_${toolCallId}`);
|
|
433
|
+
expect(toolResult?.parents).toContain(statusId);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('should handle AgentStatus processed before tool result', () => {
|
|
437
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
438
|
+
|
|
439
|
+
const message1Id = createTestId();
|
|
440
|
+
const message2Id = createTestId();
|
|
441
|
+
const statusId = createTestId();
|
|
442
|
+
const toolCallId = 'tool1';
|
|
443
|
+
|
|
444
|
+
// Tool call message
|
|
445
|
+
const toolCallMessage = Obj.make(Message.Message, {
|
|
446
|
+
id: message1Id,
|
|
447
|
+
created: '2025-01-01T00:00:00Z',
|
|
448
|
+
sender: { role: 'assistant' },
|
|
449
|
+
blocks: [
|
|
450
|
+
{
|
|
451
|
+
_tag: 'toolCall',
|
|
452
|
+
toolCallId,
|
|
453
|
+
name: 'test_tool',
|
|
454
|
+
input: '{}',
|
|
455
|
+
providerExecuted: false,
|
|
456
|
+
},
|
|
457
|
+
],
|
|
458
|
+
properties: {},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// AgentStatus event (processed before tool result)
|
|
462
|
+
const agentStatus = Obj.make(AgentStatus, {
|
|
463
|
+
id: statusId,
|
|
464
|
+
created: '2025-01-01T00:00:00Z',
|
|
465
|
+
parentMessage: message1Id,
|
|
466
|
+
toolCallId,
|
|
467
|
+
message: 'Processing...',
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// Tool result message
|
|
471
|
+
const toolResultMessage = Obj.make(Message.Message, {
|
|
472
|
+
id: message2Id,
|
|
473
|
+
created: '2025-01-01T00:01:00Z',
|
|
474
|
+
sender: { role: 'user' },
|
|
475
|
+
blocks: [
|
|
476
|
+
{
|
|
477
|
+
_tag: 'toolResult',
|
|
478
|
+
toolCallId,
|
|
479
|
+
name: 'test_tool',
|
|
480
|
+
result: '{"result": "success"}',
|
|
481
|
+
providerExecuted: false,
|
|
482
|
+
},
|
|
483
|
+
],
|
|
484
|
+
properties: {},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
graph.addEvents([toolCallMessage, agentStatus, toolResultMessage]);
|
|
488
|
+
const result = graph.getGraph();
|
|
489
|
+
|
|
490
|
+
// Tool result should point to AgentStatus
|
|
491
|
+
const toolResult = result.commits.find((c) => c.id === `${message2Id}_toolResult_${toolCallId}`);
|
|
492
|
+
expect(toolResult?.parents).toContain(statusId);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
describe('complex scenarios', () => {
|
|
497
|
+
it('should handle multiple tool calls in sequence', () => {
|
|
498
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
499
|
+
|
|
500
|
+
const msg1Id = createTestId();
|
|
501
|
+
const msg2Id = createTestId();
|
|
502
|
+
const msg3Id = createTestId();
|
|
503
|
+
const msg4Id = createTestId();
|
|
504
|
+
const msg5Id = createTestId();
|
|
505
|
+
const status1Id = createTestId();
|
|
506
|
+
const status2Id = createTestId();
|
|
507
|
+
|
|
508
|
+
const events = [
|
|
509
|
+
// User message
|
|
510
|
+
Obj.make(Message.Message, {
|
|
511
|
+
id: msg1Id,
|
|
512
|
+
created: '2025-01-01T00:00:00Z',
|
|
513
|
+
sender: { role: 'user' },
|
|
514
|
+
blocks: [{ _tag: 'text', text: 'Help me with two tasks' }],
|
|
515
|
+
properties: {},
|
|
516
|
+
}),
|
|
517
|
+
|
|
518
|
+
// Assistant with first tool call
|
|
519
|
+
Obj.make(Message.Message, {
|
|
520
|
+
id: msg2Id,
|
|
521
|
+
created: '2025-01-01T00:01:00Z',
|
|
522
|
+
sender: { role: 'assistant' },
|
|
523
|
+
blocks: [
|
|
524
|
+
{ _tag: 'text', text: 'I will help with both tasks' },
|
|
525
|
+
{ _tag: 'toolCall', toolCallId: 'tool1', name: 'task1', input: '{}', providerExecuted: false },
|
|
526
|
+
],
|
|
527
|
+
properties: {},
|
|
528
|
+
}),
|
|
529
|
+
|
|
530
|
+
// First tool result
|
|
531
|
+
Obj.make(Message.Message, {
|
|
532
|
+
id: msg3Id,
|
|
533
|
+
created: '2025-01-01T00:02:00Z',
|
|
534
|
+
sender: { role: 'user' },
|
|
535
|
+
blocks: [
|
|
536
|
+
{
|
|
537
|
+
_tag: 'toolResult',
|
|
538
|
+
toolCallId: 'tool1',
|
|
539
|
+
name: 'task1',
|
|
540
|
+
result: '{"done": true}',
|
|
541
|
+
providerExecuted: false,
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
properties: {},
|
|
545
|
+
}),
|
|
546
|
+
|
|
547
|
+
// Assistant with second tool call
|
|
548
|
+
Obj.make(Message.Message, {
|
|
549
|
+
id: msg4Id,
|
|
550
|
+
created: '2025-01-01T00:03:00Z',
|
|
551
|
+
sender: { role: 'assistant' },
|
|
552
|
+
blocks: [
|
|
553
|
+
{ _tag: 'text', text: 'Now for the second task' },
|
|
554
|
+
{ _tag: 'toolCall', toolCallId: 'tool2', name: 'task2', input: '{}', providerExecuted: false },
|
|
555
|
+
],
|
|
556
|
+
properties: {},
|
|
557
|
+
}),
|
|
558
|
+
|
|
559
|
+
// Second tool result
|
|
560
|
+
Obj.make(Message.Message, {
|
|
561
|
+
id: msg5Id,
|
|
562
|
+
created: '2025-01-01T00:04:00Z',
|
|
563
|
+
sender: { role: 'user' },
|
|
564
|
+
blocks: [
|
|
565
|
+
{
|
|
566
|
+
_tag: 'toolResult',
|
|
567
|
+
toolCallId: 'tool2',
|
|
568
|
+
name: 'task2',
|
|
569
|
+
result: '{"done": true}',
|
|
570
|
+
providerExecuted: false,
|
|
571
|
+
},
|
|
572
|
+
],
|
|
573
|
+
properties: {},
|
|
574
|
+
}),
|
|
575
|
+
|
|
576
|
+
// AgentStatus events
|
|
577
|
+
Obj.make(AgentStatus, {
|
|
578
|
+
id: status1Id,
|
|
579
|
+
created: '2025-01-01T00:05:00Z',
|
|
580
|
+
parentMessage: msg2Id,
|
|
581
|
+
toolCallId: 'tool1',
|
|
582
|
+
message: 'Processing task 1...',
|
|
583
|
+
}),
|
|
584
|
+
|
|
585
|
+
Obj.make(AgentStatus, {
|
|
586
|
+
id: status2Id,
|
|
587
|
+
created: '2025-01-01T00:06:00Z',
|
|
588
|
+
parentMessage: msg4Id,
|
|
589
|
+
toolCallId: 'tool2',
|
|
590
|
+
message: 'Processing task 2...',
|
|
591
|
+
}),
|
|
592
|
+
];
|
|
593
|
+
|
|
594
|
+
graph.addEvents(events);
|
|
595
|
+
const result = graph.getGraph();
|
|
596
|
+
|
|
597
|
+
expect(result.commits).toHaveLength(9);
|
|
598
|
+
|
|
599
|
+
// Check sequential chaining
|
|
600
|
+
expect(result.commits[0].parents).toEqual([]); // msg1_block_0
|
|
601
|
+
expect(result.commits[1].parents).toEqual([`${msg1Id}_block_0`]); // msg2_block_0
|
|
602
|
+
expect(result.commits[2].parents).toEqual([`${msg2Id}_block_0`]); // msg2_toolCall_tool1
|
|
603
|
+
expect(result.commits[3].parents).toEqual([status1Id, `${msg2Id}_toolCall_tool1`]); // msg3_toolResult_tool1
|
|
604
|
+
expect(result.commits[4].parents).toEqual([`${msg3Id}_toolResult_tool1`]); // msg4_block_0
|
|
605
|
+
expect(result.commits[5].parents).toEqual([`${msg4Id}_block_0`]); // msg4_toolCall_tool2
|
|
606
|
+
expect(result.commits[6].parents).toEqual([status2Id, `${msg4Id}_toolCall_tool2`]); // msg5_toolResult_tool2
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it('should handle mixed block types in a message', () => {
|
|
610
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
611
|
+
|
|
612
|
+
const messageId = createTestId();
|
|
613
|
+
const message = Obj.make(Message.Message, {
|
|
614
|
+
id: messageId,
|
|
615
|
+
created: '2025-01-01T00:00:00Z',
|
|
616
|
+
sender: { role: 'assistant' },
|
|
617
|
+
blocks: [
|
|
618
|
+
{ _tag: 'text', text: 'Let me help you' },
|
|
619
|
+
{ _tag: 'reasoning', reasoningText: 'I need to think about this' },
|
|
620
|
+
{ _tag: 'toolCall', toolCallId: 'tool1', name: 'analyze', input: '{}', providerExecuted: false },
|
|
621
|
+
{
|
|
622
|
+
_tag: 'stats',
|
|
623
|
+
message: 'OK',
|
|
624
|
+
duration: 1000,
|
|
625
|
+
toolCalls: 1,
|
|
626
|
+
usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 },
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
properties: {},
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
graph.addEvents([message]);
|
|
633
|
+
const result = graph.getGraph();
|
|
634
|
+
|
|
635
|
+
expect(result.commits).toHaveLength(4);
|
|
636
|
+
|
|
637
|
+
// All blocks should be chained sequentially
|
|
638
|
+
expect(result.commits[0].parents).toEqual([]); // text
|
|
639
|
+
expect(result.commits[1].parents).toEqual([`${messageId}_block_0`]); // reasoning
|
|
640
|
+
expect(result.commits[2].parents).toEqual([`${messageId}_block_1`]); // toolCall
|
|
641
|
+
expect(result.commits[3].parents).toEqual([`${messageId}_toolCall_tool1`]); // summary
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
describe('edge cases', () => {
|
|
646
|
+
it('should handle empty text blocks', () => {
|
|
647
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
648
|
+
|
|
649
|
+
const messageId = createTestId();
|
|
650
|
+
const message = Obj.make(Message.Message, {
|
|
651
|
+
id: messageId,
|
|
652
|
+
created: '2025-01-01T00:00:00Z',
|
|
653
|
+
sender: { role: 'assistant' },
|
|
654
|
+
blocks: [
|
|
655
|
+
{ _tag: 'text', text: 'Valid text' },
|
|
656
|
+
{ _tag: 'text', text: '' }, // Empty text should be filtered out
|
|
657
|
+
{ _tag: 'text', text: 'More valid text' },
|
|
658
|
+
],
|
|
659
|
+
properties: {},
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
graph.addEvents([message]);
|
|
663
|
+
const result = graph.getGraph();
|
|
664
|
+
|
|
665
|
+
expect(result.commits).toHaveLength(2); // Empty block should be filtered out
|
|
666
|
+
expect(result.commits[0].parents).toEqual([]); // First text block
|
|
667
|
+
expect(result.commits[1].parents).toEqual([`${messageId}_block_0`]); // Third text block
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
it('should handle messages with no blocks', () => {
|
|
671
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
672
|
+
|
|
673
|
+
const messageId = createTestId();
|
|
674
|
+
const message = Obj.make(Message.Message, {
|
|
675
|
+
id: messageId,
|
|
676
|
+
created: '2025-01-01T00:00:00Z',
|
|
677
|
+
sender: { role: 'assistant' },
|
|
678
|
+
blocks: [],
|
|
679
|
+
properties: {},
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
graph.addEvents([message]);
|
|
683
|
+
const result = graph.getGraph();
|
|
684
|
+
|
|
685
|
+
expect(result.commits).toHaveLength(0);
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
it('should handle getGraph with lastRequest filter', () => {
|
|
689
|
+
const graph = new ExecutionGraph(SKIP_BLOCKS);
|
|
690
|
+
|
|
691
|
+
const msg1Id = createTestId();
|
|
692
|
+
const msg2Id = createTestId();
|
|
693
|
+
const msg3Id = createTestId();
|
|
694
|
+
const msg4Id = createTestId();
|
|
695
|
+
|
|
696
|
+
const events = [
|
|
697
|
+
Obj.make(Message.Message, {
|
|
698
|
+
id: msg1Id,
|
|
699
|
+
created: '2025-01-01T00:00:00Z',
|
|
700
|
+
sender: { role: 'user' },
|
|
701
|
+
blocks: [{ _tag: 'text', text: 'First request' }],
|
|
702
|
+
properties: {},
|
|
703
|
+
}),
|
|
704
|
+
Obj.make(Message.Message, {
|
|
705
|
+
id: msg2Id,
|
|
706
|
+
created: '2025-01-01T00:01:00Z',
|
|
707
|
+
sender: { role: 'assistant' },
|
|
708
|
+
blocks: [{ _tag: 'text', text: 'Response 1' }],
|
|
709
|
+
properties: {},
|
|
710
|
+
}),
|
|
711
|
+
Obj.make(Message.Message, {
|
|
712
|
+
id: msg3Id,
|
|
713
|
+
created: '2025-01-01T00:02:00Z',
|
|
714
|
+
sender: { role: 'user' },
|
|
715
|
+
blocks: [{ _tag: 'text', text: 'Second request' }],
|
|
716
|
+
properties: {},
|
|
717
|
+
}),
|
|
718
|
+
Obj.make(Message.Message, {
|
|
719
|
+
id: msg4Id,
|
|
720
|
+
created: '2025-01-01T00:03:00Z',
|
|
721
|
+
sender: { role: 'assistant' },
|
|
722
|
+
blocks: [{ _tag: 'text', text: 'Response 2' }],
|
|
723
|
+
properties: {},
|
|
724
|
+
}),
|
|
725
|
+
];
|
|
726
|
+
|
|
727
|
+
graph.addEvents(events);
|
|
728
|
+
|
|
729
|
+
// Get all commits
|
|
730
|
+
const allCommits = graph.getGraph();
|
|
731
|
+
expect(allCommits.commits).toHaveLength(4);
|
|
732
|
+
|
|
733
|
+
// Get commits from last user request
|
|
734
|
+
const lastRequestCommits = graph.getGraph(true);
|
|
735
|
+
expect(lastRequestCommits.commits).toHaveLength(2); // Only msg3 and msg4
|
|
736
|
+
expect(lastRequestCommits.commits[0].id).toBe(`${msg3Id}_block_0`);
|
|
737
|
+
expect(lastRequestCommits.commits[1].id).toBe(`${msg4Id}_block_0`);
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
});
|