@haklex/rich-agent-core 0.1.1 → 0.3.0
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/dist/index.mjs +1453 -1389
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -1,294 +1,354 @@
|
|
|
1
|
-
var __typeError = (msg) => {
|
|
2
|
-
throw TypeError(msg);
|
|
3
|
-
};
|
|
4
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
-
var _get, _set;
|
|
9
1
|
import { createDefaultRegistry, deserializeNodesFromXml, serializeToXml } from "@haklex/rich-litexml";
|
|
10
2
|
import { nanoid } from "nanoid";
|
|
11
3
|
import { createStore } from "zustand/vanilla";
|
|
4
|
+
//#region src/document-tools.ts
|
|
12
5
|
function extractText(node) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
const n = node;
|
|
7
|
+
if (n.text) return n.text;
|
|
8
|
+
if (n.children) return n.children.map(extractText).join("");
|
|
9
|
+
return "";
|
|
17
10
|
}
|
|
18
11
|
function createDocumentTools(snapshot, operations) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
12
|
+
const registry = createDefaultRegistry();
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
name: "insert_node",
|
|
16
|
+
description: "Insert one or more block nodes at a position relative to an existing block. The xml parameter should contain XML elements like <p>, <h2>, <ul>, <codeblock>, <img />, etc.",
|
|
17
|
+
parameters: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
position: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
type: {
|
|
24
|
+
type: "string",
|
|
25
|
+
enum: [
|
|
26
|
+
"after",
|
|
27
|
+
"before",
|
|
28
|
+
"root"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
blockId: { type: "string" },
|
|
32
|
+
index: { type: "number" }
|
|
33
|
+
},
|
|
34
|
+
required: ["type"]
|
|
35
|
+
},
|
|
36
|
+
xml: {
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "XML string containing block elements to insert"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
required: ["position", "xml"]
|
|
42
|
+
},
|
|
43
|
+
describeCall: (params) => {
|
|
44
|
+
const pos = params.position;
|
|
45
|
+
return pos?.blockId ? `inserting ${pos.type} block "${pos.blockId}"` : "inserting node";
|
|
46
|
+
},
|
|
47
|
+
execute: async (params) => {
|
|
48
|
+
const { position, xml } = params;
|
|
49
|
+
if (!xml || typeof xml !== "string") return {
|
|
50
|
+
ok: false,
|
|
51
|
+
error: {
|
|
52
|
+
error: "invalid_xml",
|
|
53
|
+
message: "Missing or invalid \"xml\" parameter. Must be an XML string."
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
if (position.type !== "root" && !snapshot.getBlock(position.blockId)) return {
|
|
57
|
+
ok: false,
|
|
58
|
+
error: {
|
|
59
|
+
error: "block_not_found",
|
|
60
|
+
blockId: position.blockId,
|
|
61
|
+
message: `Block "${position.blockId}" not found.`
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
let nodes;
|
|
65
|
+
try {
|
|
66
|
+
nodes = deserializeNodesFromXml(xml, registry);
|
|
67
|
+
} catch {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
error: {
|
|
71
|
+
error: "xml_parse_error",
|
|
72
|
+
message: "Failed to parse XML string."
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (nodes.length === 0) return {
|
|
77
|
+
ok: false,
|
|
78
|
+
error: {
|
|
79
|
+
error: "empty_xml",
|
|
80
|
+
message: "XML produced no nodes."
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
84
|
+
const pos = i === 0 ? position : {
|
|
85
|
+
...position,
|
|
86
|
+
_insertIndex: i
|
|
87
|
+
};
|
|
88
|
+
operations.push({
|
|
89
|
+
op: "insert",
|
|
90
|
+
position: pos,
|
|
91
|
+
node: nodes[i]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
ok: true,
|
|
96
|
+
content: `Inserted ${nodes.length} node(s) ${position.type} block "${position.blockId ?? "root"}"`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "replace_node",
|
|
102
|
+
description: "Replace an existing block node by its blockId with new XML content. The xml should contain exactly one block element.",
|
|
103
|
+
parameters: {
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: {
|
|
106
|
+
blockId: { type: "string" },
|
|
107
|
+
xml: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "XML string containing one block element"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
required: ["blockId", "xml"]
|
|
113
|
+
},
|
|
114
|
+
describeCall: (params) => {
|
|
115
|
+
const p = params;
|
|
116
|
+
return p.blockId ? `replacing block "${p.blockId}"` : "replacing node";
|
|
117
|
+
},
|
|
118
|
+
execute: async (params) => {
|
|
119
|
+
const { blockId, xml } = params;
|
|
120
|
+
if (!xml || typeof xml !== "string") return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: {
|
|
123
|
+
error: "invalid_xml",
|
|
124
|
+
message: "Missing or invalid \"xml\" parameter."
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
if (!snapshot.getBlock(blockId)) return {
|
|
128
|
+
ok: false,
|
|
129
|
+
error: {
|
|
130
|
+
error: "block_not_found",
|
|
131
|
+
blockId,
|
|
132
|
+
message: `Block "${blockId}" not found.`
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
let nodes;
|
|
136
|
+
try {
|
|
137
|
+
nodes = deserializeNodesFromXml(xml, registry);
|
|
138
|
+
} catch {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
error: {
|
|
142
|
+
error: "xml_parse_error",
|
|
143
|
+
message: "Failed to parse XML string."
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (nodes.length === 0) return {
|
|
148
|
+
ok: false,
|
|
149
|
+
error: {
|
|
150
|
+
error: "empty_xml",
|
|
151
|
+
message: "XML produced no nodes."
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const primaryNode = {
|
|
155
|
+
...nodes[0],
|
|
156
|
+
$: {
|
|
157
|
+
...nodes[0].$,
|
|
158
|
+
blockId
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
operations.push({
|
|
162
|
+
op: "replace",
|
|
163
|
+
blockId,
|
|
164
|
+
node: primaryNode
|
|
165
|
+
});
|
|
166
|
+
for (let i = 1; i < nodes.length; i++) operations.push({
|
|
167
|
+
op: "insert",
|
|
168
|
+
position: {
|
|
169
|
+
type: "after",
|
|
170
|
+
blockId
|
|
171
|
+
},
|
|
172
|
+
node: nodes[i]
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
ok: true,
|
|
176
|
+
content: `Replaced block "${blockId}" (${nodes.length} node(s))`
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "delete_node",
|
|
182
|
+
description: "Delete an existing block node by its blockId",
|
|
183
|
+
parameters: {
|
|
184
|
+
type: "object",
|
|
185
|
+
properties: { blockId: { type: "string" } },
|
|
186
|
+
required: ["blockId"]
|
|
187
|
+
},
|
|
188
|
+
describeCall: (params) => {
|
|
189
|
+
const p = params;
|
|
190
|
+
return p.blockId ? `deleting block "${p.blockId}"` : "deleting node";
|
|
191
|
+
},
|
|
192
|
+
execute: async (params) => {
|
|
193
|
+
const { blockId } = params;
|
|
194
|
+
if (!snapshot.getBlock(blockId)) return {
|
|
195
|
+
ok: false,
|
|
196
|
+
error: {
|
|
197
|
+
error: "block_not_found",
|
|
198
|
+
blockId,
|
|
199
|
+
message: `Block "${blockId}" not found.`
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
operations.push({
|
|
203
|
+
op: "delete",
|
|
204
|
+
blockId
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
ok: true,
|
|
208
|
+
content: `Deleted block "${blockId}"`
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "search_document",
|
|
214
|
+
description: "Search for blocks in the document by text content or block type",
|
|
215
|
+
parameters: {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
query: { type: "string" },
|
|
219
|
+
blockType: { type: "string" }
|
|
220
|
+
},
|
|
221
|
+
required: ["query"]
|
|
222
|
+
},
|
|
223
|
+
describeCall: (params) => {
|
|
224
|
+
const p = params;
|
|
225
|
+
const parts = [];
|
|
226
|
+
if (p.query) parts.push(`"${p.query}"`);
|
|
227
|
+
if (p.blockType) parts.push(`type=${p.blockType}`);
|
|
228
|
+
return `searching ${parts.join(", ") || "document"}`;
|
|
229
|
+
},
|
|
230
|
+
execute: async (params) => {
|
|
231
|
+
const { query, blockType } = params;
|
|
232
|
+
const matches = [];
|
|
233
|
+
for (const blockId of snapshot.blockIds) {
|
|
234
|
+
const block = snapshot.getBlock(blockId);
|
|
235
|
+
const nodeType = block.type ?? "unknown";
|
|
236
|
+
if (blockType && nodeType !== blockType) continue;
|
|
237
|
+
const text = extractText(block);
|
|
238
|
+
if (query && !text.toLowerCase().includes(query.toLowerCase())) continue;
|
|
239
|
+
matches.push({
|
|
240
|
+
blockId,
|
|
241
|
+
nodeType,
|
|
242
|
+
textContent: text
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
ok: true,
|
|
247
|
+
content: JSON.stringify(matches)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/messages-engine/helpers.ts
|
|
195
255
|
function appendText(base, next) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
${next}`;
|
|
256
|
+
if (!next) return base;
|
|
257
|
+
if (!base) return next;
|
|
258
|
+
return `${base}\n\n${next}`;
|
|
201
259
|
}
|
|
202
260
|
function normalizeMessageList(value) {
|
|
203
|
-
|
|
204
|
-
|
|
261
|
+
if (!value) return [];
|
|
262
|
+
return Array.isArray(value) ? value : [value];
|
|
205
263
|
}
|
|
206
264
|
function getLastItem(items) {
|
|
207
|
-
|
|
265
|
+
return items.length > 0 ? items[items.length - 1] : void 0;
|
|
208
266
|
}
|
|
209
267
|
function createInitialDraft(context) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
268
|
+
return {
|
|
269
|
+
systemMessages: [],
|
|
270
|
+
messages: [...context.messages]
|
|
271
|
+
};
|
|
214
272
|
}
|
|
215
273
|
function draftToPreparedMessages(draft) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
}
|
|
274
|
+
return {
|
|
275
|
+
systemMessages: draft.systemMessages,
|
|
276
|
+
preambleMessages: draft.messages,
|
|
277
|
+
turns: []
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/messages-engine/engine.ts
|
|
282
|
+
var MessagesEngine = class {
|
|
283
|
+
constructor(processors) {
|
|
284
|
+
this.processors = processors;
|
|
285
|
+
}
|
|
286
|
+
process(context) {
|
|
287
|
+
return draftToPreparedMessages(this.processors.reduce((nextDraft, processor) => processor.process(nextDraft, context), createInitialDraft(context)));
|
|
288
|
+
}
|
|
289
|
+
};
|
|
234
290
|
function buildMessages(preparedMessages) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
291
|
+
return [
|
|
292
|
+
...preparedMessages.systemMessages,
|
|
293
|
+
...preparedMessages.preambleMessages,
|
|
294
|
+
...preparedMessages.turns
|
|
295
|
+
];
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/messages-engine/base/BaseMessageEngineProcessor.ts
|
|
299
|
+
var BaseMessageEngineProcessor = class {
|
|
300
|
+
process(draft, context) {
|
|
301
|
+
if (!this.shouldProcess(context, draft)) return draft;
|
|
302
|
+
return this.doProcess(this.cloneDraft(draft), context);
|
|
303
|
+
}
|
|
304
|
+
shouldProcess(_context, _draft) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
cloneDraft(draft) {
|
|
308
|
+
return {
|
|
309
|
+
systemMessages: [...draft.systemMessages],
|
|
310
|
+
messages: draft.messages.map((message) => message.role === "user" || message.role === "system" || message.role === "assistant" ? { ...message } : message.role === "assistant_tool_call" ? {
|
|
311
|
+
...message,
|
|
312
|
+
toolCalls: [...message.toolCalls]
|
|
313
|
+
} : { ...message })
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/messages-engine/base/constants.ts
|
|
319
|
+
var SYSTEM_CONTEXT_START = "<!-- SYSTEM CONTEXT (NOT PART OF USER QUERY) -->";
|
|
320
|
+
var SYSTEM_CONTEXT_END = "<!-- END SYSTEM CONTEXT -->";
|
|
321
|
+
var CONTEXT_INSTRUCTION = `<context.instruction>following part contains context information injected by the system. Please follow these instructions:
|
|
263
322
|
|
|
264
323
|
1. Always prioritize handling user-visible content.
|
|
265
324
|
2. the context is only required when user's queries rely on it.
|
|
266
325
|
</context.instruction>`;
|
|
326
|
+
//#endregion
|
|
327
|
+
//#region src/messages-engine/base/messageContextUtils.ts
|
|
267
328
|
function getUserMessageLocations(draft) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return locations;
|
|
329
|
+
const locations = [];
|
|
330
|
+
for (let i = 0; i < draft.messages.length; i++) if (draft.messages[i].role === "user") locations.push({
|
|
331
|
+
scope: "messages",
|
|
332
|
+
index: i
|
|
333
|
+
});
|
|
334
|
+
return locations;
|
|
275
335
|
}
|
|
276
336
|
function getUserMessage(draft, location) {
|
|
277
|
-
|
|
337
|
+
return draft.messages[location.index];
|
|
278
338
|
}
|
|
279
339
|
function setUserMessage(draft, location, message) {
|
|
280
|
-
|
|
340
|
+
draft.messages[location.index] = message;
|
|
281
341
|
}
|
|
282
342
|
function hasSystemContextWrapper(content) {
|
|
283
|
-
|
|
343
|
+
return content.includes("<!-- SYSTEM CONTEXT (NOT PART OF USER QUERY) -->") && content.includes("<!-- END SYSTEM CONTEXT -->");
|
|
284
344
|
}
|
|
285
345
|
function createContextBlock(content, contextType) {
|
|
286
|
-
|
|
346
|
+
return `<${contextType}>
|
|
287
347
|
${content}
|
|
288
348
|
</${contextType}>`;
|
|
289
349
|
}
|
|
290
350
|
function wrapWithSystemContext(content, contextType) {
|
|
291
|
-
|
|
351
|
+
return `${SYSTEM_CONTEXT_START}
|
|
292
352
|
${CONTEXT_INSTRUCTION}
|
|
293
353
|
<${contextType}>
|
|
294
354
|
${content}
|
|
@@ -296,1238 +356,1242 @@ ${content}
|
|
|
296
356
|
${SYSTEM_CONTEXT_END}`;
|
|
297
357
|
}
|
|
298
358
|
function insertIntoExistingWrapper(existingContent, newContextBlock) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
const beforeEnd = existingContent.slice(0, endMarkerIndex);
|
|
304
|
-
const afterEnd = existingContent.slice(endMarkerIndex);
|
|
305
|
-
return `${beforeEnd}${newContextBlock}
|
|
306
|
-
${afterEnd}`;
|
|
359
|
+
const endMarkerIndex = existingContent.lastIndexOf(SYSTEM_CONTEXT_END);
|
|
360
|
+
if (endMarkerIndex === -1) return appendText(existingContent, newContextBlock);
|
|
361
|
+
return `${existingContent.slice(0, endMarkerIndex)}${newContextBlock}\n${existingContent.slice(endMarkerIndex)}`;
|
|
307
362
|
}
|
|
308
363
|
function appendSystemContextToUserMessage(message, content, contextType) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
364
|
+
const currentContent = message.content;
|
|
365
|
+
if (hasSystemContextWrapper(currentContent)) return {
|
|
366
|
+
...message,
|
|
367
|
+
content: insertIntoExistingWrapper(currentContent, createContextBlock(content, contextType))
|
|
368
|
+
};
|
|
369
|
+
return {
|
|
370
|
+
...message,
|
|
371
|
+
content: appendText(currentContent, wrapWithSystemContext(content, contextType))
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/messages-engine/base/BaseEveryUserContentProvider.ts
|
|
376
|
+
var BaseEveryUserContentProvider = class extends BaseMessageEngineProcessor {
|
|
377
|
+
doProcess(draft, context) {
|
|
378
|
+
const locations = getUserMessageLocations(draft);
|
|
379
|
+
const lastIndex = locations.length - 1;
|
|
380
|
+
for (let i = 0; i < locations.length; i++) {
|
|
381
|
+
const location = locations[i];
|
|
382
|
+
const message = getUserMessage(draft, location);
|
|
383
|
+
const nextContent = this.buildContentForMessage(message, i, i === lastIndex, context);
|
|
384
|
+
if (!nextContent) continue;
|
|
385
|
+
setUserMessage(draft, location, appendSystemContextToUserMessage(message, nextContent.content, nextContent.contextType));
|
|
386
|
+
}
|
|
387
|
+
return draft;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/messages-engine/base/BaseFirstUserContentProvider.ts
|
|
392
|
+
var BaseFirstUserContentProvider = class extends BaseMessageEngineProcessor {
|
|
393
|
+
doProcess(draft, context) {
|
|
394
|
+
const messages = this.buildMessages(context);
|
|
395
|
+
if (!messages) return draft;
|
|
396
|
+
const firstUserIndex = draft.messages.findIndex((message) => message.role === "user");
|
|
397
|
+
if (firstUserIndex === -1) return draft;
|
|
398
|
+
draft.messages.splice(firstUserIndex, 0, ...normalizeMessageList(messages));
|
|
399
|
+
return draft;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/messages-engine/base/BaseLastUserContentProvider.ts
|
|
404
|
+
var BaseLastUserContentProvider = class extends BaseMessageEngineProcessor {
|
|
405
|
+
doProcess(draft, context) {
|
|
406
|
+
const lastLocation = getLastItem(getUserMessageLocations(draft));
|
|
407
|
+
if (!lastLocation) return draft;
|
|
408
|
+
const nextContent = this.buildContent(context);
|
|
409
|
+
if (!nextContent) return draft;
|
|
410
|
+
setUserMessage(draft, lastLocation, appendSystemContextToUserMessage(getUserMessage(draft, lastLocation), nextContent.content, nextContent.contextType));
|
|
411
|
+
return draft;
|
|
412
|
+
}
|
|
413
|
+
hasExistingSystemContext(draft) {
|
|
414
|
+
const lastLocation = getLastItem(getUserMessageLocations(draft));
|
|
415
|
+
if (!lastLocation) return false;
|
|
416
|
+
return hasSystemContextWrapper(getUserMessage(draft, lastLocation).content);
|
|
417
|
+
}
|
|
418
|
+
wrapWithSystemContext(content, contextType) {
|
|
419
|
+
return wrapWithSystemContext(content, contextType);
|
|
420
|
+
}
|
|
421
|
+
createContextBlock(content, contextType) {
|
|
422
|
+
return createContextBlock(content, contextType);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region src/messages-engine/base/BaseSystemRoleProvider.ts
|
|
427
|
+
var BaseSystemRoleProvider = class extends BaseMessageEngineProcessor {
|
|
428
|
+
doProcess(draft, context) {
|
|
429
|
+
const content = this.buildContent(context)?.trim();
|
|
430
|
+
if (!content) return draft;
|
|
431
|
+
const lastSystemMessage = getLastItem(draft.systemMessages);
|
|
432
|
+
if (!lastSystemMessage) {
|
|
433
|
+
draft.systemMessages = [{
|
|
434
|
+
role: "system",
|
|
435
|
+
content
|
|
436
|
+
}];
|
|
437
|
+
return draft;
|
|
438
|
+
}
|
|
439
|
+
draft.systemMessages[draft.systemMessages.length - 1] = {
|
|
440
|
+
...lastSystemMessage,
|
|
441
|
+
content: appendText(lastSystemMessage.content, content)
|
|
442
|
+
};
|
|
443
|
+
return draft;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region src/messages-engine/base/BaseSystemRootProvider.ts
|
|
448
|
+
var BaseSystemRootProvider = class extends BaseMessageEngineProcessor {
|
|
449
|
+
doProcess(draft, context) {
|
|
450
|
+
const messages = this.buildMessages(context);
|
|
451
|
+
if (!messages) return draft;
|
|
452
|
+
draft.systemMessages = normalizeMessageList(messages);
|
|
453
|
+
return draft;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
//#endregion
|
|
457
|
+
//#region src/agent-executor.ts
|
|
401
458
|
function describeToolCall(tool, params) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
const firstVal = Object.values(params)[0];
|
|
409
|
-
return firstVal !== void 0 ? String(firstVal).slice(0, 40) : void 0;
|
|
459
|
+
if (tool?.describeCall) try {
|
|
460
|
+
return tool.describeCall(params);
|
|
461
|
+
} catch {}
|
|
462
|
+
const firstVal = Object.values(params)[0];
|
|
463
|
+
return firstVal !== void 0 ? String(firstVal).slice(0, 40) : void 0;
|
|
410
464
|
}
|
|
411
465
|
function splitSteps(text) {
|
|
412
|
-
|
|
466
|
+
return text.split(/\n{2,}/).map((s) => s.trim()).filter(Boolean);
|
|
413
467
|
}
|
|
414
|
-
|
|
468
|
+
var groupCounter = 0;
|
|
415
469
|
function nextGroupId() {
|
|
416
|
-
|
|
470
|
+
return `tcg-${++groupCounter}-${Date.now()}`;
|
|
417
471
|
}
|
|
418
|
-
|
|
472
|
+
var thinkingCounter = 0;
|
|
419
473
|
function nextThinkingId() {
|
|
420
|
-
|
|
474
|
+
return `th-${++thinkingCounter}-${Date.now()}`;
|
|
421
475
|
}
|
|
422
476
|
function toolConfigToSchema(tool) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
477
|
+
return {
|
|
478
|
+
name: tool.name,
|
|
479
|
+
description: tool.description,
|
|
480
|
+
parameters: tool.parameters
|
|
481
|
+
};
|
|
428
482
|
}
|
|
429
483
|
function createAgentExecutor(config) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
484
|
+
const { provider, snapshot, store, signal, onOperationsChanged } = config;
|
|
485
|
+
const operations = [];
|
|
486
|
+
let lastOpsLength = 0;
|
|
487
|
+
const allTools = [...createDocumentTools(snapshot, operations), ...config.tools];
|
|
488
|
+
const toolMap = new Map(allTools.map((t) => [t.name, t]));
|
|
489
|
+
const toolSchemas = allTools.map(toolConfigToSchema);
|
|
490
|
+
async function executeTool(name, args) {
|
|
491
|
+
const tool = toolMap.get(name);
|
|
492
|
+
if (!tool) return {
|
|
493
|
+
ok: false,
|
|
494
|
+
error: {
|
|
495
|
+
error: "unknown_tool",
|
|
496
|
+
message: `Tool "${name}" not found`
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
const params = JSON.parse(args);
|
|
500
|
+
return tool.execute(params);
|
|
501
|
+
}
|
|
502
|
+
async function run(initialMessages) {
|
|
503
|
+
const { addBubble, setStatus, updateLastBubble } = store.getState();
|
|
504
|
+
setStatus("running");
|
|
505
|
+
const turns = [];
|
|
506
|
+
const maxTurns = 20;
|
|
507
|
+
for (let turn = 0; turn < maxTurns; turn++) {
|
|
508
|
+
signal?.throwIfAborted();
|
|
509
|
+
const messages = buildMessages({
|
|
510
|
+
...initialMessages,
|
|
511
|
+
turns
|
|
512
|
+
});
|
|
513
|
+
let textAccum = "";
|
|
514
|
+
let thinkingAccum = "";
|
|
515
|
+
let hasThinking = false;
|
|
516
|
+
let thinkingId = "";
|
|
517
|
+
const toolCalls = [];
|
|
518
|
+
let streamGroupId = null;
|
|
519
|
+
const streamToolTurns = [];
|
|
520
|
+
let assistantBubbleOpen = false;
|
|
521
|
+
const runToolCallMidStream = async (tc) => {
|
|
522
|
+
if (assistantBubbleOpen) {
|
|
523
|
+
updateLastBubble({
|
|
524
|
+
type: "assistant",
|
|
525
|
+
content: textAccum,
|
|
526
|
+
streaming: false
|
|
527
|
+
});
|
|
528
|
+
assistantBubbleOpen = false;
|
|
529
|
+
textAccum = "";
|
|
530
|
+
}
|
|
531
|
+
if (!streamGroupId) {
|
|
532
|
+
streamGroupId = nextGroupId();
|
|
533
|
+
addBubble({
|
|
534
|
+
type: "tool_call_group",
|
|
535
|
+
id: streamGroupId,
|
|
536
|
+
items: []
|
|
537
|
+
});
|
|
538
|
+
setStatus("calling_tool");
|
|
539
|
+
}
|
|
540
|
+
let params;
|
|
541
|
+
let parseError = null;
|
|
542
|
+
try {
|
|
543
|
+
params = JSON.parse(tc.arguments);
|
|
544
|
+
} catch (e) {
|
|
545
|
+
params = {};
|
|
546
|
+
parseError = e.message;
|
|
547
|
+
}
|
|
548
|
+
const { addToolCallItem, updateToolCallItem } = store.getState();
|
|
549
|
+
addToolCallItem(streamGroupId, {
|
|
550
|
+
id: tc.id,
|
|
551
|
+
toolName: tc.name,
|
|
552
|
+
description: describeToolCall(toolMap.get(tc.name), params),
|
|
553
|
+
params,
|
|
554
|
+
status: parseError ? "error" : "running",
|
|
555
|
+
startedAt: Date.now(),
|
|
556
|
+
...parseError ? {
|
|
557
|
+
error: `JSON parse error: ${parseError}`,
|
|
558
|
+
finishedAt: Date.now()
|
|
559
|
+
} : {}
|
|
560
|
+
});
|
|
561
|
+
if (parseError) {
|
|
562
|
+
streamToolTurns.push({
|
|
563
|
+
role: "tool_result",
|
|
564
|
+
toolCallId: tc.id,
|
|
565
|
+
content: `JSON parse error: ${parseError}`,
|
|
566
|
+
isError: true
|
|
567
|
+
});
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const result = await executeTool(tc.name, tc.arguments);
|
|
571
|
+
const content = result.ok ? result.content : JSON.stringify(result.error);
|
|
572
|
+
updateToolCallItem(streamGroupId, tc.id, {
|
|
573
|
+
status: result.ok ? "completed" : "error",
|
|
574
|
+
result: result.ok ? result.content : void 0,
|
|
575
|
+
resultPreview: result.ok ? result.content.slice(0, 80) : void 0,
|
|
576
|
+
error: !result.ok ? content : void 0,
|
|
577
|
+
finishedAt: Date.now()
|
|
578
|
+
});
|
|
579
|
+
streamToolTurns.push({
|
|
580
|
+
role: "tool_result",
|
|
581
|
+
toolCallId: tc.id,
|
|
582
|
+
content,
|
|
583
|
+
isError: !result.ok
|
|
584
|
+
});
|
|
585
|
+
if (operations.length > lastOpsLength) {
|
|
586
|
+
lastOpsLength = operations.length;
|
|
587
|
+
onOperationsChanged?.(operations);
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
setStatus("thinking");
|
|
591
|
+
for await (const chunk of provider.chat(messages, toolSchemas)) {
|
|
592
|
+
signal?.throwIfAborted();
|
|
593
|
+
if (chunk.type === "thinking") {
|
|
594
|
+
thinkingAccum += chunk.text;
|
|
595
|
+
if (!hasThinking) {
|
|
596
|
+
hasThinking = true;
|
|
597
|
+
thinkingId = nextThinkingId();
|
|
598
|
+
addBubble({
|
|
599
|
+
type: "thinking",
|
|
600
|
+
content: chunk.text,
|
|
601
|
+
id: thinkingId,
|
|
602
|
+
rawText: chunk.text,
|
|
603
|
+
steps: [],
|
|
604
|
+
isStreaming: true
|
|
605
|
+
});
|
|
606
|
+
} else updateLastBubble({
|
|
607
|
+
type: "thinking",
|
|
608
|
+
content: thinkingAccum,
|
|
609
|
+
id: thinkingId,
|
|
610
|
+
rawText: thinkingAccum,
|
|
611
|
+
steps: [],
|
|
612
|
+
isStreaming: true
|
|
613
|
+
});
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (chunk.type === "text") {
|
|
617
|
+
if (!assistantBubbleOpen) {
|
|
618
|
+
addBubble({
|
|
619
|
+
type: "assistant",
|
|
620
|
+
content: chunk.text,
|
|
621
|
+
streaming: true
|
|
622
|
+
});
|
|
623
|
+
assistantBubbleOpen = true;
|
|
624
|
+
textAccum = chunk.text;
|
|
625
|
+
setStatus("writing");
|
|
626
|
+
} else {
|
|
627
|
+
textAccum += chunk.text;
|
|
628
|
+
updateLastBubble({
|
|
629
|
+
type: "assistant",
|
|
630
|
+
content: textAccum,
|
|
631
|
+
streaming: true
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (chunk.type === "tool_call") {
|
|
637
|
+
toolCalls.push({
|
|
638
|
+
id: chunk.id,
|
|
639
|
+
name: chunk.name,
|
|
640
|
+
arguments: chunk.arguments
|
|
641
|
+
});
|
|
642
|
+
await runToolCallMidStream({
|
|
643
|
+
id: chunk.id,
|
|
644
|
+
name: chunk.name,
|
|
645
|
+
arguments: chunk.arguments
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
if (hasThinking) {
|
|
650
|
+
const { bubbles } = store.getState();
|
|
651
|
+
const thinkingIdx = bubbles.findIndex((b) => b.type === "thinking" && "id" in b && b.id === thinkingId);
|
|
652
|
+
if (thinkingIdx !== -1) {
|
|
653
|
+
const nextBubbles = [...bubbles];
|
|
654
|
+
nextBubbles[thinkingIdx] = {
|
|
655
|
+
type: "thinking",
|
|
656
|
+
content: thinkingAccum,
|
|
657
|
+
id: thinkingId,
|
|
658
|
+
rawText: thinkingAccum,
|
|
659
|
+
steps: splitSteps(thinkingAccum),
|
|
660
|
+
isStreaming: false
|
|
661
|
+
};
|
|
662
|
+
store.setState({ bubbles: nextBubbles });
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (assistantBubbleOpen) {
|
|
666
|
+
updateLastBubble({
|
|
667
|
+
type: "assistant",
|
|
668
|
+
content: textAccum,
|
|
669
|
+
streaming: false
|
|
670
|
+
});
|
|
671
|
+
assistantBubbleOpen = false;
|
|
672
|
+
}
|
|
673
|
+
if (toolCalls.length === 0) break;
|
|
674
|
+
turns.push({
|
|
675
|
+
role: "assistant_tool_call",
|
|
676
|
+
toolCalls
|
|
677
|
+
});
|
|
678
|
+
for (const t of streamToolTurns) turns.push(t);
|
|
679
|
+
}
|
|
680
|
+
setStatus("done");
|
|
681
|
+
return { operations };
|
|
682
|
+
}
|
|
683
|
+
return { run };
|
|
684
|
+
}
|
|
685
|
+
//#endregion
|
|
686
|
+
//#region src/snapshot.ts
|
|
606
687
|
function createSnapshot(editorState) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
};
|
|
688
|
+
const children = editorState.root.children ?? [];
|
|
689
|
+
const blockMap = /* @__PURE__ */ new Map();
|
|
690
|
+
const blockIds = [];
|
|
691
|
+
for (const child of children) {
|
|
692
|
+
const blockId = child.$?.blockId;
|
|
693
|
+
if (blockId) {
|
|
694
|
+
blockMap.set(blockId, child);
|
|
695
|
+
blockIds.push(blockId);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return {
|
|
699
|
+
raw: editorState,
|
|
700
|
+
blockIds,
|
|
701
|
+
getBlock: (blockId) => blockMap.get(blockId)
|
|
702
|
+
};
|
|
623
703
|
}
|
|
624
704
|
function compareBlockContent(a, b) {
|
|
625
|
-
|
|
705
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
626
706
|
}
|
|
707
|
+
//#endregion
|
|
708
|
+
//#region src/diff-engine.ts
|
|
627
709
|
function makeDiffState(entries) {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
};
|
|
710
|
+
return {
|
|
711
|
+
entries,
|
|
712
|
+
getByBlockId(blockId) {
|
|
713
|
+
return entries.find((e) => {
|
|
714
|
+
if (e.op.op === "replace" || e.op.op === "delete") return e.op.blockId === blockId;
|
|
715
|
+
if (e.op.op === "insert" && e.op.position.type !== "root") return e.op.position.blockId === blockId;
|
|
716
|
+
return false;
|
|
717
|
+
});
|
|
718
|
+
},
|
|
719
|
+
getPending() {
|
|
720
|
+
return entries.filter((e) => e.status === "pending");
|
|
721
|
+
}
|
|
722
|
+
};
|
|
642
723
|
}
|
|
643
724
|
function createDiffEngine(operations, editorState) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
};
|
|
656
|
-
});
|
|
657
|
-
return makeDiffState(entries);
|
|
725
|
+
const snap = createSnapshot(editorState);
|
|
726
|
+
return makeDiffState(operations.map((op) => {
|
|
727
|
+
let originalNode;
|
|
728
|
+
if (op.op === "replace" || op.op === "delete") originalNode = snap.getBlock(op.blockId);
|
|
729
|
+
return {
|
|
730
|
+
id: nanoid(8),
|
|
731
|
+
op,
|
|
732
|
+
status: "pending",
|
|
733
|
+
originalNode
|
|
734
|
+
};
|
|
735
|
+
}));
|
|
658
736
|
}
|
|
659
737
|
function updateEntry(state, entryId, status) {
|
|
660
|
-
|
|
661
|
-
|
|
738
|
+
return makeDiffState(state.entries.map((e) => e.id === entryId ? {
|
|
739
|
+
...e,
|
|
740
|
+
status
|
|
741
|
+
} : e));
|
|
662
742
|
}
|
|
663
743
|
function acceptDiff(state, entryId) {
|
|
664
|
-
|
|
744
|
+
return updateEntry(state, entryId, "accepted");
|
|
665
745
|
}
|
|
666
746
|
function rejectDiff(state, entryId) {
|
|
667
|
-
|
|
747
|
+
return updateEntry(state, entryId, "rejected");
|
|
668
748
|
}
|
|
669
749
|
function acceptAllDiffs(state) {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
750
|
+
return makeDiffState(state.entries.map((e) => e.status === "pending" ? {
|
|
751
|
+
...e,
|
|
752
|
+
status: "accepted"
|
|
753
|
+
} : e));
|
|
674
754
|
}
|
|
675
755
|
function rejectAllDiffs(state) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
756
|
+
return makeDiffState(state.entries.map((e) => e.status === "pending" ? {
|
|
757
|
+
...e,
|
|
758
|
+
status: "rejected"
|
|
759
|
+
} : e));
|
|
680
760
|
}
|
|
761
|
+
//#endregion
|
|
762
|
+
//#region src/document-context.ts
|
|
681
763
|
function buildDocumentContext(editorState, options) {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
});
|
|
764
|
+
return serializeToXml(editorState, createDefaultRegistry(), {
|
|
765
|
+
compact: options.compact ?? true,
|
|
766
|
+
selectedBlockIds: options.selectedBlockIds
|
|
767
|
+
});
|
|
687
768
|
}
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region src/initialState.ts
|
|
688
771
|
function createInitialAgentStoreState(initialBubbles) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
772
|
+
return {
|
|
773
|
+
status: "idle",
|
|
774
|
+
bubbles: initialBubbles ?? [],
|
|
775
|
+
diffState: null,
|
|
776
|
+
reviewState: null,
|
|
777
|
+
liveSelection: null,
|
|
778
|
+
pinnedSelection: null
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
//#endregion
|
|
782
|
+
//#region src/provider/sse-claude.ts
|
|
698
783
|
async function* parseClaudeSSE(response) {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
784
|
+
const reader = response.body.getReader();
|
|
785
|
+
const decoder = new TextDecoder();
|
|
786
|
+
let buffer = "";
|
|
787
|
+
let currentToolBlock = null;
|
|
788
|
+
try {
|
|
789
|
+
while (true) {
|
|
790
|
+
const { done, value } = await reader.read();
|
|
791
|
+
if (done) break;
|
|
792
|
+
buffer += decoder.decode(value, { stream: true });
|
|
793
|
+
const lines = buffer.split("\n");
|
|
794
|
+
buffer = lines.pop();
|
|
795
|
+
let currentEvent = "";
|
|
796
|
+
for (const line of lines) {
|
|
797
|
+
if (line.startsWith("event: ")) {
|
|
798
|
+
currentEvent = line.slice(7).trim();
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
if (!line.startsWith("data: ")) continue;
|
|
802
|
+
const data = line.slice(6).trim();
|
|
803
|
+
if (!data) continue;
|
|
804
|
+
let parsed;
|
|
805
|
+
try {
|
|
806
|
+
parsed = JSON.parse(data);
|
|
807
|
+
} catch {
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
const eventType = currentEvent || parsed.type;
|
|
811
|
+
if (eventType === "content_block_start") {
|
|
812
|
+
if (parsed.content_block?.type === "tool_use") currentToolBlock = {
|
|
813
|
+
id: parsed.content_block.id,
|
|
814
|
+
name: parsed.content_block.name,
|
|
815
|
+
arguments: ""
|
|
816
|
+
};
|
|
817
|
+
} else if (eventType === "content_block_delta") {
|
|
818
|
+
const delta = parsed.delta;
|
|
819
|
+
if (delta?.type === "text_delta") yield {
|
|
820
|
+
type: "text",
|
|
821
|
+
text: delta.text
|
|
822
|
+
};
|
|
823
|
+
else if (delta?.type === "thinking_delta") yield {
|
|
824
|
+
type: "thinking",
|
|
825
|
+
text: delta.thinking
|
|
826
|
+
};
|
|
827
|
+
else if (delta?.type === "input_json_delta" && currentToolBlock) currentToolBlock.arguments += delta.partial_json;
|
|
828
|
+
} else if (eventType === "content_block_stop") {
|
|
829
|
+
if (currentToolBlock) {
|
|
830
|
+
yield {
|
|
831
|
+
type: "tool_call",
|
|
832
|
+
id: currentToolBlock.id,
|
|
833
|
+
name: currentToolBlock.name,
|
|
834
|
+
arguments: currentToolBlock.arguments
|
|
835
|
+
};
|
|
836
|
+
currentToolBlock = null;
|
|
837
|
+
}
|
|
838
|
+
} else if (eventType === "message_stop") yield { type: "done" };
|
|
839
|
+
currentEvent = "";
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
} finally {
|
|
843
|
+
reader.releaseLock();
|
|
844
|
+
}
|
|
845
|
+
yield { type: "done" };
|
|
846
|
+
}
|
|
847
|
+
//#endregion
|
|
848
|
+
//#region src/provider/sse-openai.ts
|
|
764
849
|
async function* parseOpenAISSE(response) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
yield { type: "done" };
|
|
893
|
-
}
|
|
850
|
+
const reader = response.body.getReader();
|
|
851
|
+
const decoder = new TextDecoder();
|
|
852
|
+
let buffer = "";
|
|
853
|
+
const pendingToolCalls = /* @__PURE__ */ new Map();
|
|
854
|
+
function isBalanced(s) {
|
|
855
|
+
if (!s) return false;
|
|
856
|
+
let depth = 0;
|
|
857
|
+
let inString = false;
|
|
858
|
+
let escape = false;
|
|
859
|
+
let sawOpen = false;
|
|
860
|
+
for (let i = 0; i < s.length; i++) {
|
|
861
|
+
const c = s[i];
|
|
862
|
+
if (escape) {
|
|
863
|
+
escape = false;
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
if (c === "\\") {
|
|
867
|
+
escape = true;
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
if (c === "\"") {
|
|
871
|
+
inString = !inString;
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
if (inString) continue;
|
|
875
|
+
if (c === "{" || c === "[") {
|
|
876
|
+
depth++;
|
|
877
|
+
sawOpen = true;
|
|
878
|
+
} else if (c === "}" || c === "]") {
|
|
879
|
+
depth--;
|
|
880
|
+
if (sawOpen && depth === 0) return true;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
function tryYieldReady() {
|
|
886
|
+
const ready = [];
|
|
887
|
+
for (const tc of pendingToolCalls.values()) {
|
|
888
|
+
if (tc.yielded) continue;
|
|
889
|
+
if (!tc.id || !tc.name) continue;
|
|
890
|
+
if (!isBalanced(tc.arguments)) continue;
|
|
891
|
+
try {
|
|
892
|
+
JSON.parse(tc.arguments);
|
|
893
|
+
} catch {
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
tc.yielded = true;
|
|
897
|
+
ready.push({
|
|
898
|
+
type: "tool_call",
|
|
899
|
+
id: tc.id,
|
|
900
|
+
name: tc.name,
|
|
901
|
+
arguments: tc.arguments
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
return ready;
|
|
905
|
+
}
|
|
906
|
+
try {
|
|
907
|
+
while (true) {
|
|
908
|
+
const { done, value } = await reader.read();
|
|
909
|
+
if (done) break;
|
|
910
|
+
buffer += decoder.decode(value, { stream: true });
|
|
911
|
+
const lines = buffer.split("\n");
|
|
912
|
+
buffer = lines.pop();
|
|
913
|
+
for (const line of lines) {
|
|
914
|
+
if (!line.startsWith("data: ")) continue;
|
|
915
|
+
const data = line.slice(6).trim();
|
|
916
|
+
if (data === "[DONE]") {
|
|
917
|
+
for (const tc of pendingToolCalls.values()) {
|
|
918
|
+
if (tc.yielded) continue;
|
|
919
|
+
yield {
|
|
920
|
+
type: "tool_call",
|
|
921
|
+
id: tc.id,
|
|
922
|
+
name: tc.name,
|
|
923
|
+
arguments: tc.arguments
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
pendingToolCalls.clear();
|
|
927
|
+
yield { type: "done" };
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
let parsed;
|
|
931
|
+
try {
|
|
932
|
+
parsed = JSON.parse(data);
|
|
933
|
+
} catch {
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
const delta = parsed.choices?.[0]?.delta;
|
|
937
|
+
if (!delta) continue;
|
|
938
|
+
if (delta.content) yield {
|
|
939
|
+
type: "text",
|
|
940
|
+
text: delta.content
|
|
941
|
+
};
|
|
942
|
+
if (delta.tool_calls) {
|
|
943
|
+
for (const tc of delta.tool_calls) {
|
|
944
|
+
const idx = tc.index ?? 0;
|
|
945
|
+
if (!pendingToolCalls.has(idx)) pendingToolCalls.set(idx, {
|
|
946
|
+
id: tc.id || "",
|
|
947
|
+
name: tc.function?.name || "",
|
|
948
|
+
arguments: "",
|
|
949
|
+
yielded: false
|
|
950
|
+
});
|
|
951
|
+
const pending = pendingToolCalls.get(idx);
|
|
952
|
+
if (tc.id) pending.id = tc.id;
|
|
953
|
+
if (tc.function?.name) pending.name = tc.function.name;
|
|
954
|
+
if (tc.function?.arguments) pending.arguments += tc.function.arguments;
|
|
955
|
+
}
|
|
956
|
+
for (const ready of tryYieldReady()) yield ready;
|
|
957
|
+
}
|
|
958
|
+
if (parsed.choices?.[0]?.finish_reason === "tool_calls") for (const tc of pendingToolCalls.values()) {
|
|
959
|
+
if (tc.yielded) continue;
|
|
960
|
+
yield {
|
|
961
|
+
type: "tool_call",
|
|
962
|
+
id: tc.id,
|
|
963
|
+
name: tc.name,
|
|
964
|
+
arguments: tc.arguments
|
|
965
|
+
};
|
|
966
|
+
tc.yielded = true;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
} finally {
|
|
971
|
+
reader.releaseLock();
|
|
972
|
+
}
|
|
973
|
+
yield { type: "done" };
|
|
974
|
+
}
|
|
975
|
+
//#endregion
|
|
976
|
+
//#region src/provider/create-provider.ts
|
|
894
977
|
function createProvider(config) {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
978
|
+
const { model, transport, providerType } = config;
|
|
979
|
+
const parse = providerType === "claude" ? parseClaudeSSE : parseOpenAISSE;
|
|
980
|
+
return { async *chat(messages, tools) {
|
|
981
|
+
const response = await transport(messages, tools, model, new AbortController().signal);
|
|
982
|
+
if (!response.ok) {
|
|
983
|
+
const err = await response.text();
|
|
984
|
+
throw new Error(`LLM API error (${response.status}): ${err}`);
|
|
985
|
+
}
|
|
986
|
+
yield* parse(response);
|
|
987
|
+
} };
|
|
988
|
+
}
|
|
989
|
+
//#endregion
|
|
990
|
+
//#region src/provider/message-format.ts
|
|
909
991
|
function buildClaudeBody(messages, tools, model) {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
992
|
+
const systemMsgs = messages.filter((m) => m.role === "system");
|
|
993
|
+
const claudeMessages = messages.filter((m) => m.role !== "system").map((m) => {
|
|
994
|
+
if (m.role === "user") return {
|
|
995
|
+
role: "user",
|
|
996
|
+
content: m.content
|
|
997
|
+
};
|
|
998
|
+
if (m.role === "assistant") return {
|
|
999
|
+
role: "assistant",
|
|
1000
|
+
content: m.content
|
|
1001
|
+
};
|
|
1002
|
+
if (m.role === "assistant_tool_call") return {
|
|
1003
|
+
role: "assistant",
|
|
1004
|
+
content: m.toolCalls.map((tc) => ({
|
|
1005
|
+
type: "tool_use",
|
|
1006
|
+
id: tc.id,
|
|
1007
|
+
name: tc.name,
|
|
1008
|
+
input: JSON.parse(tc.arguments)
|
|
1009
|
+
}))
|
|
1010
|
+
};
|
|
1011
|
+
if (m.role === "tool_result") return {
|
|
1012
|
+
role: "user",
|
|
1013
|
+
content: [{
|
|
1014
|
+
type: "tool_result",
|
|
1015
|
+
tool_use_id: m.toolCallId,
|
|
1016
|
+
content: m.content,
|
|
1017
|
+
is_error: m.isError
|
|
1018
|
+
}]
|
|
1019
|
+
};
|
|
1020
|
+
return {
|
|
1021
|
+
role: m.role,
|
|
1022
|
+
content: m.content
|
|
1023
|
+
};
|
|
1024
|
+
});
|
|
1025
|
+
const claudeTools = tools?.map((t) => ({
|
|
1026
|
+
name: t.name,
|
|
1027
|
+
description: t.description,
|
|
1028
|
+
input_schema: t.parameters
|
|
1029
|
+
}));
|
|
1030
|
+
const body = {
|
|
1031
|
+
model,
|
|
1032
|
+
max_tokens: 4096,
|
|
1033
|
+
stream: true,
|
|
1034
|
+
messages: claudeMessages
|
|
1035
|
+
};
|
|
1036
|
+
if (systemMsgs.length > 0) body.system = systemMsgs.map((m) => ({
|
|
1037
|
+
type: "text",
|
|
1038
|
+
text: m.content
|
|
1039
|
+
}));
|
|
1040
|
+
if (claudeTools?.length) body.tools = claudeTools;
|
|
1041
|
+
if (model.includes("opus") || model.includes("sonnet")) body.thinking = {
|
|
1042
|
+
type: "enabled",
|
|
1043
|
+
budget_tokens: 2048
|
|
1044
|
+
};
|
|
1045
|
+
return body;
|
|
962
1046
|
}
|
|
963
1047
|
function buildOpenAIBody(messages, tools, model) {
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1048
|
+
const openaiMessages = messages.map((m) => {
|
|
1049
|
+
if (m.role === "system") return {
|
|
1050
|
+
role: "system",
|
|
1051
|
+
content: m.content
|
|
1052
|
+
};
|
|
1053
|
+
if (m.role === "user") return {
|
|
1054
|
+
role: "user",
|
|
1055
|
+
content: m.content
|
|
1056
|
+
};
|
|
1057
|
+
if (m.role === "assistant") return {
|
|
1058
|
+
role: "assistant",
|
|
1059
|
+
content: m.content
|
|
1060
|
+
};
|
|
1061
|
+
if (m.role === "assistant_tool_call") return {
|
|
1062
|
+
role: "assistant",
|
|
1063
|
+
content: null,
|
|
1064
|
+
tool_calls: m.toolCalls.map((tc) => ({
|
|
1065
|
+
id: tc.id,
|
|
1066
|
+
type: "function",
|
|
1067
|
+
function: {
|
|
1068
|
+
name: tc.name,
|
|
1069
|
+
arguments: tc.arguments
|
|
1070
|
+
}
|
|
1071
|
+
}))
|
|
1072
|
+
};
|
|
1073
|
+
if (m.role === "tool_result") return {
|
|
1074
|
+
role: "tool",
|
|
1075
|
+
tool_call_id: m.toolCallId,
|
|
1076
|
+
content: m.content
|
|
1077
|
+
};
|
|
1078
|
+
return {
|
|
1079
|
+
role: m.role,
|
|
1080
|
+
content: m.content
|
|
1081
|
+
};
|
|
1082
|
+
});
|
|
1083
|
+
const openaiTools = tools?.map((t) => ({
|
|
1084
|
+
type: "function",
|
|
1085
|
+
function: {
|
|
1086
|
+
name: t.name,
|
|
1087
|
+
description: t.description,
|
|
1088
|
+
parameters: t.parameters
|
|
1089
|
+
}
|
|
1090
|
+
}));
|
|
1091
|
+
const body = {
|
|
1092
|
+
model,
|
|
1093
|
+
stream: true,
|
|
1094
|
+
messages: openaiMessages
|
|
1095
|
+
};
|
|
1096
|
+
if (openaiTools?.length) body.tools = openaiTools;
|
|
1097
|
+
return body;
|
|
1098
|
+
}
|
|
1099
|
+
//#endregion
|
|
1100
|
+
//#region src/provider/transport.ts
|
|
1002
1101
|
function createDirectTransport(config) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1102
|
+
const { apiKey, baseUrl, providerType } = config;
|
|
1103
|
+
return async (messages, tools, model, signal) => {
|
|
1104
|
+
if (providerType === "claude") {
|
|
1105
|
+
const body = buildClaudeBody(messages, tools, model);
|
|
1106
|
+
return fetch(`${baseUrl}/messages`, {
|
|
1107
|
+
method: "POST",
|
|
1108
|
+
headers: {
|
|
1109
|
+
"Content-Type": "application/json",
|
|
1110
|
+
"x-api-key": apiKey,
|
|
1111
|
+
"anthropic-version": "2023-06-01",
|
|
1112
|
+
"anthropic-beta": "interleaved-thinking-2025-05-14"
|
|
1113
|
+
},
|
|
1114
|
+
body: JSON.stringify(body),
|
|
1115
|
+
signal
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
const body = buildOpenAIBody(messages, tools, model);
|
|
1119
|
+
return fetch(`${baseUrl}/chat/completions`, {
|
|
1120
|
+
method: "POST",
|
|
1121
|
+
headers: {
|
|
1122
|
+
"Content-Type": "application/json",
|
|
1123
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1124
|
+
},
|
|
1125
|
+
body: JSON.stringify(body),
|
|
1126
|
+
signal
|
|
1127
|
+
});
|
|
1128
|
+
};
|
|
1030
1129
|
}
|
|
1031
1130
|
function createProxyTransport(config) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
}
|
|
1131
|
+
const { endpoint, headers: extraHeaders } = config;
|
|
1132
|
+
return async (messages, tools, model, signal) => {
|
|
1133
|
+
return fetch(endpoint, {
|
|
1134
|
+
method: "POST",
|
|
1135
|
+
headers: {
|
|
1136
|
+
"Content-Type": "application/json",
|
|
1137
|
+
...extraHeaders
|
|
1138
|
+
},
|
|
1139
|
+
body: JSON.stringify({
|
|
1140
|
+
model,
|
|
1141
|
+
messages,
|
|
1142
|
+
tools
|
|
1143
|
+
}),
|
|
1144
|
+
signal
|
|
1145
|
+
});
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
//#endregion
|
|
1149
|
+
//#region src/review-engine.ts
|
|
1045
1150
|
function getBlockId(node) {
|
|
1046
|
-
|
|
1151
|
+
return node.$?.blockId;
|
|
1047
1152
|
}
|
|
1048
1153
|
function resolveRootInsertIndex(index, length) {
|
|
1049
|
-
|
|
1050
|
-
return Math.min(Math.max(resolved, 0), length);
|
|
1154
|
+
return Math.min(Math.max(index ?? length, 0), length);
|
|
1051
1155
|
}
|
|
1052
1156
|
function getChildBlockId(children, index) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1157
|
+
const child = children[index];
|
|
1158
|
+
return child ? getBlockId(child) : void 0;
|
|
1055
1159
|
}
|
|
1056
1160
|
function getInsertAnchors(children, position) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
targetBlockId: position.blockId,
|
|
1084
|
-
anchorBeforeId: getChildBlockId(children, index - 1),
|
|
1085
|
-
anchorAfterId: getChildBlockId(children, index)
|
|
1086
|
-
};
|
|
1161
|
+
if (position.type === "root") {
|
|
1162
|
+
const index = resolveRootInsertIndex(position.index, children.length);
|
|
1163
|
+
const anchorBeforeId = getChildBlockId(children, index - 1);
|
|
1164
|
+
const anchorAfterId = getChildBlockId(children, index);
|
|
1165
|
+
return {
|
|
1166
|
+
targetBlockId: anchorAfterId ?? anchorBeforeId,
|
|
1167
|
+
anchorBeforeId,
|
|
1168
|
+
anchorAfterId
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
const index = children.findIndex((child) => getBlockId(child) === position.blockId);
|
|
1172
|
+
if (index === -1) return {
|
|
1173
|
+
targetBlockId: position.blockId,
|
|
1174
|
+
anchorBeforeId: position.type === "after" ? position.blockId : void 0,
|
|
1175
|
+
anchorAfterId: position.type === "before" ? position.blockId : void 0
|
|
1176
|
+
};
|
|
1177
|
+
if (position.type === "after") return {
|
|
1178
|
+
targetBlockId: position.blockId,
|
|
1179
|
+
anchorBeforeId: getChildBlockId(children, index),
|
|
1180
|
+
anchorAfterId: getChildBlockId(children, index + 1)
|
|
1181
|
+
};
|
|
1182
|
+
return {
|
|
1183
|
+
targetBlockId: position.blockId,
|
|
1184
|
+
anchorBeforeId: getChildBlockId(children, index - 1),
|
|
1185
|
+
anchorAfterId: getChildBlockId(children, index)
|
|
1186
|
+
};
|
|
1087
1187
|
}
|
|
1088
1188
|
function cloneChildren(root) {
|
|
1089
|
-
|
|
1189
|
+
return [...root.children ?? []].map((c) => ({ ...c }));
|
|
1090
1190
|
}
|
|
1091
1191
|
function snapshotChildren(snapshot) {
|
|
1092
|
-
|
|
1192
|
+
return snapshot.root.children ?? [];
|
|
1093
1193
|
}
|
|
1094
1194
|
function snapshotHasBlock(snapshot, blockId) {
|
|
1095
|
-
|
|
1195
|
+
return snapshotChildren(snapshot).some((child) => getBlockId(child) === blockId);
|
|
1096
1196
|
}
|
|
1097
1197
|
function canApplyOpToSnapshot(snapshot, op) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1101
|
-
return snapshotHasBlock(snapshot, op.blockId);
|
|
1198
|
+
if (op.op === "insert") return op.position.type === "root" || snapshotHasBlock(snapshot, op.position.blockId);
|
|
1199
|
+
return snapshotHasBlock(snapshot, op.blockId);
|
|
1102
1200
|
}
|
|
1103
1201
|
function applyOpsToSnapshot(base, ops) {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
return {
|
|
1132
|
-
root: { ...base.root, children }
|
|
1133
|
-
};
|
|
1202
|
+
let children = cloneChildren(base.root);
|
|
1203
|
+
const insertOffset = /* @__PURE__ */ new Map();
|
|
1204
|
+
for (const op of ops) if (op.op === "insert") {
|
|
1205
|
+
if (!op.node?.type) continue;
|
|
1206
|
+
const pos = op.position;
|
|
1207
|
+
if (pos.type === "root") {
|
|
1208
|
+
const idx = resolveRootInsertIndex(pos.index, children.length);
|
|
1209
|
+
children.splice(idx, 0, op.node);
|
|
1210
|
+
} else {
|
|
1211
|
+
const idx = children.findIndex((c) => getBlockId(c) === pos.blockId);
|
|
1212
|
+
if (idx === -1) continue;
|
|
1213
|
+
const baseIdx = pos.type === "after" ? idx + 1 : idx;
|
|
1214
|
+
const key = `${pos.type}:${pos.blockId}`;
|
|
1215
|
+
const offset = insertOffset.get(key) ?? 0;
|
|
1216
|
+
children.splice(baseIdx + offset, 0, op.node);
|
|
1217
|
+
insertOffset.set(key, offset + 1);
|
|
1218
|
+
}
|
|
1219
|
+
} else if (op.op === "replace") {
|
|
1220
|
+
if (!op.node?.type) continue;
|
|
1221
|
+
const idx = children.findIndex((c) => getBlockId(c) === op.blockId);
|
|
1222
|
+
if (idx === -1) continue;
|
|
1223
|
+
children[idx] = op.node;
|
|
1224
|
+
} else if (op.op === "delete") children = children.filter((c) => getBlockId(c) !== op.blockId);
|
|
1225
|
+
return { root: {
|
|
1226
|
+
...base.root,
|
|
1227
|
+
children
|
|
1228
|
+
} };
|
|
1134
1229
|
}
|
|
1135
1230
|
function fingerprint(node) {
|
|
1136
|
-
|
|
1231
|
+
return JSON.stringify(node);
|
|
1137
1232
|
}
|
|
1138
1233
|
function extractTouchedBlockIds(entries) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
}
|
|
1143
|
-
return [...ids];
|
|
1234
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1235
|
+
for (const entry of entries) if (entry.targetBlockId) ids.add(entry.targetBlockId);
|
|
1236
|
+
return [...ids];
|
|
1144
1237
|
}
|
|
1145
1238
|
function updateResolvedBatch(state, batchId, status) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1239
|
+
return {
|
|
1240
|
+
...state,
|
|
1241
|
+
batches: state.batches.map((batch) => batch.id === batchId ? {
|
|
1242
|
+
...batch,
|
|
1243
|
+
status,
|
|
1244
|
+
entries: batch.entries.map((entry) => ({
|
|
1245
|
+
...entry,
|
|
1246
|
+
status
|
|
1247
|
+
}))
|
|
1248
|
+
} : batch)
|
|
1249
|
+
};
|
|
1156
1250
|
}
|
|
1157
1251
|
function batchEntriesMatch(left, right, predicate) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
if (predicate(leftEntry, rightEntry)) {
|
|
1161
|
-
return true;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
return false;
|
|
1252
|
+
for (const leftEntry of left.entries) for (const rightEntry of right.entries) if (predicate(leftEntry, rightEntry)) return true;
|
|
1253
|
+
return false;
|
|
1166
1254
|
}
|
|
1167
1255
|
function createReviewBatch(ops, baseSnapshot, baseRevision) {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
baseSnapshot,
|
|
1208
|
-
previewSnapshot,
|
|
1209
|
-
status: "pending",
|
|
1210
|
-
entries,
|
|
1211
|
-
touchedBlockIds: extractTouchedBlockIds(entries)
|
|
1212
|
-
};
|
|
1256
|
+
const previewSnapshot = applyOpsToSnapshot(baseSnapshot, ops);
|
|
1257
|
+
const baseChildren = baseSnapshot.root.children ?? [];
|
|
1258
|
+
const blockMap = /* @__PURE__ */ new Map();
|
|
1259
|
+
for (const child of baseChildren) {
|
|
1260
|
+
const id = getBlockId(child);
|
|
1261
|
+
if (id) blockMap.set(id, child);
|
|
1262
|
+
}
|
|
1263
|
+
const entries = ops.filter((op) => {
|
|
1264
|
+
if (op.op === "insert" || op.op === "replace") return !!op.node?.type;
|
|
1265
|
+
return true;
|
|
1266
|
+
}).map((op) => {
|
|
1267
|
+
let targetBlockId;
|
|
1268
|
+
let anchorBeforeId;
|
|
1269
|
+
let anchorAfterId;
|
|
1270
|
+
let fp = "";
|
|
1271
|
+
if (op.op === "replace" || op.op === "delete") {
|
|
1272
|
+
targetBlockId = op.blockId;
|
|
1273
|
+
const orig = blockMap.get(op.blockId);
|
|
1274
|
+
if (orig) fp = fingerprint(orig);
|
|
1275
|
+
} else if (op.op === "insert") ({targetBlockId, anchorBeforeId, anchorAfterId} = getInsertAnchors(baseChildren, op.position));
|
|
1276
|
+
return {
|
|
1277
|
+
id: nanoid(8),
|
|
1278
|
+
op,
|
|
1279
|
+
targetBlockId,
|
|
1280
|
+
anchorBeforeId,
|
|
1281
|
+
anchorAfterId,
|
|
1282
|
+
originalFingerprint: fp,
|
|
1283
|
+
status: "pending"
|
|
1284
|
+
};
|
|
1285
|
+
});
|
|
1286
|
+
return {
|
|
1287
|
+
id: nanoid(8),
|
|
1288
|
+
baseRevision,
|
|
1289
|
+
baseSnapshot,
|
|
1290
|
+
previewSnapshot,
|
|
1291
|
+
status: "pending",
|
|
1292
|
+
entries,
|
|
1293
|
+
touchedBlockIds: extractTouchedBlockIds(entries)
|
|
1294
|
+
};
|
|
1213
1295
|
}
|
|
1214
1296
|
function acceptBatch(state, batchId) {
|
|
1215
|
-
|
|
1297
|
+
return updateResolvedBatch(state, batchId, "accepted");
|
|
1216
1298
|
}
|
|
1217
1299
|
function rejectBatch(state, batchId) {
|
|
1218
|
-
|
|
1300
|
+
return updateResolvedBatch(state, batchId, "rejected");
|
|
1219
1301
|
}
|
|
1220
1302
|
function batchesConflict(left, right) {
|
|
1221
|
-
|
|
1303
|
+
return batchEntriesMatch(left, right, entriesConflict);
|
|
1222
1304
|
}
|
|
1223
1305
|
function batchesAreOrderDependent(left, right) {
|
|
1224
|
-
|
|
1306
|
+
return batchEntriesMatch(left, right, entriesAreOrderDependent);
|
|
1225
1307
|
}
|
|
1226
1308
|
function entriesConflict(left, right) {
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
}
|
|
1235
|
-
if (rightOp.op === "delete") {
|
|
1236
|
-
return conflictsWithDeletedBlock(rightOp.blockId, left);
|
|
1237
|
-
}
|
|
1238
|
-
if (leftOp.op === "replace" && rightOp.op === "replace") {
|
|
1239
|
-
return leftOp.blockId === rightOp.blockId;
|
|
1240
|
-
}
|
|
1241
|
-
return false;
|
|
1309
|
+
const leftOp = left.op;
|
|
1310
|
+
const rightOp = right.op;
|
|
1311
|
+
if (leftOp.op === "insert" && rightOp.op === "insert") return false;
|
|
1312
|
+
if (leftOp.op === "delete") return conflictsWithDeletedBlock(leftOp.blockId, right);
|
|
1313
|
+
if (rightOp.op === "delete") return conflictsWithDeletedBlock(rightOp.blockId, left);
|
|
1314
|
+
if (leftOp.op === "replace" && rightOp.op === "replace") return leftOp.blockId === rightOp.blockId;
|
|
1315
|
+
return false;
|
|
1242
1316
|
}
|
|
1243
1317
|
function entriesAreOrderDependent(left, right) {
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
}
|
|
1247
|
-
return left.anchorBeforeId === right.anchorBeforeId && left.anchorAfterId === right.anchorAfterId;
|
|
1318
|
+
if (left.op.op !== "insert" || right.op.op !== "insert") return false;
|
|
1319
|
+
return left.anchorBeforeId === right.anchorBeforeId && left.anchorAfterId === right.anchorAfterId;
|
|
1248
1320
|
}
|
|
1249
1321
|
function conflictsWithDeletedBlock(deletedBlockId, entry) {
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
}
|
|
1254
|
-
return entry.targetBlockId === deletedBlockId || entry.anchorBeforeId === deletedBlockId || entry.anchorAfterId === deletedBlockId;
|
|
1322
|
+
const op = entry.op;
|
|
1323
|
+
if (op.op === "delete" || op.op === "replace") return op.blockId === deletedBlockId;
|
|
1324
|
+
return entry.targetBlockId === deletedBlockId || entry.anchorBeforeId === deletedBlockId || entry.anchorAfterId === deletedBlockId;
|
|
1255
1325
|
}
|
|
1256
1326
|
function isFinalBatchStatus(status) {
|
|
1257
|
-
|
|
1327
|
+
return status === "accepted" || status === "rejected";
|
|
1258
1328
|
}
|
|
1259
1329
|
function getInitialBatchStatus(batch, documentRevision) {
|
|
1260
|
-
|
|
1330
|
+
return batch.baseRevision < documentRevision ? "conflicted" : "pending";
|
|
1261
1331
|
}
|
|
1262
1332
|
function updateStatusUnlessConflicted(statuses, batchId, status) {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
}
|
|
1266
|
-
statuses.set(batchId, status);
|
|
1333
|
+
if (statuses.get(batchId) === "conflicted") return;
|
|
1334
|
+
statuses.set(batchId, status);
|
|
1267
1335
|
}
|
|
1268
1336
|
function rebaseBatch(batch, baseSnapshot, baseRevision) {
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
...rebased,
|
|
1276
|
-
id: batch.id
|
|
1277
|
-
};
|
|
1337
|
+
const ops = batch.entries.map((entry) => entry.op);
|
|
1338
|
+
if (!ops.every((op) => canApplyOpToSnapshot(baseSnapshot, op))) return batch;
|
|
1339
|
+
return {
|
|
1340
|
+
...createReviewBatch(ops, baseSnapshot, baseRevision),
|
|
1341
|
+
id: batch.id
|
|
1342
|
+
};
|
|
1278
1343
|
}
|
|
1279
1344
|
function reconcileReviewBatches(state) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
...state,
|
|
1305
|
-
batches: state.batches.map(
|
|
1306
|
-
(batch) => isFinalBatchStatus(batch.status) ? batch : { ...batch, status: nextStatuses.get(batch.id) ?? batch.status }
|
|
1307
|
-
)
|
|
1308
|
-
};
|
|
1345
|
+
const nextStatuses = /* @__PURE__ */ new Map();
|
|
1346
|
+
const activeBatches = state.batches.filter((batch) => !isFinalBatchStatus(batch.status));
|
|
1347
|
+
const currentRevisionBatches = activeBatches.filter((batch) => batch.baseRevision === state.documentRevision);
|
|
1348
|
+
for (const batch of activeBatches) nextStatuses.set(batch.id, getInitialBatchStatus(batch, state.documentRevision));
|
|
1349
|
+
for (let i = 0; i < currentRevisionBatches.length; i++) for (let j = i + 1; j < currentRevisionBatches.length; j++) {
|
|
1350
|
+
const left = currentRevisionBatches[i];
|
|
1351
|
+
const right = currentRevisionBatches[j];
|
|
1352
|
+
if (batchesConflict(left, right)) {
|
|
1353
|
+
nextStatuses.set(left.id, "conflicted");
|
|
1354
|
+
nextStatuses.set(right.id, "conflicted");
|
|
1355
|
+
continue;
|
|
1356
|
+
}
|
|
1357
|
+
if (batchesAreOrderDependent(left, right)) {
|
|
1358
|
+
updateStatusUnlessConflicted(nextStatuses, left.id, "order_dependent");
|
|
1359
|
+
updateStatusUnlessConflicted(nextStatuses, right.id, "order_dependent");
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
return {
|
|
1363
|
+
...state,
|
|
1364
|
+
batches: state.batches.map((batch) => isFinalBatchStatus(batch.status) ? batch : {
|
|
1365
|
+
...batch,
|
|
1366
|
+
status: nextStatuses.get(batch.id) ?? batch.status
|
|
1367
|
+
})
|
|
1368
|
+
};
|
|
1309
1369
|
}
|
|
1310
1370
|
function acceptAndRebaseBatch(state, batchId) {
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
}
|
|
1324
|
-
return rebaseBatch(batch, acceptedBatch.previewSnapshot, nextRevision);
|
|
1325
|
-
})
|
|
1326
|
-
};
|
|
1327
|
-
return reconcileReviewBatches(nextState);
|
|
1371
|
+
const acceptedState = acceptBatch(state, batchId);
|
|
1372
|
+
const acceptedBatch = acceptedState.batches.find((batch) => batch.id === batchId);
|
|
1373
|
+
if (!acceptedBatch) return state;
|
|
1374
|
+
const nextRevision = state.documentRevision + 1;
|
|
1375
|
+
return reconcileReviewBatches({
|
|
1376
|
+
...acceptedState,
|
|
1377
|
+
documentRevision: nextRevision,
|
|
1378
|
+
batches: acceptedState.batches.map((batch) => {
|
|
1379
|
+
if (batch.id === batchId || isFinalBatchStatus(batch.status)) return batch;
|
|
1380
|
+
return rebaseBatch(batch, acceptedBatch.previewSnapshot, nextRevision);
|
|
1381
|
+
})
|
|
1382
|
+
});
|
|
1328
1383
|
}
|
|
1329
1384
|
function resolveReviewEntry(state, batchId, entryId, resolution) {
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1385
|
+
return {
|
|
1386
|
+
...state,
|
|
1387
|
+
batches: state.batches.map((batch) => {
|
|
1388
|
+
if (batch.id !== batchId) return batch;
|
|
1389
|
+
const entries = batch.entries.map((entry) => entry.id === entryId ? {
|
|
1390
|
+
...entry,
|
|
1391
|
+
status: resolution
|
|
1392
|
+
} : entry);
|
|
1393
|
+
const allResolved = entries.every((e) => e.status === "accepted" || e.status === "rejected");
|
|
1394
|
+
let batchStatus = batch.status;
|
|
1395
|
+
if (allResolved) batchStatus = entries.every((e) => e.status === "rejected") ? "rejected" : "accepted";
|
|
1396
|
+
return {
|
|
1397
|
+
...batch,
|
|
1398
|
+
entries,
|
|
1399
|
+
status: batchStatus
|
|
1400
|
+
};
|
|
1401
|
+
})
|
|
1402
|
+
};
|
|
1346
1403
|
}
|
|
1347
1404
|
function detectConflicts(state) {
|
|
1348
|
-
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1405
|
+
return reconcileReviewBatches(state);
|
|
1406
|
+
}
|
|
1407
|
+
//#endregion
|
|
1408
|
+
//#region src/selectors.ts
|
|
1409
|
+
var agentStoreSelectors = {
|
|
1410
|
+
bubbles: (state) => state.bubbles,
|
|
1411
|
+
diffState: (state) => state.diffState,
|
|
1412
|
+
liveSelection: (state) => state.liveSelection,
|
|
1413
|
+
pinnedSelection: (state) => state.pinnedSelection,
|
|
1414
|
+
reviewState: (state) => state.reviewState,
|
|
1415
|
+
status: (state) => state.status
|
|
1357
1416
|
};
|
|
1417
|
+
//#endregion
|
|
1418
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/checkPrivateRedeclaration.js
|
|
1419
|
+
function _checkPrivateRedeclaration(e, t) {
|
|
1420
|
+
if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
1421
|
+
}
|
|
1422
|
+
//#endregion
|
|
1423
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/classPrivateFieldInitSpec.js
|
|
1424
|
+
function _classPrivateFieldInitSpec(e, t, a) {
|
|
1425
|
+
_checkPrivateRedeclaration(e, t), t.set(e, a);
|
|
1426
|
+
}
|
|
1427
|
+
//#endregion
|
|
1428
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/assertClassBrand.js
|
|
1429
|
+
function _assertClassBrand(e, t, n) {
|
|
1430
|
+
if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
|
|
1431
|
+
throw new TypeError("Private element is not present on this object");
|
|
1432
|
+
}
|
|
1433
|
+
//#endregion
|
|
1434
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/classPrivateFieldGet2.js
|
|
1435
|
+
function _classPrivateFieldGet2(s, a) {
|
|
1436
|
+
return s.get(_assertClassBrand(s, a));
|
|
1437
|
+
}
|
|
1438
|
+
//#endregion
|
|
1439
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/classPrivateFieldSet2.js
|
|
1440
|
+
function _classPrivateFieldSet2(s, a, r) {
|
|
1441
|
+
return s.set(_assertClassBrand(s, a), r), r;
|
|
1442
|
+
}
|
|
1443
|
+
//#endregion
|
|
1444
|
+
//#region src/store-actions.ts
|
|
1358
1445
|
function createAgentStoreSlice(set, get, api) {
|
|
1359
|
-
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
if (!descriptor) continue;
|
|
1475
|
-
if (typeof descriptor.value === "function") {
|
|
1476
|
-
result[key] = descriptor.value.bind(action);
|
|
1477
|
-
} else {
|
|
1478
|
-
Object.defineProperty(result, key, {
|
|
1479
|
-
...descriptor,
|
|
1480
|
-
configurable: true,
|
|
1481
|
-
enumerable: true
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
current = Object.getPrototypeOf(current);
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
return result;
|
|
1446
|
+
return new AgentStoreActionImpl(set, get, api);
|
|
1447
|
+
}
|
|
1448
|
+
var _get = /* @__PURE__ */ new WeakMap();
|
|
1449
|
+
var _set = /* @__PURE__ */ new WeakMap();
|
|
1450
|
+
var AgentStoreActionImpl = class {
|
|
1451
|
+
constructor(set, get, api) {
|
|
1452
|
+
_classPrivateFieldInitSpec(this, _get, void 0);
|
|
1453
|
+
_classPrivateFieldInitSpec(this, _set, void 0);
|
|
1454
|
+
this.addBubble = (bubble) => {
|
|
1455
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => ({ bubbles: [...state.bubbles, bubble] }));
|
|
1456
|
+
};
|
|
1457
|
+
this.reset = () => {
|
|
1458
|
+
_classPrivateFieldGet2(_set, this).call(this, createInitialAgentStoreState());
|
|
1459
|
+
};
|
|
1460
|
+
this.setLiveSelection = (selection) => {
|
|
1461
|
+
_classPrivateFieldGet2(_set, this).call(this, { liveSelection: selection });
|
|
1462
|
+
};
|
|
1463
|
+
this.clearLiveSelection = () => {
|
|
1464
|
+
_classPrivateFieldGet2(_set, this).call(this, { liveSelection: null });
|
|
1465
|
+
};
|
|
1466
|
+
this.pinSelection = (selection) => {
|
|
1467
|
+
_classPrivateFieldGet2(_set, this).call(this, { pinnedSelection: selection });
|
|
1468
|
+
};
|
|
1469
|
+
this.clearPinnedSelection = () => {
|
|
1470
|
+
_classPrivateFieldGet2(_set, this).call(this, { pinnedSelection: null });
|
|
1471
|
+
};
|
|
1472
|
+
this.setDiffState = (diffState) => {
|
|
1473
|
+
_classPrivateFieldGet2(_set, this).call(this, { diffState });
|
|
1474
|
+
};
|
|
1475
|
+
this.addReviewBatch = (batch) => {
|
|
1476
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1477
|
+
const current = state.reviewState ?? {
|
|
1478
|
+
documentRevision: 0,
|
|
1479
|
+
batches: []
|
|
1480
|
+
};
|
|
1481
|
+
return { reviewState: reconcileReviewBatches({
|
|
1482
|
+
...current,
|
|
1483
|
+
batches: [...current.batches, batch]
|
|
1484
|
+
}) };
|
|
1485
|
+
});
|
|
1486
|
+
};
|
|
1487
|
+
this.acceptReviewBatch = (batchId) => {
|
|
1488
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1489
|
+
if (!state.reviewState) return {};
|
|
1490
|
+
return { reviewState: acceptAndRebaseBatch(state.reviewState, batchId) };
|
|
1491
|
+
});
|
|
1492
|
+
};
|
|
1493
|
+
this.acceptReviewEntry = (batchId, entryId) => {
|
|
1494
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1495
|
+
if (!state.reviewState) return {};
|
|
1496
|
+
return { reviewState: resolveReviewEntry(state.reviewState, batchId, entryId, "accepted") };
|
|
1497
|
+
});
|
|
1498
|
+
};
|
|
1499
|
+
this.rejectReviewBatch = (batchId) => {
|
|
1500
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1501
|
+
if (!state.reviewState) return {};
|
|
1502
|
+
return { reviewState: reconcileReviewBatches(rejectBatch(state.reviewState, batchId)) };
|
|
1503
|
+
});
|
|
1504
|
+
};
|
|
1505
|
+
this.rejectReviewEntry = (batchId, entryId) => {
|
|
1506
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1507
|
+
if (!state.reviewState) return {};
|
|
1508
|
+
return { reviewState: resolveReviewEntry(state.reviewState, batchId, entryId, "rejected") };
|
|
1509
|
+
});
|
|
1510
|
+
};
|
|
1511
|
+
this.setReviewState = (reviewState) => {
|
|
1512
|
+
_classPrivateFieldGet2(_set, this).call(this, { reviewState });
|
|
1513
|
+
};
|
|
1514
|
+
this.setStatus = (status) => {
|
|
1515
|
+
_classPrivateFieldGet2(_set, this).call(this, { status });
|
|
1516
|
+
};
|
|
1517
|
+
this.updateToolCallItem = (groupId, itemId, patch) => {
|
|
1518
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1519
|
+
const idx = state.bubbles.findIndex((b) => b.type === "tool_call_group" && b.id === groupId);
|
|
1520
|
+
if (idx === -1) return {};
|
|
1521
|
+
const group = state.bubbles[idx];
|
|
1522
|
+
const itemIdx = group.items.findIndex((item) => item.id === itemId);
|
|
1523
|
+
if (itemIdx === -1) return {};
|
|
1524
|
+
const nextItems = [...group.items];
|
|
1525
|
+
nextItems[itemIdx] = {
|
|
1526
|
+
...nextItems[itemIdx],
|
|
1527
|
+
...patch
|
|
1528
|
+
};
|
|
1529
|
+
const nextBubbles = [...state.bubbles];
|
|
1530
|
+
nextBubbles[idx] = {
|
|
1531
|
+
...group,
|
|
1532
|
+
items: nextItems
|
|
1533
|
+
};
|
|
1534
|
+
return { bubbles: nextBubbles };
|
|
1535
|
+
});
|
|
1536
|
+
};
|
|
1537
|
+
this.addToolCallItem = (groupId, item) => {
|
|
1538
|
+
_classPrivateFieldGet2(_set, this).call(this, (state) => {
|
|
1539
|
+
const idx = state.bubbles.findIndex((b) => b.type === "tool_call_group" && b.id === groupId);
|
|
1540
|
+
if (idx === -1) return {};
|
|
1541
|
+
const group = state.bubbles[idx];
|
|
1542
|
+
if (group.items.some((it) => it.id === item.id)) return {};
|
|
1543
|
+
const nextBubbles = [...state.bubbles];
|
|
1544
|
+
nextBubbles[idx] = {
|
|
1545
|
+
...group,
|
|
1546
|
+
items: [...group.items, item]
|
|
1547
|
+
};
|
|
1548
|
+
return { bubbles: nextBubbles };
|
|
1549
|
+
});
|
|
1550
|
+
};
|
|
1551
|
+
this.updateLastBubble = (bubble) => {
|
|
1552
|
+
const { bubbles } = _classPrivateFieldGet2(_get, this).call(this);
|
|
1553
|
+
if (bubbles.length === 0) return;
|
|
1554
|
+
const nextBubbles = [...bubbles];
|
|
1555
|
+
nextBubbles[nextBubbles.length - 1] = bubble;
|
|
1556
|
+
_classPrivateFieldGet2(_set, this).call(this, { bubbles: nextBubbles });
|
|
1557
|
+
};
|
|
1558
|
+
_classPrivateFieldSet2(_set, this, set);
|
|
1559
|
+
_classPrivateFieldSet2(_get, this, get);
|
|
1560
|
+
}
|
|
1489
1561
|
};
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
compareBlockContent,
|
|
1515
|
-
createAgentExecutor,
|
|
1516
|
-
createAgentStore,
|
|
1517
|
-
createAgentStoreSlice,
|
|
1518
|
-
createDiffEngine,
|
|
1519
|
-
createDirectTransport,
|
|
1520
|
-
createDocumentTools,
|
|
1521
|
-
createInitialAgentStoreState,
|
|
1522
|
-
createProvider,
|
|
1523
|
-
createProxyTransport,
|
|
1524
|
-
createReviewBatch,
|
|
1525
|
-
createSnapshot,
|
|
1526
|
-
detectConflicts,
|
|
1527
|
-
flattenActions,
|
|
1528
|
-
reconcileReviewBatches,
|
|
1529
|
-
rejectAllDiffs,
|
|
1530
|
-
rejectBatch,
|
|
1531
|
-
rejectDiff,
|
|
1532
|
-
resolveReviewEntry
|
|
1562
|
+
//#endregion
|
|
1563
|
+
//#region src/store-utils.ts
|
|
1564
|
+
var flattenActions = (actions) => {
|
|
1565
|
+
const result = {};
|
|
1566
|
+
for (const action of actions) {
|
|
1567
|
+
let current = action;
|
|
1568
|
+
while (current && current !== Object.prototype) {
|
|
1569
|
+
const keys = Object.getOwnPropertyNames(current);
|
|
1570
|
+
for (const key of keys) {
|
|
1571
|
+
if (key === "constructor") continue;
|
|
1572
|
+
if (key in result) continue;
|
|
1573
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
1574
|
+
if (!descriptor) continue;
|
|
1575
|
+
if (typeof descriptor.value === "function") result[key] = descriptor.value.bind(action);
|
|
1576
|
+
else Object.defineProperty(result, key, {
|
|
1577
|
+
...descriptor,
|
|
1578
|
+
configurable: true,
|
|
1579
|
+
enumerable: true
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
current = Object.getPrototypeOf(current);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
return result;
|
|
1533
1586
|
};
|
|
1587
|
+
//#endregion
|
|
1588
|
+
//#region src/store.ts
|
|
1589
|
+
function createAgentStore(initialBubbles) {
|
|
1590
|
+
const stateCreator = (...params) => ({
|
|
1591
|
+
...createInitialAgentStoreState(initialBubbles),
|
|
1592
|
+
...flattenActions([createAgentStoreSlice(...params)])
|
|
1593
|
+
});
|
|
1594
|
+
return createStore()(stateCreator);
|
|
1595
|
+
}
|
|
1596
|
+
//#endregion
|
|
1597
|
+
export { BaseEveryUserContentProvider, BaseFirstUserContentProvider, BaseFirstUserContentProvider as BaseFirstUserMessageProvider, BaseLastUserContentProvider, BaseMessageEngineProcessor, BaseSystemRoleProvider as BaseSystemMessageProvider, BaseSystemRoleProvider, BaseSystemRootProvider, MessagesEngine, acceptAllDiffs, acceptAndRebaseBatch, acceptBatch, acceptDiff, agentStoreSelectors, applyOpsToSnapshot, buildDocumentContext, compareBlockContent, createAgentExecutor, createAgentStore, createAgentStoreSlice, createDiffEngine, createDirectTransport, createDocumentTools, createInitialAgentStoreState, createProvider, createProxyTransport, createReviewBatch, createSnapshot, detectConflicts, flattenActions, reconcileReviewBatches, rejectAllDiffs, rejectBatch, rejectDiff, resolveReviewEntry };
|