@ai-sdk/harness-deepagents 1.0.133 → 1.0.135
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/CHANGELOG.md +19 -0
- package/dist/bridge/index.mjs +1343 -2393
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +131 -129
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +758 -932
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/bridge/index.ts +1 -1
package/dist/bridge/index.mjs
CHANGED
|
@@ -1,2481 +1,1431 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
// ../harness/dist/bridge/index.js
|
|
6
|
-
import { appendFile, mkdir, writeFile } from "fs/promises";
|
|
7
|
-
import { existsSync, readFileSync } from "fs";
|
|
8
|
-
import { randomUUID } from "crypto";
|
|
9
|
-
import { env as procEnv, pid, stdout } from "process";
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { argv, env, pid, stdout } from "node:process";
|
|
3
|
+
import { appendFile, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
5
|
import { WebSocketServer } from "ws";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
import { ChatAnthropic } from "@langchain/anthropic";
|
|
7
|
+
import { tool } from "@langchain/core/tools";
|
|
8
|
+
import { Command, MemorySaver, Overwrite } from "@langchain/langgraph";
|
|
9
|
+
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
10
|
+
import { LocalShellBackend, createDeepAgent } from "deepagents";
|
|
11
|
+
import { createMiddleware, toolStrategy } from "langchain";
|
|
12
|
+
import { z } from "zod/v4";
|
|
13
|
+
import { dirname } from "node:path";
|
|
14
|
+
import { AIMessage, ToolMessage } from "@langchain/core/messages";
|
|
15
|
+
//#region ../harness/dist/bridge/index.js
|
|
16
|
+
const DEBUG_LEVEL_WEIGHT = {
|
|
17
|
+
error: 0,
|
|
18
|
+
warn: 1,
|
|
19
|
+
info: 2,
|
|
20
|
+
debug: 3,
|
|
21
|
+
trace: 4
|
|
17
22
|
};
|
|
23
|
+
/** Exact-or-dotted-prefix subsystem match (`'bridge'` matches `'bridge.turn'`). */
|
|
18
24
|
function subsystemMatches(filters, subsystem) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
(filter) => subsystem === filter || subsystem.startsWith(`${filter}.`)
|
|
22
|
-
);
|
|
25
|
+
if (!filters || filters.length === 0) return true;
|
|
26
|
+
return filters.some((filter) => subsystem === filter || subsystem.startsWith(`${filter}.`));
|
|
23
27
|
}
|
|
24
28
|
function formatBridgeError(err) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return { message: String(err) };
|
|
29
|
+
if (err instanceof Error) return {
|
|
30
|
+
name: err.name,
|
|
31
|
+
message: err.message,
|
|
32
|
+
stack: err.stack
|
|
33
|
+
};
|
|
34
|
+
if (typeof err === "string") return { message: err };
|
|
35
|
+
if (err !== null && typeof err === "object") try {
|
|
36
|
+
return { message: JSON.stringify(err) };
|
|
37
|
+
} catch {}
|
|
38
|
+
return { message: String(err) };
|
|
38
39
|
}
|
|
39
40
|
function createBridgeUserMessageQueue(options) {
|
|
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
|
-
value: void 0
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
return new Promise(
|
|
130
|
-
(resolve) => {
|
|
131
|
-
waiters.push(resolve);
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
};
|
|
41
|
+
const messages = [];
|
|
42
|
+
const waiters = [];
|
|
43
|
+
const entries = /* @__PURE__ */ new Map();
|
|
44
|
+
let closed = false;
|
|
45
|
+
let pendingCount = 0;
|
|
46
|
+
const enqueue = (input) => {
|
|
47
|
+
const existing = entries.get(input.messageId);
|
|
48
|
+
if (existing != null) {
|
|
49
|
+
if (existing.response != null) options.respond(existing.response);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let settled = false;
|
|
53
|
+
const settle = (response) => {
|
|
54
|
+
if (settled) return;
|
|
55
|
+
settled = true;
|
|
56
|
+
pendingCount--;
|
|
57
|
+
const entry = entries.get(input.messageId);
|
|
58
|
+
if (entry != null) entry.response = response;
|
|
59
|
+
options.respond(response);
|
|
60
|
+
};
|
|
61
|
+
const message = {
|
|
62
|
+
messageId: input.messageId,
|
|
63
|
+
text: input.text,
|
|
64
|
+
accept: () => {
|
|
65
|
+
settle({
|
|
66
|
+
type: "user-message-response",
|
|
67
|
+
messageId: input.messageId,
|
|
68
|
+
accepted: true
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
reject: (error) => {
|
|
72
|
+
settle({
|
|
73
|
+
type: "user-message-response",
|
|
74
|
+
messageId: input.messageId,
|
|
75
|
+
accepted: false,
|
|
76
|
+
error: { message: formatBridgeError(error).message }
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
entries.set(input.messageId, { reject: message.reject });
|
|
81
|
+
pendingCount++;
|
|
82
|
+
if (closed) {
|
|
83
|
+
message.reject(/* @__PURE__ */ new Error("The bridge turn is no longer accepting user messages."));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const waiter = waiters.shift();
|
|
87
|
+
if (waiter != null) waiter({
|
|
88
|
+
done: false,
|
|
89
|
+
value: message
|
|
90
|
+
});
|
|
91
|
+
else messages.push(message);
|
|
92
|
+
};
|
|
93
|
+
const close = (error) => {
|
|
94
|
+
if (closed) return;
|
|
95
|
+
closed = true;
|
|
96
|
+
const reason = error ?? /* @__PURE__ */ new Error("The bridge turn ended before accepting the user message.");
|
|
97
|
+
for (const entry of entries.values()) if (entry.response == null) entry.reject(reason);
|
|
98
|
+
messages.length = 0;
|
|
99
|
+
while (waiters.length > 0) waiters.shift()({
|
|
100
|
+
done: true,
|
|
101
|
+
value: void 0
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
return {
|
|
105
|
+
get pendingCount() {
|
|
106
|
+
return pendingCount;
|
|
107
|
+
},
|
|
108
|
+
enqueue,
|
|
109
|
+
close,
|
|
110
|
+
[Symbol.asyncIterator]() {
|
|
111
|
+
return { next: () => {
|
|
112
|
+
const message = messages.shift();
|
|
113
|
+
if (message != null) return Promise.resolve({
|
|
114
|
+
done: false,
|
|
115
|
+
value: message
|
|
116
|
+
});
|
|
117
|
+
if (closed) return Promise.resolve({
|
|
118
|
+
done: true,
|
|
119
|
+
value: void 0
|
|
120
|
+
});
|
|
121
|
+
return new Promise((resolve) => {
|
|
122
|
+
waiters.push(resolve);
|
|
123
|
+
});
|
|
124
|
+
} };
|
|
125
|
+
}
|
|
126
|
+
};
|
|
138
127
|
}
|
|
139
128
|
function parseEnvList(value) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
if (!value) return void 0;
|
|
130
|
+
const items = value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
131
|
+
return items.length > 0 ? items : void 0;
|
|
143
132
|
}
|
|
144
|
-
|
|
145
|
-
|
|
133
|
+
const ENV_TRUTHY = /* @__PURE__ */ new Set([
|
|
134
|
+
"1",
|
|
135
|
+
"true",
|
|
136
|
+
"yes",
|
|
137
|
+
"on"
|
|
138
|
+
]);
|
|
139
|
+
const WS_OPEN = 1;
|
|
146
140
|
async function runBridge(options) {
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
-
options.onListening?.(currentBoundPort);
|
|
579
|
-
});
|
|
580
|
-
wss.on("connection", (ws, req) => {
|
|
581
|
-
const url = new URL(req.url ?? "/", "http://localhost");
|
|
582
|
-
if (url.searchParams.get("agent_bridge_token") !== expectedToken) {
|
|
583
|
-
ws.close(1008, "unauthorized");
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
sendControl(ws, {
|
|
587
|
-
type: "bridge-hello",
|
|
588
|
-
state: currentTurnState,
|
|
589
|
-
lastSeq: seqCounter,
|
|
590
|
-
capabilities: { experimental_userMessageResponses: true }
|
|
591
|
-
});
|
|
592
|
-
ws.on("message", (raw) => {
|
|
593
|
-
let parsed;
|
|
594
|
-
try {
|
|
595
|
-
const text = typeof raw === "string" ? raw : Buffer.from(raw).toString("utf8");
|
|
596
|
-
parsed = JSON.parse(text);
|
|
597
|
-
} catch (err) {
|
|
598
|
-
sendControl(ws, {
|
|
599
|
-
type: "error",
|
|
600
|
-
error: `protocol parse error: ${err.message}`
|
|
601
|
-
});
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
void handleInbound(parsed, ws);
|
|
605
|
-
});
|
|
606
|
-
ws.on("close", () => {
|
|
607
|
-
if (activeSocket === ws) {
|
|
608
|
-
activeSocket = void 0;
|
|
609
|
-
}
|
|
610
|
-
});
|
|
611
|
-
ws.on("error", () => {
|
|
612
|
-
});
|
|
613
|
-
});
|
|
614
|
-
process.on("uncaughtException", (err) => {
|
|
615
|
-
emitError({ error: err, message: "uncaught exception" });
|
|
616
|
-
});
|
|
617
|
-
process.on("unhandledRejection", (err) => {
|
|
618
|
-
emitError({ error: err, message: "unhandled rejection" });
|
|
619
|
-
});
|
|
620
|
-
await new Promise((resolve, reject) => {
|
|
621
|
-
if (wss.address() != null) {
|
|
622
|
-
resolve();
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
wss.once("listening", resolve);
|
|
626
|
-
wss.once("error", reject);
|
|
627
|
-
});
|
|
628
|
-
return {
|
|
629
|
-
port: currentBoundPort,
|
|
630
|
-
close: () => new Promise((resolve) => {
|
|
631
|
-
wss.close(() => resolve());
|
|
632
|
-
})
|
|
633
|
-
};
|
|
141
|
+
const { bridgeType, bridgeStateDir, onStart, onStop, onDestroy } = options;
|
|
142
|
+
const teardownGraceMs = options.turnTeardownGraceMs ?? 1e4;
|
|
143
|
+
const expectedToken = options.token ?? env.BRIDGE_CHANNEL_TOKEN ?? "";
|
|
144
|
+
const bridgeWsPort = options.port ?? parseInt(env.BRIDGE_WS_PORT ?? "0", 10);
|
|
145
|
+
const bridgeMetaPath = `${bridgeStateDir}/bridge-meta.json`;
|
|
146
|
+
const startConfigPath = `${bridgeStateDir}/start-config.json`;
|
|
147
|
+
const rerunStartConfigPath = `${bridgeStateDir}/rerun-start-config.json`;
|
|
148
|
+
const eventLogPath = `${bridgeStateDir}/event-log.ndjson`;
|
|
149
|
+
try {
|
|
150
|
+
await mkdir(bridgeStateDir, { recursive: true });
|
|
151
|
+
} catch {}
|
|
152
|
+
let currentBoundPort = 0;
|
|
153
|
+
let currentTurnState = "init";
|
|
154
|
+
let activeSocket;
|
|
155
|
+
let isFirstTurn = true;
|
|
156
|
+
let turnAbort;
|
|
157
|
+
let currentUserMessages;
|
|
158
|
+
/**
|
|
159
|
+
* Settles when the in-flight turn has fully wound down — `onStart`
|
|
160
|
+
* returned or threw AND its completion state was recorded. `undefined`
|
|
161
|
+
* between turns. A new `start` fences on this so turns never overlap.
|
|
162
|
+
*/
|
|
163
|
+
let activeTurn;
|
|
164
|
+
let debugConfig;
|
|
165
|
+
let consoleCaptureInstalled = false;
|
|
166
|
+
const envDebugEnabled = ENV_TRUTHY.has((env.HARNESS_DEBUG ?? "").toLowerCase());
|
|
167
|
+
let seqCounter = 0;
|
|
168
|
+
let eventLog = [];
|
|
169
|
+
let diskBuffer = "";
|
|
170
|
+
let flushPromise = null;
|
|
171
|
+
const flushEventsToDisk = async () => {
|
|
172
|
+
while (diskBuffer.length > 0) {
|
|
173
|
+
const buf = diskBuffer;
|
|
174
|
+
diskBuffer = "";
|
|
175
|
+
await appendFile(eventLogPath, buf).catch(() => {});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const scheduleEventFlush = () => {
|
|
179
|
+
if (flushPromise) return;
|
|
180
|
+
flushPromise = new Promise((resolve) => {
|
|
181
|
+
setImmediate(() => {
|
|
182
|
+
flushEventsToDisk().finally(resolve);
|
|
183
|
+
});
|
|
184
|
+
}).finally(() => {
|
|
185
|
+
flushPromise = null;
|
|
186
|
+
if (diskBuffer.length > 0) scheduleEventFlush();
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const flushPendingEventsToDisk = async () => {
|
|
190
|
+
if (diskBuffer.length > 0 && !flushPromise) scheduleEventFlush();
|
|
191
|
+
let inFlight = flushPromise;
|
|
192
|
+
while (inFlight) {
|
|
193
|
+
await inFlight;
|
|
194
|
+
inFlight = flushPromise;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
if (env.BRIDGE_REPLAY_FROM_DISK === "1" && existsSync(eventLogPath)) try {
|
|
198
|
+
eventLog = readFileSync(eventLogPath, "utf8").split("\n").map((line) => line.trim()).filter(Boolean).map((line) => ({
|
|
199
|
+
seq: JSON.parse(line).seq,
|
|
200
|
+
line
|
|
201
|
+
}));
|
|
202
|
+
seqCounter = eventLog.at(-1)?.seq ?? 0;
|
|
203
|
+
} catch {
|
|
204
|
+
eventLog = [];
|
|
205
|
+
seqCounter = 0;
|
|
206
|
+
}
|
|
207
|
+
const pendingToolResults = /* @__PURE__ */ new Map();
|
|
208
|
+
const bufferedToolResults = [];
|
|
209
|
+
const pendingToolApprovals = /* @__PURE__ */ new Map();
|
|
210
|
+
const writeBridgeMeta = async (state) => {
|
|
211
|
+
try {
|
|
212
|
+
await writeFile(bridgeMetaPath, JSON.stringify({
|
|
213
|
+
type: bridgeType,
|
|
214
|
+
port: currentBoundPort,
|
|
215
|
+
state,
|
|
216
|
+
pid
|
|
217
|
+
}));
|
|
218
|
+
} catch {}
|
|
219
|
+
};
|
|
220
|
+
const writeStartConfig = async (start) => {
|
|
221
|
+
try {
|
|
222
|
+
const serialized = JSON.stringify(start);
|
|
223
|
+
await writeFile(startConfigPath, serialized);
|
|
224
|
+
if (!existsSync(rerunStartConfigPath)) await writeFile(rerunStartConfigPath, serialized);
|
|
225
|
+
} catch {}
|
|
226
|
+
};
|
|
227
|
+
const emit = (event) => {
|
|
228
|
+
const seq = ++seqCounter;
|
|
229
|
+
const line = JSON.stringify({
|
|
230
|
+
...event,
|
|
231
|
+
seq
|
|
232
|
+
});
|
|
233
|
+
eventLog.push({
|
|
234
|
+
seq,
|
|
235
|
+
line
|
|
236
|
+
});
|
|
237
|
+
diskBuffer += `${line}\n`;
|
|
238
|
+
scheduleEventFlush();
|
|
239
|
+
if (activeSocket?.readyState === WS_OPEN) try {
|
|
240
|
+
activeSocket.send(line);
|
|
241
|
+
} catch {}
|
|
242
|
+
};
|
|
243
|
+
const replay = (ws, afterSeq) => {
|
|
244
|
+
for (const entry of eventLog) if (entry.seq > afterSeq && ws.readyState === WS_OPEN) ws.send(entry.line);
|
|
245
|
+
};
|
|
246
|
+
const shouldEmitDebugEvent = (level, subsystem) => {
|
|
247
|
+
if (!debugConfig?.enabled) return false;
|
|
248
|
+
const threshold = debugConfig.level ?? "debug";
|
|
249
|
+
if (DEBUG_LEVEL_WEIGHT[level] > DEBUG_LEVEL_WEIGHT[threshold]) return false;
|
|
250
|
+
return subsystemMatches(debugConfig.subsystems, subsystem);
|
|
251
|
+
};
|
|
252
|
+
const rawStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
253
|
+
const rawStderrWrite = process.stderr.write.bind(process.stderr);
|
|
254
|
+
const writeErrorToStderr = (input) => {
|
|
255
|
+
try {
|
|
256
|
+
const formatted = formatBridgeError(input.error);
|
|
257
|
+
rawStderrWrite(`[harness:${bridgeType}:error] ${input.message}: ${formatted.message}\n`);
|
|
258
|
+
if (formatted.stack) rawStderrWrite(`${formatted.stack}\n`);
|
|
259
|
+
} catch {}
|
|
260
|
+
};
|
|
261
|
+
const emitWarning = (input) => {
|
|
262
|
+
try {
|
|
263
|
+
for (const line of input.message.split("\n")) if (line.trim().length > 0) rawStderrWrite(`[harness:${bridgeType}:warn] ${line}\n`);
|
|
264
|
+
} catch {}
|
|
265
|
+
};
|
|
266
|
+
const emitError = (input) => {
|
|
267
|
+
writeErrorToStderr({
|
|
268
|
+
message: input.message ?? "bridge error",
|
|
269
|
+
error: input.error
|
|
270
|
+
});
|
|
271
|
+
emit({
|
|
272
|
+
type: "error",
|
|
273
|
+
error: serialiseError(input.error)
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
const installConsoleCapture = () => {
|
|
277
|
+
if (consoleCaptureInstalled) return;
|
|
278
|
+
consoleCaptureInstalled = true;
|
|
279
|
+
const buffers = {
|
|
280
|
+
stdout: "",
|
|
281
|
+
stderr: ""
|
|
282
|
+
};
|
|
283
|
+
const patch = (stream, raw) => (chunk, encoding, cb) => {
|
|
284
|
+
if (debugConfig?.enabled) try {
|
|
285
|
+
const enc = typeof encoding === "string" ? encoding : "utf8";
|
|
286
|
+
const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString(enc);
|
|
287
|
+
const parts = (buffers[stream] + text.replace(/\r\n/g, "\n")).split("\n");
|
|
288
|
+
buffers[stream] = parts.pop() ?? "";
|
|
289
|
+
for (const line of parts) {
|
|
290
|
+
const trimmed = line.replace(/\s+$/, "");
|
|
291
|
+
if (trimmed) emit({
|
|
292
|
+
type: "sandbox-log",
|
|
293
|
+
source: bridgeType,
|
|
294
|
+
stream,
|
|
295
|
+
line: trimmed
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
} catch {}
|
|
299
|
+
return raw(chunk, encoding, cb);
|
|
300
|
+
};
|
|
301
|
+
process.stdout.write = patch("stdout", rawStdoutWrite);
|
|
302
|
+
process.stderr.write = patch("stderr", rawStderrWrite);
|
|
303
|
+
};
|
|
304
|
+
const handleInbound = async (msg, ws) => {
|
|
305
|
+
switch (msg.type) {
|
|
306
|
+
case "start": {
|
|
307
|
+
for (;;) {
|
|
308
|
+
const pendingTurn = activeTurn;
|
|
309
|
+
if (pendingTurn == null) break;
|
|
310
|
+
turnAbort?.abort();
|
|
311
|
+
currentUserMessages?.close(/* @__PURE__ */ new Error("A new bridge turn replaced the active turn."));
|
|
312
|
+
let graceTimer;
|
|
313
|
+
const settled = await Promise.race([pendingTurn.then(() => true), new Promise((resolve) => {
|
|
314
|
+
graceTimer = setTimeout(() => resolve(false), teardownGraceMs);
|
|
315
|
+
graceTimer.unref?.();
|
|
316
|
+
})]);
|
|
317
|
+
clearTimeout(graceTimer);
|
|
318
|
+
if (!settled) break;
|
|
319
|
+
}
|
|
320
|
+
let turnFinished;
|
|
321
|
+
const thisTurn = new Promise((resolve) => turnFinished = resolve);
|
|
322
|
+
activeTurn = thisTurn;
|
|
323
|
+
activeSocket = ws;
|
|
324
|
+
const firstTurn = isFirstTurn;
|
|
325
|
+
isFirstTurn = false;
|
|
326
|
+
eventLog = [];
|
|
327
|
+
diskBuffer = "";
|
|
328
|
+
writeFile(eventLogPath, "").catch(() => {});
|
|
329
|
+
turnAbort = new AbortController();
|
|
330
|
+
currentTurnState = "running";
|
|
331
|
+
writeStartConfig(msg);
|
|
332
|
+
writeBridgeMeta("running");
|
|
333
|
+
const startDebug = msg.debug;
|
|
334
|
+
debugConfig = {
|
|
335
|
+
enabled: startDebug?.enabled ?? envDebugEnabled,
|
|
336
|
+
level: startDebug?.level ?? env.HARNESS_DEBUG_LEVEL,
|
|
337
|
+
subsystems: startDebug?.subsystems ?? parseEnvList(env.HARNESS_DEBUG_SUBSYSTEMS)
|
|
338
|
+
};
|
|
339
|
+
if (debugConfig.enabled) installConsoleCapture();
|
|
340
|
+
const userMessages = createBridgeUserMessageQueue({ respond: emit });
|
|
341
|
+
const turn = {
|
|
342
|
+
emit,
|
|
343
|
+
requestToolResult: (requestInput) => {
|
|
344
|
+
const request = typeof requestInput === "string" ? { toolCallId: requestInput } : requestInput;
|
|
345
|
+
const bufferedIndex = bufferedToolResults.findIndex((buffered) => buffered.toolCallId === request.toolCallId || request.matches?.(buffered.result) === true);
|
|
346
|
+
if (bufferedIndex >= 0) return Promise.resolve(bufferedToolResults.splice(bufferedIndex, 1)[0].result);
|
|
347
|
+
return new Promise((resolve) => {
|
|
348
|
+
pendingToolResults.set(request.toolCallId, {
|
|
349
|
+
resolve,
|
|
350
|
+
matches: request.matches
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
},
|
|
354
|
+
requestToolApproval: (approvalId) => new Promise((resolve) => {
|
|
355
|
+
pendingToolApprovals.set(approvalId, resolve);
|
|
356
|
+
}),
|
|
357
|
+
experimental_userMessages: userMessages,
|
|
358
|
+
abortSignal: turnAbort.signal,
|
|
359
|
+
firstTurn,
|
|
360
|
+
bridgeLog: (input) => {
|
|
361
|
+
const level = input.level ?? "debug";
|
|
362
|
+
if (!shouldEmitDebugEvent(level, input.subsystem)) return;
|
|
363
|
+
emit({
|
|
364
|
+
type: "debug-event",
|
|
365
|
+
level,
|
|
366
|
+
subsystem: input.subsystem,
|
|
367
|
+
message: input.message,
|
|
368
|
+
...input.attrs ? { attrs: input.attrs } : {},
|
|
369
|
+
...input.error !== void 0 ? { error: formatBridgeError(input.error) } : {}
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
emitWarning,
|
|
373
|
+
emitError
|
|
374
|
+
};
|
|
375
|
+
currentUserMessages = userMessages;
|
|
376
|
+
try {
|
|
377
|
+
await onStart(msg, turn);
|
|
378
|
+
} catch (err) {
|
|
379
|
+
emitError({
|
|
380
|
+
error: err,
|
|
381
|
+
message: "bridge turn failed"
|
|
382
|
+
});
|
|
383
|
+
} finally {
|
|
384
|
+
userMessages.close();
|
|
385
|
+
if (currentUserMessages === userMessages) currentUserMessages = void 0;
|
|
386
|
+
if (activeTurn === thisTurn) {
|
|
387
|
+
activeTurn = void 0;
|
|
388
|
+
currentTurnState = "waiting";
|
|
389
|
+
writeBridgeMeta("waiting");
|
|
390
|
+
}
|
|
391
|
+
turnFinished();
|
|
392
|
+
}
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
case "tool-result": {
|
|
396
|
+
const result = {
|
|
397
|
+
output: msg.output,
|
|
398
|
+
isError: msg.isError,
|
|
399
|
+
toolResult: msg.toolResult
|
|
400
|
+
};
|
|
401
|
+
const exactPending = pendingToolResults.get(msg.toolCallId);
|
|
402
|
+
const matchingPending = exactPending == null ? Array.from(pendingToolResults.entries()).find(([, pending]) => pending.matches?.(result) === true) : void 0;
|
|
403
|
+
const pending = exactPending ?? matchingPending?.[1];
|
|
404
|
+
const pendingId = exactPending != null ? msg.toolCallId : matchingPending?.[0];
|
|
405
|
+
if (pending != null && pendingId != null) {
|
|
406
|
+
pendingToolResults.delete(pendingId);
|
|
407
|
+
pending.resolve(result);
|
|
408
|
+
} else bufferedToolResults.push({
|
|
409
|
+
toolCallId: msg.toolCallId,
|
|
410
|
+
result
|
|
411
|
+
});
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
case "tool-approval-response": {
|
|
415
|
+
const resolver = pendingToolApprovals.get(msg.approvalId);
|
|
416
|
+
if (resolver) {
|
|
417
|
+
pendingToolApprovals.delete(msg.approvalId);
|
|
418
|
+
resolver({
|
|
419
|
+
approved: msg.approved,
|
|
420
|
+
reason: msg.reason
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
case "user-message": {
|
|
426
|
+
const messageId = msg.messageId ?? randomUUID();
|
|
427
|
+
if (currentUserMessages == null) {
|
|
428
|
+
sendControl(ws, {
|
|
429
|
+
type: "user-message-response",
|
|
430
|
+
messageId,
|
|
431
|
+
accepted: false,
|
|
432
|
+
error: { message: "The bridge has no active turn to steer." }
|
|
433
|
+
});
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (ws !== activeSocket) {
|
|
437
|
+
sendControl(ws, {
|
|
438
|
+
type: "user-message-response",
|
|
439
|
+
messageId,
|
|
440
|
+
accepted: false,
|
|
441
|
+
error: { message: "The connection does not own the active bridge turn." }
|
|
442
|
+
});
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
currentUserMessages.enqueue({
|
|
446
|
+
messageId,
|
|
447
|
+
text: msg.text
|
|
448
|
+
});
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
case "abort":
|
|
452
|
+
turnAbort?.abort();
|
|
453
|
+
return;
|
|
454
|
+
case "resume":
|
|
455
|
+
activeSocket = ws;
|
|
456
|
+
replay(ws, msg.lastSeenEventId);
|
|
457
|
+
return;
|
|
458
|
+
case "destroy":
|
|
459
|
+
currentTurnState = "done";
|
|
460
|
+
writeBridgeMeta("done");
|
|
461
|
+
await onDestroy?.();
|
|
462
|
+
drainThenExit(ws, 1e3, "destroy");
|
|
463
|
+
return;
|
|
464
|
+
case "stop":
|
|
465
|
+
currentTurnState = "done";
|
|
466
|
+
writeBridgeMeta("done");
|
|
467
|
+
sendControl(ws, {
|
|
468
|
+
type: "bridge-stop",
|
|
469
|
+
data: await onStop?.() ?? {}
|
|
470
|
+
});
|
|
471
|
+
drainThenExit(ws, 1e3, "stop");
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
writeBridgeMeta("init");
|
|
475
|
+
const wss = new WebSocketServer({
|
|
476
|
+
port: bridgeWsPort,
|
|
477
|
+
host: "0.0.0.0"
|
|
478
|
+
});
|
|
479
|
+
const exit = () => {
|
|
480
|
+
if (options.onExit) {
|
|
481
|
+
options.onExit();
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
wss.close(() => process.exit(0));
|
|
485
|
+
setTimeout(() => process.exit(0), 1e3).unref();
|
|
486
|
+
};
|
|
487
|
+
const drainThenExit = (ws, code, reason) => {
|
|
488
|
+
const start = Date.now();
|
|
489
|
+
const tick = () => {
|
|
490
|
+
if (ws.bufferedAmount === 0 || ws.readyState !== WS_OPEN || Date.now() - start >= 5e3) {
|
|
491
|
+
flushPendingEventsToDisk().finally(() => {
|
|
492
|
+
try {
|
|
493
|
+
ws.close(code, reason);
|
|
494
|
+
} finally {
|
|
495
|
+
exit();
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
setTimeout(tick, 10).unref();
|
|
501
|
+
};
|
|
502
|
+
tick();
|
|
503
|
+
};
|
|
504
|
+
wss.on("listening", () => {
|
|
505
|
+
const addr = wss.address();
|
|
506
|
+
currentBoundPort = typeof addr === "object" && addr ? addr.port : 0;
|
|
507
|
+
currentTurnState = "waiting";
|
|
508
|
+
writeBridgeMeta("waiting");
|
|
509
|
+
stdout.write(JSON.stringify({
|
|
510
|
+
type: "bridge-ready",
|
|
511
|
+
port: currentBoundPort
|
|
512
|
+
}) + "\n");
|
|
513
|
+
options.onListening?.(currentBoundPort);
|
|
514
|
+
});
|
|
515
|
+
wss.on("connection", (ws, req) => {
|
|
516
|
+
if (new URL(req.url ?? "/", "http://localhost").searchParams.get("agent_bridge_token") !== expectedToken) {
|
|
517
|
+
ws.close(1008, "unauthorized");
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
sendControl(ws, {
|
|
521
|
+
type: "bridge-hello",
|
|
522
|
+
state: currentTurnState,
|
|
523
|
+
lastSeq: seqCounter,
|
|
524
|
+
capabilities: { experimental_userMessageResponses: true }
|
|
525
|
+
});
|
|
526
|
+
ws.on("message", (raw) => {
|
|
527
|
+
let parsed;
|
|
528
|
+
try {
|
|
529
|
+
const text = typeof raw === "string" ? raw : Buffer.from(raw).toString("utf8");
|
|
530
|
+
parsed = JSON.parse(text);
|
|
531
|
+
} catch (err) {
|
|
532
|
+
sendControl(ws, {
|
|
533
|
+
type: "error",
|
|
534
|
+
error: `protocol parse error: ${err.message}`
|
|
535
|
+
});
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
handleInbound(parsed, ws);
|
|
539
|
+
});
|
|
540
|
+
ws.on("close", () => {
|
|
541
|
+
if (activeSocket === ws) activeSocket = void 0;
|
|
542
|
+
});
|
|
543
|
+
ws.on("error", () => {});
|
|
544
|
+
});
|
|
545
|
+
process.on("uncaughtException", (err) => {
|
|
546
|
+
emitError({
|
|
547
|
+
error: err,
|
|
548
|
+
message: "uncaught exception"
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
process.on("unhandledRejection", (err) => {
|
|
552
|
+
emitError({
|
|
553
|
+
error: err,
|
|
554
|
+
message: "unhandled rejection"
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
await new Promise((resolve, reject) => {
|
|
558
|
+
if (wss.address() != null) {
|
|
559
|
+
resolve();
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
wss.once("listening", resolve);
|
|
563
|
+
wss.once("error", reject);
|
|
564
|
+
});
|
|
565
|
+
return {
|
|
566
|
+
port: currentBoundPort,
|
|
567
|
+
close: () => new Promise((resolve) => {
|
|
568
|
+
wss.close(() => resolve());
|
|
569
|
+
})
|
|
570
|
+
};
|
|
634
571
|
}
|
|
635
572
|
function sendControl(socket, message) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
} catch {
|
|
640
|
-
}
|
|
641
|
-
}
|
|
573
|
+
if (socket?.readyState === WS_OPEN) try {
|
|
574
|
+
socket.send(JSON.stringify(message));
|
|
575
|
+
} catch {}
|
|
642
576
|
}
|
|
643
577
|
function serialiseError(err) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
578
|
+
if (err instanceof Error) return {
|
|
579
|
+
name: err.name,
|
|
580
|
+
message: err.message,
|
|
581
|
+
stack: err.stack
|
|
582
|
+
};
|
|
583
|
+
return err;
|
|
648
584
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
import { RunnableBinding, ensureConfig } from "@langchain/core/runnables";
|
|
662
|
-
import { AsyncGeneratorWithSetup, IterableReadableStream } from "@langchain/core/utils/stream";
|
|
663
|
-
import { ChatModelStream } from "@langchain/core/language_models/stream";
|
|
664
|
-
import { DEFAULT_LANGSMITH_GATEWAY, resolveLangSmithGatewayConfig } from "@langchain/core/utils/gateway";
|
|
665
|
-
import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
666
|
-
var MODEL_PROVIDER_CONFIG = {
|
|
667
|
-
openai: {
|
|
668
|
-
package: "@langchain/openai",
|
|
669
|
-
className: "ChatOpenAI"
|
|
670
|
-
},
|
|
671
|
-
anthropic: {
|
|
672
|
-
package: "@langchain/anthropic",
|
|
673
|
-
className: "ChatAnthropic"
|
|
674
|
-
},
|
|
675
|
-
azure_openai: {
|
|
676
|
-
package: "@langchain/openai",
|
|
677
|
-
className: "AzureChatOpenAI"
|
|
678
|
-
},
|
|
679
|
-
langsmith: {
|
|
680
|
-
package: "@langchain/openai",
|
|
681
|
-
className: "ChatOpenAI"
|
|
682
|
-
},
|
|
683
|
-
cohere: {
|
|
684
|
-
package: "@langchain/cohere",
|
|
685
|
-
className: "ChatCohere"
|
|
686
|
-
},
|
|
687
|
-
google: {
|
|
688
|
-
package: "@langchain/google",
|
|
689
|
-
className: "ChatGoogle"
|
|
690
|
-
},
|
|
691
|
-
"google-vertexai": {
|
|
692
|
-
package: "@langchain/google-vertexai",
|
|
693
|
-
className: "ChatVertexAI"
|
|
694
|
-
},
|
|
695
|
-
"google-vertexai-web": {
|
|
696
|
-
package: "@langchain/google-vertexai-web",
|
|
697
|
-
className: "ChatVertexAI"
|
|
698
|
-
},
|
|
699
|
-
"google-genai": {
|
|
700
|
-
package: "@langchain/google-genai",
|
|
701
|
-
className: "ChatGoogleGenerativeAI"
|
|
702
|
-
},
|
|
703
|
-
ollama: {
|
|
704
|
-
package: "@langchain/ollama",
|
|
705
|
-
className: "ChatOllama"
|
|
706
|
-
},
|
|
707
|
-
mistralai: {
|
|
708
|
-
package: "@langchain/mistralai",
|
|
709
|
-
className: "ChatMistralAI"
|
|
710
|
-
},
|
|
711
|
-
mistral: {
|
|
712
|
-
package: "@langchain/mistralai",
|
|
713
|
-
className: "ChatMistralAI"
|
|
714
|
-
},
|
|
715
|
-
groq: {
|
|
716
|
-
package: "@langchain/groq",
|
|
717
|
-
className: "ChatGroq"
|
|
718
|
-
},
|
|
719
|
-
bedrock: {
|
|
720
|
-
package: "@langchain/aws",
|
|
721
|
-
className: "ChatBedrockConverse"
|
|
722
|
-
},
|
|
723
|
-
aws: {
|
|
724
|
-
package: "@langchain/aws",
|
|
725
|
-
className: "ChatBedrockConverse"
|
|
726
|
-
},
|
|
727
|
-
deepseek: {
|
|
728
|
-
package: "@langchain/deepseek",
|
|
729
|
-
className: "ChatDeepSeek"
|
|
730
|
-
},
|
|
731
|
-
xai: {
|
|
732
|
-
package: "@langchain/xai",
|
|
733
|
-
className: "ChatXAI"
|
|
734
|
-
},
|
|
735
|
-
cerebras: {
|
|
736
|
-
package: "@langchain/cerebras",
|
|
737
|
-
className: "ChatCerebras"
|
|
738
|
-
},
|
|
739
|
-
fireworks: {
|
|
740
|
-
package: "@langchain/fireworks",
|
|
741
|
-
className: "ChatFireworks"
|
|
742
|
-
},
|
|
743
|
-
together: {
|
|
744
|
-
package: "@langchain/together-ai",
|
|
745
|
-
className: "ChatTogetherAI",
|
|
746
|
-
hasCircularDependency: true
|
|
747
|
-
},
|
|
748
|
-
perplexity: {
|
|
749
|
-
package: "@langchain/perplexity",
|
|
750
|
-
className: "ChatPerplexity"
|
|
751
|
-
}
|
|
752
|
-
};
|
|
753
|
-
var SUPPORTED_PROVIDERS = Object.keys(MODEL_PROVIDER_CONFIG);
|
|
754
|
-
|
|
755
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/tools/headless.js
|
|
756
|
-
import { tool } from "@langchain/core/tools";
|
|
757
|
-
|
|
758
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/errors.js
|
|
759
|
-
import { isGraphBubbleUp } from "@langchain/langgraph";
|
|
760
|
-
var StructuredOutputParsingError = class extends Error {
|
|
761
|
-
toolName;
|
|
762
|
-
errors;
|
|
763
|
-
constructor(toolName, errors) {
|
|
764
|
-
super(`Failed to parse structured output for tool '${toolName}':${errors.map((e) => `
|
|
765
|
-
- ${e}`).join("")}.`);
|
|
766
|
-
this.toolName = toolName;
|
|
767
|
-
this.errors = errors;
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
|
|
771
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/model.js
|
|
772
|
-
function isBaseChatModel(model) {
|
|
773
|
-
return "invoke" in model && typeof model.invoke === "function" && "_streamResponseChunks" in model;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/responses.js
|
|
777
|
-
import { isInteropZodObject, isInteropZodSchema } from "@langchain/core/utils/types";
|
|
778
|
-
import { Validator, toJsonSchema } from "@langchain/core/utils/json_schema";
|
|
779
|
-
import { isSerializableSchema } from "@langchain/core/utils/standard_schema";
|
|
780
|
-
var PROVIDER_STRATEGY_DEFAULT_STRICT = true;
|
|
781
|
-
var bindingIdentifier = 0;
|
|
782
|
-
var ToolStrategy = class ToolStrategy2 {
|
|
783
|
-
schema;
|
|
784
|
-
tool;
|
|
785
|
-
options;
|
|
786
|
-
constructor(schema, tool4, options) {
|
|
787
|
-
this.schema = schema;
|
|
788
|
-
this.tool = tool4;
|
|
789
|
-
this.options = options;
|
|
790
|
-
}
|
|
791
|
-
get name() {
|
|
792
|
-
return this.tool.function.name;
|
|
793
|
-
}
|
|
794
|
-
static fromSchema(schema, outputOptions) {
|
|
795
|
-
function getFunctionName(name) {
|
|
796
|
-
return name ?? `extract-${++bindingIdentifier}`;
|
|
797
|
-
}
|
|
798
|
-
if (isSerializableSchema(schema) || isInteropZodSchema(schema)) {
|
|
799
|
-
const asJsonSchema2 = toJsonSchema(schema);
|
|
800
|
-
const tool4 = {
|
|
801
|
-
type: "function",
|
|
802
|
-
function: {
|
|
803
|
-
name: getFunctionName(asJsonSchema2.title),
|
|
804
|
-
strict: false,
|
|
805
|
-
description: asJsonSchema2.description ?? "Tool for extracting structured output from the model's response.",
|
|
806
|
-
parameters: asJsonSchema2
|
|
807
|
-
}
|
|
808
|
-
};
|
|
809
|
-
return new ToolStrategy2(asJsonSchema2, tool4, outputOptions);
|
|
810
|
-
}
|
|
811
|
-
let functionDefinition;
|
|
812
|
-
if (typeof schema.name === "string" && typeof schema.parameters === "object" && schema.parameters != null) functionDefinition = schema;
|
|
813
|
-
else functionDefinition = {
|
|
814
|
-
name: getFunctionName(schema.title),
|
|
815
|
-
description: schema.description ?? "",
|
|
816
|
-
parameters: schema.schema || schema
|
|
817
|
-
};
|
|
818
|
-
const asJsonSchema = toJsonSchema(schema);
|
|
819
|
-
return new ToolStrategy2(asJsonSchema, {
|
|
820
|
-
type: "function",
|
|
821
|
-
function: functionDefinition
|
|
822
|
-
}, outputOptions);
|
|
823
|
-
}
|
|
824
|
-
/**
|
|
825
|
-
* Parse tool arguments according to the schema.
|
|
826
|
-
*
|
|
827
|
-
* @throws {StructuredOutputParsingError} if the response is not valid
|
|
828
|
-
* @param toolArgs - The arguments from the tool call
|
|
829
|
-
* @returns The parsed response according to the schema type
|
|
830
|
-
*/
|
|
831
|
-
parse(toolArgs) {
|
|
832
|
-
const result = new Validator(this.schema).validate(toolArgs);
|
|
833
|
-
if (!result.valid) throw new StructuredOutputParsingError(this.name, result.errors.map((e) => e.error));
|
|
834
|
-
return toolArgs;
|
|
835
|
-
}
|
|
836
|
-
};
|
|
837
|
-
var ProviderStrategy = class ProviderStrategy2 {
|
|
838
|
-
_schemaType;
|
|
839
|
-
/**
|
|
840
|
-
* The schema to use for the provider strategy
|
|
841
|
-
*/
|
|
842
|
-
schema;
|
|
843
|
-
/**
|
|
844
|
-
* Whether to use strict mode for the provider strategy
|
|
845
|
-
*/
|
|
846
|
-
strict;
|
|
847
|
-
constructor(schemaOrOptions, strict) {
|
|
848
|
-
if ("schema" in schemaOrOptions && typeof schemaOrOptions.schema === "object" && schemaOrOptions.schema !== null && !("type" in schemaOrOptions)) {
|
|
849
|
-
const options = schemaOrOptions;
|
|
850
|
-
this.schema = options.schema;
|
|
851
|
-
this.strict = options.strict ?? PROVIDER_STRATEGY_DEFAULT_STRICT;
|
|
852
|
-
} else {
|
|
853
|
-
this.schema = schemaOrOptions;
|
|
854
|
-
this.strict = strict ?? PROVIDER_STRATEGY_DEFAULT_STRICT;
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
static fromSchema(schema, strict) {
|
|
858
|
-
const asJsonSchema = toJsonSchema(schema);
|
|
859
|
-
return new ProviderStrategy2(asJsonSchema, strict);
|
|
860
|
-
}
|
|
861
|
-
/**
|
|
862
|
-
* Parse tool arguments according to the schema. If the response is not valid, return undefined.
|
|
863
|
-
*
|
|
864
|
-
* @param response - The AI message response to parse
|
|
865
|
-
* @returns The parsed response according to the schema type
|
|
866
|
-
*/
|
|
867
|
-
parse(response) {
|
|
868
|
-
let textContent;
|
|
869
|
-
if (typeof response.content === "string") textContent = response.content;
|
|
870
|
-
else if (Array.isArray(response.content)) {
|
|
871
|
-
for (const block of response.content) if (typeof block === "object" && block !== null && "type" in block && block.type === "text" && !("thought" in block && block.thought === true) && "text" in block && typeof block.text === "string") {
|
|
872
|
-
textContent = block.text;
|
|
873
|
-
break;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
if (!textContent || textContent === "") return;
|
|
877
|
-
try {
|
|
878
|
-
const content = JSON.parse(textContent);
|
|
879
|
-
if (!new Validator(this.schema).validate(content).valid) return;
|
|
880
|
-
return content;
|
|
881
|
-
} catch {
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
};
|
|
885
|
-
function transformResponseFormat(responseFormat, options, model) {
|
|
886
|
-
if (!responseFormat) return [];
|
|
887
|
-
if (typeof responseFormat === "object" && responseFormat !== null && "__responseFormatUndefined" in responseFormat) return [];
|
|
888
|
-
if (Array.isArray(responseFormat)) {
|
|
889
|
-
if (responseFormat.every((item) => item instanceof ToolStrategy || item instanceof ProviderStrategy)) return responseFormat;
|
|
890
|
-
if (responseFormat.every((item) => isSerializableSchema(item))) return responseFormat.map((item) => ToolStrategy.fromSchema(item, options));
|
|
891
|
-
if (responseFormat.every((item) => isInteropZodObject(item))) return responseFormat.map((item) => ToolStrategy.fromSchema(item, options));
|
|
892
|
-
if (responseFormat.every((item) => typeof item === "object" && item !== null && !isInteropZodObject(item) && !isSerializableSchema(item))) return responseFormat.map((item) => ToolStrategy.fromSchema(item, options));
|
|
893
|
-
throw new Error("Invalid response format: list contains mixed types.\nAll items must be either InteropZodObject, Standard Schema, or plain JSON schema objects.");
|
|
894
|
-
}
|
|
895
|
-
if (responseFormat instanceof ToolStrategy || responseFormat instanceof ProviderStrategy) return [responseFormat];
|
|
896
|
-
const useProviderStrategy = hasSupportForJsonSchemaOutput(model);
|
|
897
|
-
if (isSerializableSchema(responseFormat)) return useProviderStrategy ? [ProviderStrategy.fromSchema(responseFormat)] : [ToolStrategy.fromSchema(responseFormat, options)];
|
|
898
|
-
if (isInteropZodObject(responseFormat)) return useProviderStrategy ? [ProviderStrategy.fromSchema(responseFormat)] : [ToolStrategy.fromSchema(responseFormat, options)];
|
|
899
|
-
if (typeof responseFormat === "object" && responseFormat !== null && "properties" in responseFormat) return useProviderStrategy ? [ProviderStrategy.fromSchema(responseFormat)] : [ToolStrategy.fromSchema(responseFormat, options)];
|
|
900
|
-
throw new Error(`Invalid response format: ${String(responseFormat)}`);
|
|
901
|
-
}
|
|
902
|
-
function toolStrategy(responseFormat, options) {
|
|
903
|
-
return transformResponseFormat(responseFormat, options);
|
|
904
|
-
}
|
|
905
|
-
function hasSupportForJsonSchemaOutput(model) {
|
|
906
|
-
if (!model || !isBaseChatModel(model) || !("profile" in model) || typeof model.profile !== "object" || !model.profile) return false;
|
|
907
|
-
return "structuredOutput" in model.profile && model.profile.structuredOutput === true;
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/utils.js
|
|
911
|
-
import { AIMessage, ToolMessage } from "@langchain/core/messages";
|
|
912
|
-
import { isLangChainTool } from "@langchain/core/tools";
|
|
913
|
-
import { convertToOpenAITool } from "@langchain/core/utils/function_calling";
|
|
914
|
-
|
|
915
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/transformers/tool-call.js
|
|
916
|
-
import { ToolMessage as ToolMessage2 } from "@langchain/core/messages";
|
|
917
|
-
import { StreamChannel } from "@langchain/langgraph";
|
|
918
|
-
|
|
919
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/transformers/subagent.js
|
|
920
|
-
import { StreamChannel as StreamChannel2, createMessagesTransformer } from "@langchain/langgraph";
|
|
921
|
-
|
|
922
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/types.js
|
|
923
|
-
var MIDDLEWARE_BRAND = /* @__PURE__ */ Symbol.for("AgentMiddleware");
|
|
924
|
-
|
|
925
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware.js
|
|
926
|
-
function createMiddleware(config) {
|
|
927
|
-
return {
|
|
928
|
-
[MIDDLEWARE_BRAND]: true,
|
|
929
|
-
name: config.name,
|
|
930
|
-
stateSchema: config.stateSchema,
|
|
931
|
-
contextSchema: config.contextSchema,
|
|
932
|
-
wrapToolCall: config.wrapToolCall,
|
|
933
|
-
wrapModelCall: config.wrapModelCall,
|
|
934
|
-
beforeAgent: config.beforeAgent,
|
|
935
|
-
beforeModel: config.beforeModel,
|
|
936
|
-
afterModel: config.afterModel,
|
|
937
|
-
afterAgent: config.afterAgent,
|
|
938
|
-
tools: config.tools,
|
|
939
|
-
streamTransformers: config.streamTransformers
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/tests/utils.js
|
|
944
|
-
import { AIMessage as AIMessage2, HumanMessage } from "@langchain/core/messages";
|
|
945
|
-
import { BaseChatModel as BaseChatModel2 } from "@langchain/core/language_models/chat_models";
|
|
946
|
-
import { RunnableLambda } from "@langchain/core/runnables";
|
|
947
|
-
import "@langchain/core/tools";
|
|
948
|
-
|
|
949
|
-
// ../../node_modules/.pnpm/@langchain+langgraph-checkpoint@1.1.5_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@_ff898d037cda6bb5f88aa9c9d1caaf93/node_modules/@langchain/langgraph-checkpoint/dist/id.js
|
|
950
|
-
import { v5, v6 } from "@langchain/core/utils/uuid";
|
|
951
|
-
|
|
952
|
-
// ../../node_modules/.pnpm/@langchain+langgraph-checkpoint@1.1.5_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@_ff898d037cda6bb5f88aa9c9d1caaf93/node_modules/@langchain/langgraph-checkpoint/dist/serde/types.js
|
|
953
|
-
var ERROR = "__error__";
|
|
954
|
-
var SCHEDULED = "__scheduled__";
|
|
955
|
-
var INTERRUPT = "__interrupt__";
|
|
956
|
-
var RESUME = "__resume__";
|
|
957
|
-
|
|
958
|
-
// ../../node_modules/.pnpm/@langchain+langgraph-checkpoint@1.1.5_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@_ff898d037cda6bb5f88aa9c9d1caaf93/node_modules/@langchain/langgraph-checkpoint/dist/serde/jsonplus.js
|
|
959
|
-
import { load } from "@langchain/core/load";
|
|
960
|
-
|
|
961
|
-
// ../../node_modules/.pnpm/@langchain+langgraph-checkpoint@1.1.5_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@_ff898d037cda6bb5f88aa9c9d1caaf93/node_modules/@langchain/langgraph-checkpoint/dist/base.js
|
|
962
|
-
var WRITES_IDX_MAP = {
|
|
963
|
-
[ERROR]: -1,
|
|
964
|
-
[SCHEDULED]: -2,
|
|
965
|
-
[INTERRUPT]: -3,
|
|
966
|
-
[RESUME]: -4
|
|
967
|
-
};
|
|
968
|
-
|
|
969
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/tests/utils.js
|
|
970
|
-
import "zod/v3";
|
|
971
|
-
|
|
972
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/annotation.js
|
|
973
|
-
import { MessagesValue, ReducedValue, StateSchema, UntrackedValue } from "@langchain/langgraph";
|
|
974
|
-
import { schemaMetaRegistry } from "@langchain/langgraph/zod";
|
|
975
|
-
import { getInteropZodObjectShape, isInteropZodObject as isInteropZodObject2, isZodSchemaV4 } from "@langchain/core/utils/types";
|
|
976
|
-
|
|
977
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/utils.js
|
|
978
|
-
import { AIMessage as AIMessage3, AIMessageChunk, SystemMessage, ToolMessage as ToolMessage3 } from "@langchain/core/messages";
|
|
979
|
-
import { Runnable, RunnableBinding as RunnableBinding2, RunnableSequence } from "@langchain/core/runnables";
|
|
980
|
-
import { StateSchema as StateSchema2, isCommand } from "@langchain/langgraph";
|
|
981
|
-
import { interopParse, isInteropZodSchema as isInteropZodSchema2 } from "@langchain/core/utils/types";
|
|
982
|
-
|
|
983
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/nodes/utils.js
|
|
984
|
-
import { END, ReducedValue as ReducedValue2, StateSchema as StateSchema3 } from "@langchain/langgraph";
|
|
985
|
-
import { getInteropZodObjectShape as getInteropZodObjectShape2, interopSafeParseAsync, interopZodObjectMakeFieldsOptional, interopZodObjectPartial, isInteropZodObject as isInteropZodObject3, isZodSchemaV4 as isZodSchemaV42 } from "@langchain/core/utils/types";
|
|
986
|
-
import { z } from "zod/v4";
|
|
987
|
-
|
|
988
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/RunnableCallable.js
|
|
989
|
-
import { Runnable as Runnable2, mergeConfigs } from "@langchain/core/runnables";
|
|
990
|
-
import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
|
|
991
|
-
|
|
992
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/withAgentName.js
|
|
993
|
-
import { RunnableLambda as RunnableLambda2, RunnableSequence as RunnableSequence2 } from "@langchain/core/runnables";
|
|
994
|
-
|
|
995
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/nodes/AgentNode.js
|
|
996
|
-
import { AIMessage as AIMessage4, SystemMessage as SystemMessage2, ToolMessage as ToolMessage4 } from "@langchain/core/messages";
|
|
997
|
-
import { raceWithSignal } from "@langchain/core/runnables";
|
|
998
|
-
import { Command, isCommand as isCommand2 } from "@langchain/langgraph";
|
|
999
|
-
import { getSchemaDescription, interopParse as interopParse2 } from "@langchain/core/utils/types";
|
|
1000
|
-
|
|
1001
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/nodes/ToolNode.js
|
|
1002
|
-
import { AIMessage as AIMessage5, BaseMessage, ToolMessage as ToolMessage5 } from "@langchain/core/messages";
|
|
1003
|
-
import { ToolInputParsingException } from "@langchain/core/tools";
|
|
1004
|
-
import { Command as Command2, Send, isCommand as isCommand3, isGraphInterrupt } from "@langchain/langgraph";
|
|
1005
|
-
|
|
1006
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/nodes/middleware.js
|
|
1007
|
-
import { getInteropZodObjectShape as getInteropZodObjectShape3, interopParse as interopParse3, isInteropZodObject as isInteropZodObject4 } from "@langchain/core/utils/types";
|
|
1008
|
-
|
|
1009
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/ReactAgent.js
|
|
1010
|
-
import { AIMessage as AIMessage6, ToolMessage as ToolMessage6 } from "@langchain/core/messages";
|
|
1011
|
-
import { mergeConfigs as mergeConfigs2 } from "@langchain/core/runnables";
|
|
1012
|
-
import { Command as Command3, END as END2, START, Send as Send2, StateGraph } from "@langchain/langgraph";
|
|
1013
|
-
|
|
1014
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/hitl.js
|
|
1015
|
-
import { AIMessage as AIMessage7, ToolMessage as ToolMessage7 } from "@langchain/core/messages";
|
|
1016
|
-
import { interrupt } from "@langchain/langgraph";
|
|
1017
|
-
import { interopParse as interopParse4 } from "@langchain/core/utils/types";
|
|
1018
|
-
import { z as z2 } from "zod/v3";
|
|
1019
|
-
var WhenFunctionSchema = z2.function().args(z2.custom()).returns(z2.union([z2.boolean(), z2.promise(z2.boolean())]));
|
|
1020
|
-
var DescriptionFunctionSchema = z2.function().args(z2.custom(), z2.custom(), z2.custom()).returns(z2.union([z2.string(), z2.promise(z2.string())]));
|
|
1021
|
-
var ALLOWED_DECISIONS = [
|
|
1022
|
-
"approve",
|
|
1023
|
-
"edit",
|
|
1024
|
-
"reject"
|
|
1025
|
-
];
|
|
1026
|
-
var DecisionType = z2.enum(ALLOWED_DECISIONS);
|
|
1027
|
-
var InterruptOnConfigSchema = z2.object({
|
|
1028
|
-
/**
|
|
1029
|
-
* The decisions that are allowed for this action.
|
|
1030
|
-
*/
|
|
1031
|
-
allowedDecisions: z2.array(DecisionType),
|
|
1032
|
-
/**
|
|
1033
|
-
* The description attached to the request for human input.
|
|
1034
|
-
* Can be either:
|
|
1035
|
-
* - A static string describing the approval request
|
|
1036
|
-
* - A callable that dynamically generates the description based on agent state,
|
|
1037
|
-
* runtime, and tool call information
|
|
1038
|
-
*
|
|
1039
|
-
* @example
|
|
1040
|
-
* Static string description
|
|
1041
|
-
* ```typescript
|
|
1042
|
-
* import type { InterruptOnConfig } from "langchain";
|
|
1043
|
-
*
|
|
1044
|
-
* const config: InterruptOnConfig = {
|
|
1045
|
-
* allowedDecisions: ["approve", "reject"],
|
|
1046
|
-
* description: "Please review this tool execution"
|
|
1047
|
-
* };
|
|
1048
|
-
* ```
|
|
1049
|
-
*
|
|
1050
|
-
* @example
|
|
1051
|
-
* Dynamic callable description
|
|
1052
|
-
* ```typescript
|
|
1053
|
-
* import type {
|
|
1054
|
-
* AgentBuiltInState,
|
|
1055
|
-
* Runtime,
|
|
1056
|
-
* DescriptionFactory,
|
|
1057
|
-
* ToolCall,
|
|
1058
|
-
* InterruptOnConfig
|
|
1059
|
-
* } from "langchain";
|
|
1060
|
-
*
|
|
1061
|
-
* const formatToolDescription: DescriptionFactory = (
|
|
1062
|
-
* toolCall: ToolCall,
|
|
1063
|
-
* state: AgentBuiltInState,
|
|
1064
|
-
* runtime: Runtime<unknown>
|
|
1065
|
-
* ) => {
|
|
1066
|
-
* return `Tool: ${toolCall.name}\nArguments:\n${JSON.stringify(toolCall.args, null, 2)}`;
|
|
1067
|
-
* };
|
|
1068
|
-
*
|
|
1069
|
-
* const config: InterruptOnConfig = {
|
|
1070
|
-
* allowedDecisions: ["approve", "edit"],
|
|
1071
|
-
* description: formatToolDescription
|
|
1072
|
-
* };
|
|
1073
|
-
* ```
|
|
1074
|
-
*/
|
|
1075
|
-
description: z2.union([z2.string(), DescriptionFunctionSchema]).optional(),
|
|
1076
|
-
/**
|
|
1077
|
-
* JSON schema for the arguments associated with the action, if edits are allowed.
|
|
1078
|
-
*/
|
|
1079
|
-
argsSchema: z2.record(z2.any()).optional(),
|
|
1080
|
-
/**
|
|
1081
|
-
* Optional predicate controlling whether to interrupt for a given tool call.
|
|
1082
|
-
*
|
|
1083
|
-
* Receives a {@link ToolCallRequest} and returns `true` to interrupt or
|
|
1084
|
-
* `false` to auto-approve the tool call.
|
|
1085
|
-
*
|
|
1086
|
-
* The request is constructed with `tool` set to `undefined` and `runtime` set
|
|
1087
|
-
* to the node-level {@link Runtime}, so `request.tool` is not available.
|
|
1088
|
-
*
|
|
1089
|
-
* @example
|
|
1090
|
-
* ```typescript
|
|
1091
|
-
* import type { InterruptOnConfig } from "langchain";
|
|
1092
|
-
*
|
|
1093
|
-
* // Only interrupt delete_file calls targeting /etc
|
|
1094
|
-
* const config: InterruptOnConfig = {
|
|
1095
|
-
* allowedDecisions: ["approve", "reject"],
|
|
1096
|
-
* when: (request) =>
|
|
1097
|
-
* String(request.toolCall.args.path ?? "").startsWith("/etc"),
|
|
1098
|
-
* };
|
|
1099
|
-
* ```
|
|
1100
|
-
*/
|
|
1101
|
-
when: WhenFunctionSchema.optional()
|
|
1102
|
-
});
|
|
1103
|
-
var contextSchema = z2.object({
|
|
1104
|
-
/**
|
|
1105
|
-
* Mapping of tool name to allowed reviewer responses.
|
|
1106
|
-
* If a tool doesn't have an entry, it's auto-approved by default.
|
|
1107
|
-
*
|
|
1108
|
-
* - `true` -> pause for approval and allow approve/edit/reject decisions
|
|
1109
|
-
* - `false` -> auto-approve (no human review)
|
|
1110
|
-
* - `InterruptOnConfig` -> explicitly specify which decisions are allowed for this tool
|
|
1111
|
-
*/
|
|
1112
|
-
interruptOn: z2.record(z2.union([z2.boolean(), InterruptOnConfigSchema])).optional(),
|
|
1113
|
-
/**
|
|
1114
|
-
* Prefix used when constructing human-facing approval messages.
|
|
1115
|
-
* Provides context about the tool call being reviewed; does not change the underlying action.
|
|
1116
|
-
*
|
|
1117
|
-
* Note: This prefix is only applied for tools that do not provide a custom
|
|
1118
|
-
* `description` via their {@link InterruptOnConfig}. If a tool specifies a custom
|
|
1119
|
-
* `description`, that per-tool text is used and this prefix is ignored.
|
|
1120
|
-
*/
|
|
1121
|
-
descriptionPrefix: z2.string().default("Tool execution requires approval")
|
|
1122
|
-
});
|
|
1123
|
-
|
|
1124
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/constants.js
|
|
1125
|
-
import { z as z3 } from "zod/v3";
|
|
1126
|
-
import { getRetryable } from "@langchain/core/errors";
|
|
1127
|
-
var RetrySchema = z3.object({
|
|
1128
|
-
/**
|
|
1129
|
-
* Maximum number of retry attempts after the initial call.
|
|
1130
|
-
* Default is 2 retries (3 total attempts). Must be >= 0.
|
|
1131
|
-
*/
|
|
1132
|
-
maxRetries: z3.number().min(0).default(2),
|
|
1133
|
-
/**
|
|
1134
|
-
* Either an array of error constructors to retry on, or a function
|
|
1135
|
-
* that takes an error and returns `true` if it should be retried.
|
|
1136
|
-
* Default is to retry unless the error is marked non-retryable.
|
|
1137
|
-
*/
|
|
1138
|
-
retryOn: z3.union([z3.function().args(z3.instanceof(Error)).returns(z3.boolean()), z3.array(z3.custom())]).default(() => (error) => getRetryable(error) ?? true),
|
|
1139
|
-
/**
|
|
1140
|
-
* Multiplier for exponential backoff. Each retry waits
|
|
1141
|
-
* `initialDelayMs * (backoffFactor ** retryNumber)` milliseconds.
|
|
1142
|
-
* Set to 0.0 for constant delay. Default is 2.0.
|
|
1143
|
-
*/
|
|
1144
|
-
backoffFactor: z3.number().min(0).default(2),
|
|
1145
|
-
/**
|
|
1146
|
-
* Initial delay in milliseconds before first retry. Default is 1000 (1 second).
|
|
1147
|
-
*/
|
|
1148
|
-
initialDelayMs: z3.number().min(0).default(1e3),
|
|
1149
|
-
/**
|
|
1150
|
-
* Maximum delay in milliseconds between retries. Caps exponential
|
|
1151
|
-
* backoff growth. Default is 60000 (60 seconds).
|
|
1152
|
-
*/
|
|
1153
|
-
maxDelayMs: z3.number().min(0).default(6e4),
|
|
1154
|
-
/**
|
|
1155
|
-
* Whether to add random jitter (±25%) to delay to avoid thundering herd.
|
|
1156
|
-
* Default is `true`.
|
|
1157
|
-
*/
|
|
1158
|
-
jitter: z3.boolean().default(true)
|
|
1159
|
-
});
|
|
1160
|
-
|
|
1161
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/summarization.js
|
|
1162
|
-
import { AIMessage as AIMessage8, HumanMessage as HumanMessage2, RemoveMessage, SystemMessage as SystemMessage3, ToolMessage as ToolMessage8, getBufferString, trimMessages } from "@langchain/core/messages";
|
|
1163
|
-
import { mergeConfigs as mergeConfigs3, pickRunnableConfigKeys } from "@langchain/core/runnables";
|
|
1164
|
-
import { REMOVE_ALL_MESSAGES } from "@langchain/langgraph";
|
|
1165
|
-
import { interopSafeParse } from "@langchain/core/utils/types";
|
|
1166
|
-
import { z as z4 } from "zod/v4";
|
|
1167
|
-
import { z as z$1 } from "zod/v3";
|
|
1168
|
-
import { v4 } from "@langchain/core/utils/uuid";
|
|
1169
|
-
import { getModelContextSize } from "@langchain/core/language_models/base";
|
|
1170
|
-
var DEFAULT_SUMMARY_PROMPT = `<role>
|
|
1171
|
-
Context Extraction Assistant
|
|
1172
|
-
</role>
|
|
1173
|
-
|
|
1174
|
-
<primary_objective>
|
|
1175
|
-
Your sole objective in this task is to extract the highest quality/most relevant context from the conversation history below.
|
|
1176
|
-
</primary_objective>
|
|
1177
|
-
|
|
1178
|
-
<objective_information>
|
|
1179
|
-
You're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history.
|
|
1180
|
-
This context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to your overall goal.
|
|
1181
|
-
</objective_information>
|
|
1182
|
-
|
|
1183
|
-
<instructions>
|
|
1184
|
-
The conversation history below will be replaced with the context you extract in this step. Because of this, you must do your very best to extract and record all of the most important context from the conversation history.
|
|
1185
|
-
You want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal.
|
|
1186
|
-
</instructions>
|
|
1187
|
-
|
|
1188
|
-
The user will message you with the full message history you'll be extracting context from, to then replace. Carefully read over it all, and think deeply about what information is most important to your overall goal that should be saved:
|
|
1189
|
-
|
|
1190
|
-
With all of this in mind, please carefully read over the entire conversation history, and extract the most important and relevant context to replace it so that you can free up space in the conversation history.
|
|
1191
|
-
Respond ONLY with the extracted context. Do not include any additional information, or text before or after the extracted context.
|
|
1192
|
-
|
|
1193
|
-
<messages>
|
|
1194
|
-
Messages to summarize:
|
|
1195
|
-
{messages}
|
|
1196
|
-
</messages>`;
|
|
1197
|
-
var tokenCounterSchema = z$1.function().args(z$1.array(z$1.custom())).returns(z$1.union([z$1.number(), z$1.promise(z$1.number())]));
|
|
1198
|
-
var contextSizeSchema = z$1.object({
|
|
1199
|
-
/**
|
|
1200
|
-
* Fraction of the model's context size to use as the trigger
|
|
1201
|
-
*/
|
|
1202
|
-
fraction: z$1.number().gt(0, "Fraction must be greater than 0").max(1, "Fraction must be less than or equal to 1").optional(),
|
|
1203
|
-
/**
|
|
1204
|
-
* Number of tokens to use as the trigger
|
|
1205
|
-
*/
|
|
1206
|
-
tokens: z$1.number().positive("Tokens must be greater than 0").optional(),
|
|
1207
|
-
/**
|
|
1208
|
-
* Number of messages to use as the trigger
|
|
1209
|
-
*/
|
|
1210
|
-
messages: z$1.number().int("Messages must be an integer").positive("Messages must be greater than 0").optional()
|
|
1211
|
-
}).refine((data) => {
|
|
1212
|
-
return [
|
|
1213
|
-
data.fraction,
|
|
1214
|
-
data.tokens,
|
|
1215
|
-
data.messages
|
|
1216
|
-
].filter((v) => v !== void 0).length >= 1;
|
|
1217
|
-
}, { message: "At least one of fraction, tokens, or messages must be provided" });
|
|
1218
|
-
var keepSchema = z$1.object({
|
|
1219
|
-
/**
|
|
1220
|
-
* Fraction of the model's context size to keep
|
|
1221
|
-
*/
|
|
1222
|
-
fraction: z$1.number().min(0, "Messages must be non-negative").max(1, "Fraction must be less than or equal to 1").optional(),
|
|
1223
|
-
/**
|
|
1224
|
-
* Number of tokens to keep
|
|
1225
|
-
*/
|
|
1226
|
-
tokens: z$1.number().min(0, "Tokens must be greater than or equal to 0").optional(),
|
|
1227
|
-
messages: z$1.number().int("Messages must be an integer").min(0, "Messages must be non-negative").optional()
|
|
1228
|
-
}).refine((data) => {
|
|
1229
|
-
return [
|
|
1230
|
-
data.fraction,
|
|
1231
|
-
data.tokens,
|
|
1232
|
-
data.messages
|
|
1233
|
-
].filter((v) => v !== void 0).length === 1;
|
|
1234
|
-
}, { message: "Exactly one of fraction, tokens, or messages must be provided" });
|
|
1235
|
-
var contextSchema2 = z$1.object({
|
|
1236
|
-
/**
|
|
1237
|
-
* Model to use for summarization
|
|
1238
|
-
*/
|
|
1239
|
-
model: z$1.custom(),
|
|
1240
|
-
/**
|
|
1241
|
-
* Trigger conditions for summarization.
|
|
1242
|
-
* Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).
|
|
1243
|
-
*
|
|
1244
|
-
* @example
|
|
1245
|
-
* ```ts
|
|
1246
|
-
* // Single condition: trigger if tokens >= 5000 AND messages >= 3
|
|
1247
|
-
* trigger: { tokens: 5000, messages: 3 }
|
|
1248
|
-
*
|
|
1249
|
-
* // Multiple conditions: trigger if (tokens >= 5000 AND messages >= 3) OR (tokens >= 3000 AND messages >= 6)
|
|
1250
|
-
* trigger: [
|
|
1251
|
-
* { tokens: 5000, messages: 3 },
|
|
1252
|
-
* { tokens: 3000, messages: 6 }
|
|
1253
|
-
* ]
|
|
1254
|
-
* ```
|
|
1255
|
-
*/
|
|
1256
|
-
trigger: z$1.union([contextSizeSchema, z$1.array(contextSizeSchema)]).optional(),
|
|
1257
|
-
/**
|
|
1258
|
-
* Keep conditions for summarization
|
|
1259
|
-
*/
|
|
1260
|
-
keep: keepSchema.optional(),
|
|
1261
|
-
/**
|
|
1262
|
-
* Token counter function to use for summarization
|
|
1263
|
-
*/
|
|
1264
|
-
tokenCounter: tokenCounterSchema.optional(),
|
|
1265
|
-
/**
|
|
1266
|
-
* Summary prompt to use for summarization
|
|
1267
|
-
* @default {@link DEFAULT_SUMMARY_PROMPT}
|
|
1268
|
-
*/
|
|
1269
|
-
summaryPrompt: z$1.string().default(DEFAULT_SUMMARY_PROMPT),
|
|
1270
|
-
/**
|
|
1271
|
-
* Number of tokens to trim to before summarizing
|
|
1272
|
-
*/
|
|
1273
|
-
trimTokensToSummarize: z$1.number().optional(),
|
|
1274
|
-
/**
|
|
1275
|
-
* Prefix to add to the summary
|
|
1276
|
-
*/
|
|
1277
|
-
summaryPrefix: z$1.string().optional(),
|
|
1278
|
-
/**
|
|
1279
|
-
* @deprecated Use `trigger: { tokens: value }` instead.
|
|
1280
|
-
*/
|
|
1281
|
-
maxTokensBeforeSummary: z$1.number().optional(),
|
|
1282
|
-
/**
|
|
1283
|
-
* @deprecated Use `keep: { messages: value }` instead.
|
|
1284
|
-
*/
|
|
1285
|
-
messagesToKeep: z$1.number().optional()
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/dynamicSystemPrompt.js
|
|
1289
|
-
import { SystemMessage as SystemMessage4 } from "@langchain/core/messages";
|
|
1290
|
-
|
|
1291
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/llmToolSelector.js
|
|
1292
|
-
import { HumanMessage as HumanMessage3 } from "@langchain/core/messages";
|
|
1293
|
-
import { mergeConfigs as mergeConfigs4, pickRunnableConfigKeys as pickRunnableConfigKeys2 } from "@langchain/core/runnables";
|
|
1294
|
-
import { z as z5 } from "zod/v3";
|
|
1295
|
-
import { BaseLanguageModel } from "@langchain/core/language_models/base";
|
|
1296
|
-
var LLMToolSelectorOptionsSchema = z5.object({
|
|
1297
|
-
/**
|
|
1298
|
-
* The language model to use for tool selection (default: the provided model from the agent options).
|
|
1299
|
-
*/
|
|
1300
|
-
model: z5.string().or(z5.instanceof(BaseLanguageModel)).optional(),
|
|
1301
|
-
/**
|
|
1302
|
-
* System prompt for the tool selection model.
|
|
1303
|
-
*/
|
|
1304
|
-
systemPrompt: z5.string().optional(),
|
|
1305
|
-
/**
|
|
1306
|
-
* Maximum number of tools to select. If the model selects more,
|
|
1307
|
-
* only the first maxTools will be used. No limit if not specified.
|
|
1308
|
-
*/
|
|
1309
|
-
maxTools: z5.number().optional(),
|
|
1310
|
-
/**
|
|
1311
|
-
* Tool names to always include regardless of selection.
|
|
1312
|
-
* These do not count against the maxTools limit.
|
|
1313
|
-
*/
|
|
1314
|
-
alwaysInclude: z5.array(z5.string()).optional()
|
|
1315
|
-
});
|
|
1316
|
-
|
|
1317
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/pii.js
|
|
1318
|
-
import { AIMessage as AIMessage9, HumanMessage as HumanMessage4, ToolMessage as ToolMessage9 } from "@langchain/core/messages";
|
|
1319
|
-
import { z as z6 } from "zod/v3";
|
|
1320
|
-
import { sha256 } from "@langchain/core/utils/hash";
|
|
1321
|
-
var contextSchema3 = z6.object({
|
|
1322
|
-
/**
|
|
1323
|
-
* Whether to check user messages before model call
|
|
1324
|
-
*/
|
|
1325
|
-
applyToInput: z6.boolean().optional(),
|
|
1326
|
-
/**
|
|
1327
|
-
* Whether to check AI messages after model call
|
|
1328
|
-
*/
|
|
1329
|
-
applyToOutput: z6.boolean().optional(),
|
|
1330
|
-
/**
|
|
1331
|
-
* Whether to check tool result messages after tool execution
|
|
1332
|
-
*/
|
|
1333
|
-
applyToToolResults: z6.boolean().optional()
|
|
1334
|
-
});
|
|
1335
|
-
|
|
1336
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/piiRedaction.js
|
|
1337
|
-
import { AIMessage as AIMessage10, HumanMessage as HumanMessage5, RemoveMessage as RemoveMessage2, SystemMessage as SystemMessage5, ToolMessage as ToolMessage10 } from "@langchain/core/messages";
|
|
1338
|
-
import { z as z7 } from "zod/v3";
|
|
1339
|
-
var contextSchema4 = z7.object({
|
|
1340
|
-
/**
|
|
1341
|
-
* A record of PII detection rules to apply
|
|
1342
|
-
* @default DEFAULT_PII_RULES (with enabled rules only)
|
|
1343
|
-
*/
|
|
1344
|
-
rules: z7.record(z7.string(), z7.instanceof(RegExp).describe("Regular expression pattern to match PII")).optional()
|
|
1345
|
-
});
|
|
1346
|
-
|
|
1347
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/contextEditing.js
|
|
1348
|
-
import { AIMessage as AIMessage11, SystemMessage as SystemMessage6, ToolMessage as ToolMessage11 } from "@langchain/core/messages";
|
|
1349
|
-
|
|
1350
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/toolCallLimit.js
|
|
1351
|
-
import { AIMessage as AIMessage12, ToolMessage as ToolMessage12 } from "@langchain/core/messages";
|
|
1352
|
-
import { z as z8 } from "zod/v4";
|
|
1353
|
-
import { z as z$12 } from "zod/v3";
|
|
1354
|
-
var VALID_EXIT_BEHAVIORS = [
|
|
1355
|
-
"continue",
|
|
1356
|
-
"error",
|
|
1357
|
-
"end"
|
|
1358
|
-
];
|
|
1359
|
-
var DEFAULT_EXIT_BEHAVIOR = "continue";
|
|
1360
|
-
var exitBehaviorSchema = z$12.enum(VALID_EXIT_BEHAVIORS).default(DEFAULT_EXIT_BEHAVIOR);
|
|
1361
|
-
z$12.object({
|
|
1362
|
-
/**
|
|
1363
|
-
* Name of the specific tool to limit. If undefined, limits apply to all tools.
|
|
1364
|
-
*/
|
|
1365
|
-
toolName: z$12.string().optional(),
|
|
1366
|
-
/**
|
|
1367
|
-
* Maximum number of tool calls allowed per thread.
|
|
1368
|
-
* undefined means no limit.
|
|
1369
|
-
*/
|
|
1370
|
-
threadLimit: z$12.number().optional(),
|
|
1371
|
-
/**
|
|
1372
|
-
* Maximum number of tool calls allowed per run.
|
|
1373
|
-
* undefined means no limit.
|
|
1374
|
-
*/
|
|
1375
|
-
runLimit: z$12.number().optional(),
|
|
1376
|
-
/**
|
|
1377
|
-
* What to do when limits are exceeded.
|
|
1378
|
-
* - "continue": Block exceeded tools with error messages, let other tools continue (default)
|
|
1379
|
-
* - "error": Raise a ToolCallLimitExceededError exception
|
|
1380
|
-
* - "end": Stop execution immediately, injecting a ToolMessage and an AI message
|
|
1381
|
-
* for the single tool call that exceeded the limit. Raises NotImplementedError
|
|
1382
|
-
* if there are multiple tool calls.
|
|
1383
|
-
*
|
|
1384
|
-
* @default "continue"
|
|
1385
|
-
*/
|
|
1386
|
-
exitBehavior: exitBehaviorSchema
|
|
1387
|
-
});
|
|
1388
|
-
var stateSchema = z$12.object({
|
|
1389
|
-
threadToolCallCount: z$12.record(z$12.string(), z$12.number()).default({}),
|
|
1390
|
-
runToolCallCount: z$12.record(z$12.string(), z$12.number()).default({})
|
|
1391
|
-
});
|
|
1392
|
-
|
|
1393
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/todoListMiddleware.js
|
|
1394
|
-
import { AIMessage as AIMessage13, ToolMessage as ToolMessage13 } from "@langchain/core/messages";
|
|
1395
|
-
import { tool as tool2 } from "@langchain/core/tools";
|
|
1396
|
-
import { Command as Command4 } from "@langchain/langgraph";
|
|
1397
|
-
import { z as z9 } from "zod/v3";
|
|
1398
|
-
var TodoStatus = z9.enum([
|
|
1399
|
-
"pending",
|
|
1400
|
-
"in_progress",
|
|
1401
|
-
"completed"
|
|
1402
|
-
]).describe("Status of the todo");
|
|
1403
|
-
var TodoSchema = z9.object({
|
|
1404
|
-
content: z9.string().describe("Content of the todo item"),
|
|
1405
|
-
status: TodoStatus
|
|
1406
|
-
});
|
|
1407
|
-
var stateSchema2 = z9.object({ todos: z9.array(TodoSchema).default([]) });
|
|
1408
|
-
|
|
1409
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/modelCallLimit.js
|
|
1410
|
-
import { AIMessage as AIMessage14 } from "@langchain/core/messages";
|
|
1411
|
-
import { z as z10 } from "zod/v3";
|
|
1412
|
-
var contextSchema5 = z10.object({
|
|
1413
|
-
/**
|
|
1414
|
-
* The maximum number of model calls allowed per thread.
|
|
1415
|
-
*/
|
|
1416
|
-
threadLimit: z10.number().optional(),
|
|
1417
|
-
/**
|
|
1418
|
-
* The maximum number of model calls allowed per run.
|
|
1419
|
-
*/
|
|
1420
|
-
runLimit: z10.number().optional(),
|
|
1421
|
-
/**
|
|
1422
|
-
* The behavior to take when the limit is exceeded.
|
|
1423
|
-
* - "error" will throw an error and stop the agent.
|
|
1424
|
-
* - "end" will end the agent.
|
|
1425
|
-
* @default "end"
|
|
1426
|
-
*/
|
|
1427
|
-
exitBehavior: z10.enum(["error", "end"]).optional()
|
|
1428
|
-
});
|
|
1429
|
-
var stateSchema3 = z10.object({
|
|
1430
|
-
threadModelCallCount: z10.number().default(0),
|
|
1431
|
-
runModelCallCount: z10.number().default(0)
|
|
1432
|
-
});
|
|
1433
|
-
|
|
1434
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/error.js
|
|
1435
|
-
import { z as z11 } from "zod/v4";
|
|
1436
|
-
|
|
1437
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/modelRetry.js
|
|
1438
|
-
import { AIMessage as AIMessage15 } from "@langchain/core/messages";
|
|
1439
|
-
import { z as z12 } from "zod/v3";
|
|
1440
|
-
var ModelRetryMiddlewareOptionsSchema = z12.object({
|
|
1441
|
-
/**
|
|
1442
|
-
* Behavior when all retries are exhausted. Options:
|
|
1443
|
-
* - `"continue"` (default): Return an AIMessage with error details, allowing
|
|
1444
|
-
* the agent to potentially handle the failure gracefully.
|
|
1445
|
-
* - `"error"`: Re-raise the exception, stopping agent execution.
|
|
1446
|
-
* - Custom function: Function that takes the exception and returns a string
|
|
1447
|
-
* for the AIMessage content, allowing custom error formatting.
|
|
1448
|
-
*/
|
|
1449
|
-
onFailure: z12.union([
|
|
1450
|
-
z12.literal("error"),
|
|
1451
|
-
z12.literal("continue"),
|
|
1452
|
-
z12.function().args(z12.instanceof(Error)).returns(z12.string())
|
|
1453
|
-
]).default("continue")
|
|
1454
|
-
}).merge(RetrySchema);
|
|
1455
|
-
|
|
1456
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/toolRetry.js
|
|
1457
|
-
import { ToolMessage as ToolMessage14 } from "@langchain/core/messages";
|
|
1458
|
-
import { z as z13 } from "zod/v3";
|
|
1459
|
-
var ToolRetryMiddlewareOptionsSchema = z13.object({
|
|
1460
|
-
/**
|
|
1461
|
-
* Optional list of tools or tool names to apply retry logic to.
|
|
1462
|
-
* Can be a list of `BaseTool` instances or tool name strings.
|
|
1463
|
-
* If `undefined`, applies to all tools. Default is `undefined`.
|
|
1464
|
-
*/
|
|
1465
|
-
tools: z13.array(z13.union([
|
|
1466
|
-
z13.custom(),
|
|
1467
|
-
z13.custom(),
|
|
1468
|
-
z13.string()
|
|
1469
|
-
])).optional(),
|
|
1470
|
-
/**
|
|
1471
|
-
* Behavior when all retries are exhausted. Options:
|
|
1472
|
-
* - `"continue"` (default): Return an AIMessage with error details, allowing
|
|
1473
|
-
* the agent to potentially handle the failure gracefully.
|
|
1474
|
-
* - `"error"`: Re-raise the exception, stopping agent execution.
|
|
1475
|
-
* - Custom function: Function that takes the exception and returns a string
|
|
1476
|
-
* for the AIMessage content, allowing custom error formatting.
|
|
1477
|
-
*
|
|
1478
|
-
* Deprecated values:
|
|
1479
|
-
* - `"raise"`: use `"error"` instead.
|
|
1480
|
-
* - `"return_message"`: use `"continue"` instead.
|
|
1481
|
-
*/
|
|
1482
|
-
onFailure: z13.union([
|
|
1483
|
-
z13.literal("error"),
|
|
1484
|
-
z13.literal("continue"),
|
|
1485
|
-
z13.literal("raise"),
|
|
1486
|
-
z13.literal("return_message"),
|
|
1487
|
-
z13.function().args(z13.instanceof(Error)).returns(z13.string())
|
|
1488
|
-
]).default("continue")
|
|
1489
|
-
}).merge(RetrySchema);
|
|
1490
|
-
|
|
1491
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/toolError.js
|
|
1492
|
-
import { ToolMessage as ToolMessage15 } from "@langchain/core/messages";
|
|
1493
|
-
import { isGraphBubbleUp as isGraphBubbleUp2 } from "@langchain/langgraph";
|
|
1494
|
-
|
|
1495
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/toolEmulator.js
|
|
1496
|
-
import { HumanMessage as HumanMessage6, ToolMessage as ToolMessage16 } from "@langchain/core/messages";
|
|
1497
|
-
import { mergeConfigs as mergeConfigs5, pickRunnableConfigKeys as pickRunnableConfigKeys3 } from "@langchain/core/runnables";
|
|
1498
|
-
|
|
1499
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/providerToolSearch.js
|
|
1500
|
-
import { isLangChainTool as isLangChainTool2 } from "@langchain/core/utils/function_calling";
|
|
1501
|
-
|
|
1502
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/provider/openai/moderation.js
|
|
1503
|
-
import { AIMessage as AIMessage16, HumanMessage as HumanMessage7, ToolMessage as ToolMessage17 } from "@langchain/core/messages";
|
|
1504
|
-
|
|
1505
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/provider/anthropic/promptCaching.js
|
|
1506
|
-
import { z as z14 } from "zod/v3";
|
|
1507
|
-
var contextSchema6 = z14.object({
|
|
1508
|
-
/**
|
|
1509
|
-
* Whether to enable prompt caching.
|
|
1510
|
-
* @default true
|
|
1511
|
-
*/
|
|
1512
|
-
enableCaching: z14.boolean().optional(),
|
|
1513
|
-
/**
|
|
1514
|
-
* The time-to-live for the cached prompt.
|
|
1515
|
-
* @default "5m"
|
|
1516
|
-
*/
|
|
1517
|
-
ttl: z14.enum(["5m", "1h"]).optional(),
|
|
1518
|
-
/**
|
|
1519
|
-
* The minimum number of messages required before caching is applied.
|
|
1520
|
-
* @default 3
|
|
1521
|
-
*/
|
|
1522
|
-
minMessagesToCache: z14.number().optional(),
|
|
1523
|
-
/**
|
|
1524
|
-
* The behavior to take when an unsupported model is used.
|
|
1525
|
-
* - "ignore" will ignore the unsupported model and continue without caching.
|
|
1526
|
-
* - "warn" will warn the user and continue without caching.
|
|
1527
|
-
* - "raise" will raise an error and stop the agent.
|
|
1528
|
-
* @default "warn"
|
|
1529
|
-
*/
|
|
1530
|
-
unsupportedModelBehavior: z14.enum([
|
|
1531
|
-
"ignore",
|
|
1532
|
-
"warn",
|
|
1533
|
-
"raise"
|
|
1534
|
-
]).optional()
|
|
1535
|
-
});
|
|
1536
|
-
|
|
1537
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/agents/middleware/provider/aws/promptCaching.js
|
|
1538
|
-
import { z as z15 } from "zod/v3";
|
|
1539
|
-
var contextSchema7 = z15.object({
|
|
1540
|
-
/**
|
|
1541
|
-
* Whether to enable prompt caching.
|
|
1542
|
-
* @default true
|
|
1543
|
-
*/
|
|
1544
|
-
enableCaching: z15.boolean().optional(),
|
|
1545
|
-
/**
|
|
1546
|
-
* The time-to-live for the cached prompt.
|
|
1547
|
-
* @default "5m"
|
|
1548
|
-
*/
|
|
1549
|
-
ttl: z15.enum(["5m", "1h"]).optional(),
|
|
1550
|
-
/**
|
|
1551
|
-
* The minimum number of messages required before caching is applied.
|
|
1552
|
-
* @default 1
|
|
1553
|
-
*/
|
|
1554
|
-
minMessagesToCache: z15.number().optional(),
|
|
1555
|
-
/**
|
|
1556
|
-
* The behavior to take when an unsupported model is used.
|
|
1557
|
-
* - "ignore" will ignore the unsupported model and continue without caching.
|
|
1558
|
-
* - "warn" will warn the user and continue without caching.
|
|
1559
|
-
* - "raise" will raise an error and stop the agent.
|
|
1560
|
-
* @default "warn"
|
|
1561
|
-
*/
|
|
1562
|
-
unsupportedModelBehavior: z15.enum([
|
|
1563
|
-
"ignore",
|
|
1564
|
-
"warn",
|
|
1565
|
-
"raise"
|
|
1566
|
-
]).optional()
|
|
1567
|
-
});
|
|
1568
|
-
|
|
1569
|
-
// ../../node_modules/.pnpm/langchain@1.5.11_@langchain+core@1.2.11_@opentelemetry+api@1.9.1_@opentelemetry+exporte_f5289af23b1dceae16b2f90e7460a344/node_modules/langchain/dist/index.js
|
|
1570
|
-
import { AIMessage as AIMessage17, AIMessageChunk as AIMessageChunk2, BaseMessage as BaseMessage2, BaseMessageChunk, HumanMessage as HumanMessage8, HumanMessageChunk, SystemMessage as SystemMessage7, SystemMessageChunk, ToolMessage as ToolMessage18, ToolMessageChunk, filterMessages, trimMessages as trimMessages2 } from "@langchain/core/messages";
|
|
1571
|
-
import { DynamicStructuredTool, DynamicTool, StructuredTool, Tool } from "@langchain/core/tools";
|
|
1572
|
-
import { context } from "@langchain/core/utils/context";
|
|
1573
|
-
import { InMemoryStore as InMemoryStore2 } from "@langchain/core/stores";
|
|
1574
|
-
import { Document } from "@langchain/core/documents";
|
|
1575
|
-
import { fakeModel, langchainMatchers } from "@langchain/core/testing";
|
|
1576
|
-
|
|
1577
|
-
// src/bridge/approvals.ts
|
|
1578
|
-
var NATIVE_TOOL_KIND = {
|
|
1579
|
-
read_file: "readonly",
|
|
1580
|
-
write_file: "edit",
|
|
1581
|
-
edit_file: "edit",
|
|
1582
|
-
execute: "bash",
|
|
1583
|
-
grep: "readonly",
|
|
1584
|
-
glob: "readonly",
|
|
1585
|
-
ls: "readonly",
|
|
1586
|
-
task: "edit",
|
|
1587
|
-
write_todos: "edit"
|
|
585
|
+
//#endregion
|
|
586
|
+
//#region src/bridge/approvals.ts
|
|
587
|
+
const NATIVE_TOOL_KIND = {
|
|
588
|
+
read_file: "readonly",
|
|
589
|
+
write_file: "edit",
|
|
590
|
+
edit_file: "edit",
|
|
591
|
+
execute: "bash",
|
|
592
|
+
grep: "readonly",
|
|
593
|
+
glob: "readonly",
|
|
594
|
+
ls: "readonly",
|
|
595
|
+
task: "edit",
|
|
596
|
+
write_todos: "edit"
|
|
1588
597
|
};
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
598
|
+
const NATIVE_TO_COMMON$1 = {
|
|
599
|
+
read_file: "read",
|
|
600
|
+
write_file: "write",
|
|
601
|
+
edit_file: "edit",
|
|
602
|
+
execute: "bash"
|
|
1594
603
|
};
|
|
1595
|
-
function toCommonName(nativeName) {
|
|
1596
|
-
|
|
604
|
+
function toCommonName$1(nativeName) {
|
|
605
|
+
return NATIVE_TO_COMMON$1[nativeName] ?? nativeName;
|
|
1597
606
|
}
|
|
1598
607
|
function isBuiltinToolIncluded(input) {
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
608
|
+
if (input.toolFiltering == null) return true;
|
|
609
|
+
const toolName = toCommonName$1(input.nativeName);
|
|
610
|
+
return input.toolFiltering.mode === "allow" ? input.toolFiltering.toolNames.includes(toolName) : !input.toolFiltering.toolNames.includes(toolName);
|
|
1602
611
|
}
|
|
1603
612
|
function builtinToolRequiresApproval(kind, permissionMode) {
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
613
|
+
if (permissionMode === "allow-all") return false;
|
|
614
|
+
if (permissionMode === "allow-edits") return kind === "bash";
|
|
615
|
+
return kind === "edit" || kind === "bash";
|
|
1607
616
|
}
|
|
1608
617
|
function buildInterruptOn(permissionMode, builtinToolFiltering) {
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
config[nativeName] = { allowedDecisions: ["approve", "reject"] };
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
return Object.keys(config).length > 0 ? config : void 0;
|
|
618
|
+
const config = {};
|
|
619
|
+
for (const [nativeName, kind] of Object.entries(NATIVE_TOOL_KIND)) if (permissionMode != null && isBuiltinToolIncluded({
|
|
620
|
+
nativeName,
|
|
621
|
+
toolFiltering: builtinToolFiltering
|
|
622
|
+
}) && builtinToolRequiresApproval(kind, permissionMode)) config[nativeName] = { allowedDecisions: ["approve", "reject"] };
|
|
623
|
+
return Object.keys(config).length > 0 ? config : void 0;
|
|
1619
624
|
}
|
|
1620
625
|
function collectActionRequests(interrupts) {
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
626
|
+
const out = [];
|
|
627
|
+
for (const interrupt of interrupts) {
|
|
628
|
+
const value = interrupt.value;
|
|
629
|
+
for (const action of value?.actionRequests ?? []) out.push({
|
|
630
|
+
name: action.name,
|
|
631
|
+
args: action.args ?? {}
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
return out;
|
|
1629
635
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
636
|
+
//#endregion
|
|
637
|
+
//#region src/bridge/create-emit-stream-event.ts
|
|
1633
638
|
function createDeepAgentsStreamEventState() {
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
639
|
+
return {
|
|
640
|
+
streamStarted: false,
|
|
641
|
+
textBlockId: void 0,
|
|
642
|
+
reasoningBlockId: void 0,
|
|
643
|
+
inputTokens: 0,
|
|
644
|
+
outputTokens: 0,
|
|
645
|
+
streamedStepInput: 0,
|
|
646
|
+
streamedStepOutput: 0,
|
|
647
|
+
pendingStep: void 0,
|
|
648
|
+
approvedToolQueue: /* @__PURE__ */ new Map(),
|
|
649
|
+
approvedRunIds: /* @__PURE__ */ new Map(),
|
|
650
|
+
dynamicToolRunIds: /* @__PURE__ */ new Set()
|
|
651
|
+
};
|
|
1647
652
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
653
|
+
const NATIVE_TO_COMMON = {
|
|
654
|
+
read_file: "read",
|
|
655
|
+
write_file: "write",
|
|
656
|
+
edit_file: "edit",
|
|
657
|
+
execute: "bash"
|
|
1653
658
|
};
|
|
1654
|
-
function
|
|
1655
|
-
|
|
659
|
+
function toCommonName(nativeName) {
|
|
660
|
+
return NATIVE_TO_COMMON[nativeName] ?? nativeName;
|
|
1656
661
|
}
|
|
1657
|
-
function createEmitStreamEvent({
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
662
|
+
function createEmitStreamEvent({ state, configuredModel, hostToolNames, mcpToolNames, structuredOutputToolNames = /* @__PURE__ */ new Set(), emit }) {
|
|
663
|
+
return (event) => {
|
|
664
|
+
const kind = event.event;
|
|
665
|
+
const data = event.data ?? {};
|
|
666
|
+
const nested = (event.metadata?.langgraph_checkpoint_ns ?? "").includes("|");
|
|
667
|
+
if (kind === "on_chat_model_start") {
|
|
668
|
+
if (!nested) {
|
|
669
|
+
if (!state.streamStarted) {
|
|
670
|
+
state.streamStarted = true;
|
|
671
|
+
const modelId = resolveDeepAgentsModelId({
|
|
672
|
+
configuredModel,
|
|
673
|
+
metadata: event.metadata
|
|
674
|
+
});
|
|
675
|
+
emit({
|
|
676
|
+
type: "stream-start",
|
|
677
|
+
...modelId ? { modelId } : {}
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
flushStep({
|
|
681
|
+
state,
|
|
682
|
+
emit
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
} else if (kind === "on_chat_model_stream") {
|
|
686
|
+
if (nested) return;
|
|
687
|
+
const chunk = data.chunk;
|
|
688
|
+
if (!chunk) return;
|
|
689
|
+
const content = chunk.content;
|
|
690
|
+
if (typeof content === "string" && content) emitText({
|
|
691
|
+
state,
|
|
692
|
+
emit,
|
|
693
|
+
delta: content
|
|
694
|
+
});
|
|
695
|
+
else if (Array.isArray(content)) {
|
|
696
|
+
for (const block of content) if (block && typeof block === "object") {
|
|
697
|
+
const value = block;
|
|
698
|
+
if ((value.type === "text" || value.type === "text-delta") && value.text) emitText({
|
|
699
|
+
state,
|
|
700
|
+
emit,
|
|
701
|
+
delta: value.text
|
|
702
|
+
});
|
|
703
|
+
else if (value.type === "thinking" && value.thinking) emitReasoning({
|
|
704
|
+
state,
|
|
705
|
+
emit,
|
|
706
|
+
delta: value.thinking
|
|
707
|
+
});
|
|
708
|
+
else if ((value.type === "reasoning" || value.type === "reasoning-delta") && value.reasoning) emitReasoning({
|
|
709
|
+
state,
|
|
710
|
+
emit,
|
|
711
|
+
delta: value.reasoning
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
const usage = chunk.usage_metadata;
|
|
716
|
+
if (usage) {
|
|
717
|
+
state.streamedStepInput = Math.max(state.streamedStepInput, usage.input_tokens ?? 0);
|
|
718
|
+
state.streamedStepOutput = Math.max(state.streamedStepOutput, usage.output_tokens ?? 0);
|
|
719
|
+
}
|
|
720
|
+
} else if (kind === "on_chat_model_end") {
|
|
721
|
+
const usage = data.output?.usage_metadata;
|
|
722
|
+
const stepInput = usage?.input_tokens ?? state.streamedStepInput;
|
|
723
|
+
const stepOutput = usage?.output_tokens ?? state.streamedStepOutput;
|
|
724
|
+
state.inputTokens += stepInput;
|
|
725
|
+
state.outputTokens += stepOutput;
|
|
726
|
+
state.streamedStepInput = 0;
|
|
727
|
+
state.streamedStepOutput = 0;
|
|
728
|
+
if (!nested) {
|
|
729
|
+
endTextBlock({
|
|
730
|
+
state,
|
|
731
|
+
emit
|
|
732
|
+
});
|
|
733
|
+
endReasoningBlock({
|
|
734
|
+
state,
|
|
735
|
+
emit
|
|
736
|
+
});
|
|
737
|
+
state.pendingStep = {
|
|
738
|
+
input: stepInput,
|
|
739
|
+
output: stepOutput
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
} else if (kind === "on_tool_start") {
|
|
743
|
+
const toolName = event.name ?? "unknown";
|
|
744
|
+
if (structuredOutputToolNames.has(toolName)) return;
|
|
745
|
+
const runId = event.run_id ?? "";
|
|
746
|
+
if (!nested && !hostToolNames.has(toolName)) {
|
|
747
|
+
const isMcpTool = mcpToolNames.has(toolName);
|
|
748
|
+
if (isMcpTool && runId) state.dynamicToolRunIds.add(runId);
|
|
749
|
+
const queued = state.approvedToolQueue.get(toolName);
|
|
750
|
+
if (queued && queued.length > 0) {
|
|
751
|
+
const approvalId = queued.shift();
|
|
752
|
+
if (runId) state.approvedRunIds.set(runId, approvalId);
|
|
753
|
+
} else {
|
|
754
|
+
endTextBlock({
|
|
755
|
+
state,
|
|
756
|
+
emit
|
|
757
|
+
});
|
|
758
|
+
endReasoningBlock({
|
|
759
|
+
state,
|
|
760
|
+
emit
|
|
761
|
+
});
|
|
762
|
+
emit({
|
|
763
|
+
type: "tool-call",
|
|
764
|
+
toolCallId: runId,
|
|
765
|
+
toolName: toCommonName(toolName),
|
|
766
|
+
input: toToolCallInput(data.input),
|
|
767
|
+
providerExecuted: true,
|
|
768
|
+
nativeName: toolName,
|
|
769
|
+
...isMcpTool ? { dynamic: true } : {}
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
} else if (kind === "on_tool_end") {
|
|
774
|
+
const toolName = event.name ?? "unknown";
|
|
775
|
+
if (structuredOutputToolNames.has(toolName)) return;
|
|
776
|
+
const runId = event.run_id ?? "";
|
|
777
|
+
if (!nested && !hostToolNames.has(toolName)) {
|
|
778
|
+
const dynamic = state.dynamicToolRunIds.delete(runId);
|
|
779
|
+
let output = data.output ?? "";
|
|
780
|
+
if (output && typeof output === "object" && "content" in output) output = output.content;
|
|
781
|
+
emit({
|
|
782
|
+
type: "tool-result",
|
|
783
|
+
toolCallId: state.approvedRunIds.get(runId) ?? runId,
|
|
784
|
+
toolName: toCommonName(toolName),
|
|
785
|
+
result: output ?? null,
|
|
786
|
+
...dynamic ? { dynamic: true } : {}
|
|
787
|
+
});
|
|
788
|
+
state.approvedRunIds.delete(runId);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
};
|
|
1777
792
|
}
|
|
1778
|
-
function endTextBlock({
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
793
|
+
function endTextBlock({ state, emit }) {
|
|
794
|
+
if (state.textBlockId) {
|
|
795
|
+
emit({
|
|
796
|
+
type: "text-end",
|
|
797
|
+
id: state.textBlockId
|
|
798
|
+
});
|
|
799
|
+
state.textBlockId = void 0;
|
|
800
|
+
}
|
|
1786
801
|
}
|
|
1787
|
-
function endReasoningBlock({
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
802
|
+
function endReasoningBlock({ state, emit }) {
|
|
803
|
+
if (state.reasoningBlockId) {
|
|
804
|
+
emit({
|
|
805
|
+
type: "reasoning-end",
|
|
806
|
+
id: state.reasoningBlockId
|
|
807
|
+
});
|
|
808
|
+
state.reasoningBlockId = void 0;
|
|
809
|
+
}
|
|
1795
810
|
}
|
|
1796
|
-
function flushStep({
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
}
|
|
1808
|
-
});
|
|
1809
|
-
state.pendingStep = void 0;
|
|
811
|
+
function flushStep({ state, emit }) {
|
|
812
|
+
if (!state.pendingStep) return;
|
|
813
|
+
emit({
|
|
814
|
+
type: "finish-step",
|
|
815
|
+
finishReason: { unified: "stop" },
|
|
816
|
+
usage: {
|
|
817
|
+
inputTokens: { total: state.pendingStep.input },
|
|
818
|
+
outputTokens: { total: state.pendingStep.output }
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
state.pendingStep = void 0;
|
|
1810
822
|
}
|
|
1811
|
-
function ensureTextBlock({
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
823
|
+
function ensureTextBlock({ state, emit }) {
|
|
824
|
+
if (!state.textBlockId) {
|
|
825
|
+
state.textBlockId = `text-${randomUUID()}`;
|
|
826
|
+
emit({
|
|
827
|
+
type: "text-start",
|
|
828
|
+
id: state.textBlockId
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
return state.textBlockId;
|
|
1820
832
|
}
|
|
1821
|
-
function emitText({
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
})
|
|
1826
|
-
|
|
1827
|
-
|
|
833
|
+
function emitText({ state, emit, delta }) {
|
|
834
|
+
endReasoningBlock({
|
|
835
|
+
state,
|
|
836
|
+
emit
|
|
837
|
+
});
|
|
838
|
+
emit({
|
|
839
|
+
type: "text-delta",
|
|
840
|
+
id: ensureTextBlock({
|
|
841
|
+
state,
|
|
842
|
+
emit
|
|
843
|
+
}),
|
|
844
|
+
delta
|
|
845
|
+
});
|
|
1828
846
|
}
|
|
1829
|
-
function emitReasoning({
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
})
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
847
|
+
function emitReasoning({ state, emit, delta }) {
|
|
848
|
+
endTextBlock({
|
|
849
|
+
state,
|
|
850
|
+
emit
|
|
851
|
+
});
|
|
852
|
+
if (!state.reasoningBlockId) {
|
|
853
|
+
state.reasoningBlockId = `reasoning-${randomUUID()}`;
|
|
854
|
+
emit({
|
|
855
|
+
type: "reasoning-start",
|
|
856
|
+
id: state.reasoningBlockId
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
emit({
|
|
860
|
+
type: "reasoning-delta",
|
|
861
|
+
id: state.reasoningBlockId,
|
|
862
|
+
delta
|
|
863
|
+
});
|
|
1840
864
|
}
|
|
1841
|
-
function resolveDeepAgentsModelId({
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
if (typeof modelId === "string" && modelId.length > 0) return modelId;
|
|
1848
|
-
}
|
|
1849
|
-
return configuredModel;
|
|
865
|
+
function resolveDeepAgentsModelId({ configuredModel, metadata }) {
|
|
866
|
+
if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) {
|
|
867
|
+
const modelId = metadata.ls_model_name;
|
|
868
|
+
if (typeof modelId === "string" && modelId.length > 0) return modelId;
|
|
869
|
+
}
|
|
870
|
+
return configuredModel;
|
|
1850
871
|
}
|
|
1851
872
|
function toToolCallInput(raw) {
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
873
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && Object.keys(raw).length === 1 && typeof raw.input === "string") {
|
|
874
|
+
const inner = raw.input;
|
|
875
|
+
if (/^\s*[[{]/.test(inner)) return inner;
|
|
876
|
+
}
|
|
877
|
+
return JSON.stringify(raw ?? {});
|
|
1857
878
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
import { z as z16 } from "zod/v4";
|
|
879
|
+
//#endregion
|
|
880
|
+
//#region src/bridge/json-schema-to-zod.ts
|
|
1861
881
|
function jsonSchemaToZodObject(input) {
|
|
1862
|
-
|
|
1863
|
-
|
|
882
|
+
const schema = input && typeof input === "object" ? input : {};
|
|
883
|
+
return z.object(toZodShape(schema));
|
|
1864
884
|
}
|
|
1865
885
|
function toZodShape(schema) {
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
886
|
+
if (!schema.properties) return {};
|
|
887
|
+
const required = new Set(schema.required);
|
|
888
|
+
const shape = {};
|
|
889
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
890
|
+
const propType = toZodType(propSchema);
|
|
891
|
+
shape[key] = required.has(key) ? propType : propType.optional();
|
|
892
|
+
}
|
|
893
|
+
return shape;
|
|
1874
894
|
}
|
|
1875
895
|
function toZodType(schema) {
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
return zType;
|
|
896
|
+
if (!schema) return z.any();
|
|
897
|
+
const types = Array.isArray(schema.type) ? schema.type.filter((t) => t !== "null") : [schema.type].filter(Boolean);
|
|
898
|
+
let zType;
|
|
899
|
+
switch (types[0]) {
|
|
900
|
+
case "string":
|
|
901
|
+
zType = z.string();
|
|
902
|
+
break;
|
|
903
|
+
case "number":
|
|
904
|
+
zType = z.number();
|
|
905
|
+
break;
|
|
906
|
+
case "integer":
|
|
907
|
+
zType = z.number().int();
|
|
908
|
+
break;
|
|
909
|
+
case "boolean":
|
|
910
|
+
zType = z.boolean();
|
|
911
|
+
break;
|
|
912
|
+
case "array":
|
|
913
|
+
zType = z.array(toZodType(schema.items));
|
|
914
|
+
break;
|
|
915
|
+
case "object":
|
|
916
|
+
zType = z.object(toZodShape(schema));
|
|
917
|
+
break;
|
|
918
|
+
case "null":
|
|
919
|
+
zType = z.null();
|
|
920
|
+
break;
|
|
921
|
+
default: zType = z.any();
|
|
922
|
+
}
|
|
923
|
+
if (schema.description) zType = zType.describe(schema.description);
|
|
924
|
+
if (schema.nullable) zType = zType.nullable();
|
|
925
|
+
return zType;
|
|
1907
926
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
rootDir,
|
|
1914
|
-
env = process.env
|
|
1915
|
-
}) {
|
|
1916
|
-
return new LocalShellBackend({
|
|
1917
|
-
rootDir,
|
|
1918
|
-
env: {
|
|
1919
|
-
PATH: env.PATH ?? SANDBOX_PATH_FALLBACK
|
|
1920
|
-
}
|
|
1921
|
-
});
|
|
927
|
+
function createLocalShellBackend({ rootDir, env = process.env }) {
|
|
928
|
+
return new LocalShellBackend({
|
|
929
|
+
rootDir,
|
|
930
|
+
env: { PATH: env.PATH ?? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }
|
|
931
|
+
});
|
|
1922
932
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
import { dirname } from "path";
|
|
1927
|
-
var SNAPSHOT_HEADER = "deepagents-memory-saver-v1";
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/bridge/persistent-memory-saver.ts
|
|
935
|
+
const SNAPSHOT_HEADER = "deepagents-memory-saver-v1";
|
|
1928
936
|
function encodeString(value) {
|
|
1929
|
-
|
|
937
|
+
return Buffer.from(value, "utf8").toString("base64");
|
|
1930
938
|
}
|
|
1931
939
|
function decodeString(value) {
|
|
1932
|
-
|
|
940
|
+
return Buffer.from(value, "base64").toString("utf8");
|
|
1933
941
|
}
|
|
1934
942
|
function encodeBytes(value) {
|
|
1935
|
-
|
|
943
|
+
return Buffer.from(value).toString("base64");
|
|
1936
944
|
}
|
|
1937
945
|
function decodeBytes(value) {
|
|
1938
|
-
|
|
946
|
+
return Buffer.from(value, "base64");
|
|
1939
947
|
}
|
|
1940
|
-
async function loadMemorySaver({
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
}
|
|
1986
|
-
throw new Error("Invalid Deep Agents conversation checkpoint");
|
|
1987
|
-
}
|
|
1988
|
-
saver.storage = storage;
|
|
1989
|
-
saver.writes = writes;
|
|
948
|
+
async function loadMemorySaver({ path, saver }) {
|
|
949
|
+
let snapshot;
|
|
950
|
+
try {
|
|
951
|
+
snapshot = await readFile(path, "utf8");
|
|
952
|
+
} catch (error) {
|
|
953
|
+
if (error.code === "ENOENT") return;
|
|
954
|
+
throw error;
|
|
955
|
+
}
|
|
956
|
+
const [header, ...lines] = snapshot.split("\n");
|
|
957
|
+
if (header !== SNAPSHOT_HEADER) throw new Error("Unsupported Deep Agents conversation checkpoint format");
|
|
958
|
+
const storage = Object.create(null);
|
|
959
|
+
const writes = Object.create(null);
|
|
960
|
+
for (const line of lines) {
|
|
961
|
+
if (line === "") continue;
|
|
962
|
+
const fields = line.split(" ");
|
|
963
|
+
if (fields[0] === "S" && fields.length === 7) {
|
|
964
|
+
const [, threadIdValue, namespaceValue, checkpointIdValue] = fields;
|
|
965
|
+
const threadId = decodeString(threadIdValue);
|
|
966
|
+
const namespace = decodeString(namespaceValue);
|
|
967
|
+
const checkpointId = decodeString(checkpointIdValue);
|
|
968
|
+
storage[threadId] ??= Object.create(null);
|
|
969
|
+
storage[threadId][namespace] ??= Object.create(null);
|
|
970
|
+
storage[threadId][namespace][checkpointId] = [
|
|
971
|
+
decodeBytes(fields[4]),
|
|
972
|
+
decodeBytes(fields[5]),
|
|
973
|
+
fields[6] === "" ? void 0 : decodeString(fields[6])
|
|
974
|
+
];
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
if (fields[0] === "W" && fields.length === 6) {
|
|
978
|
+
const [, keyValue, indexValue, taskIdValue, channelValue, value] = fields;
|
|
979
|
+
const key = decodeString(keyValue);
|
|
980
|
+
const index = decodeString(indexValue);
|
|
981
|
+
writes[key] ??= Object.create(null);
|
|
982
|
+
writes[key][index] = [
|
|
983
|
+
decodeString(taskIdValue),
|
|
984
|
+
decodeString(channelValue),
|
|
985
|
+
decodeBytes(value)
|
|
986
|
+
];
|
|
987
|
+
continue;
|
|
988
|
+
}
|
|
989
|
+
throw new Error("Invalid Deep Agents conversation checkpoint");
|
|
990
|
+
}
|
|
991
|
+
saver.storage = storage;
|
|
992
|
+
saver.writes = writes;
|
|
1990
993
|
}
|
|
1991
|
-
async function saveMemorySaver({
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
for (const [key, indexedWrites] of Object.entries(saver.writes)) {
|
|
2017
|
-
for (const [index, [taskId, channel, value]] of Object.entries(
|
|
2018
|
-
indexedWrites
|
|
2019
|
-
)) {
|
|
2020
|
-
lines.push(
|
|
2021
|
-
[
|
|
2022
|
-
"W",
|
|
2023
|
-
encodeString(key),
|
|
2024
|
-
encodeString(index),
|
|
2025
|
-
encodeString(taskId),
|
|
2026
|
-
encodeString(channel),
|
|
2027
|
-
encodeBytes(value)
|
|
2028
|
-
].join(" ")
|
|
2029
|
-
);
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
await mkdir2(dirname(path), { recursive: true });
|
|
2033
|
-
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
2034
|
-
await writeFile2(temporaryPath, `${lines.join("\n")}
|
|
2035
|
-
`, "utf8");
|
|
2036
|
-
await rename(temporaryPath, path);
|
|
994
|
+
async function saveMemorySaver({ path, saver }) {
|
|
995
|
+
const lines = [SNAPSHOT_HEADER];
|
|
996
|
+
for (const [threadId, namespaces] of Object.entries(saver.storage)) for (const [namespace, checkpoints] of Object.entries(namespaces)) for (const [checkpointId, [checkpoint, metadata, parentCheckpointId]] of Object.entries(checkpoints)) lines.push([
|
|
997
|
+
"S",
|
|
998
|
+
encodeString(threadId),
|
|
999
|
+
encodeString(namespace),
|
|
1000
|
+
encodeString(checkpointId),
|
|
1001
|
+
encodeBytes(checkpoint),
|
|
1002
|
+
encodeBytes(metadata),
|
|
1003
|
+
parentCheckpointId == null ? "" : encodeString(parentCheckpointId)
|
|
1004
|
+
].join(" "));
|
|
1005
|
+
for (const [key, indexedWrites] of Object.entries(saver.writes)) for (const [index, [taskId, channel, value]] of Object.entries(indexedWrites)) lines.push([
|
|
1006
|
+
"W",
|
|
1007
|
+
encodeString(key),
|
|
1008
|
+
encodeString(index),
|
|
1009
|
+
encodeString(taskId),
|
|
1010
|
+
encodeString(channel),
|
|
1011
|
+
encodeBytes(value)
|
|
1012
|
+
].join(" "));
|
|
1013
|
+
await mkdir(dirname(path), { recursive: true });
|
|
1014
|
+
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
1015
|
+
await writeFile(temporaryPath, `${lines.join("\n")}\n`, "utf8");
|
|
1016
|
+
await rename(temporaryPath, path);
|
|
2037
1017
|
}
|
|
2038
1018
|
async function removeMemorySaverSnapshot(path) {
|
|
2039
|
-
|
|
1019
|
+
await rm(path, { force: true });
|
|
2040
1020
|
}
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
AIMessage as AIMessage18,
|
|
2045
|
-
ToolMessage as ToolMessage19
|
|
2046
|
-
} from "@langchain/core/messages";
|
|
2047
|
-
var MIDDLEWARE_BRAND2 = /* @__PURE__ */ Symbol.for("AgentMiddleware");
|
|
1021
|
+
//#endregion
|
|
1022
|
+
//#region src/bridge/tool-filtering.ts
|
|
1023
|
+
const MIDDLEWARE_BRAND = Symbol.for("AgentMiddleware");
|
|
2048
1024
|
function getBuiltinToolFilteringDenialReason(input) {
|
|
2049
|
-
|
|
1025
|
+
return `Tool '${input.toolName}' is inactive due to the HarnessAgent tool filtering policy.`;
|
|
2050
1026
|
}
|
|
2051
1027
|
function stringifyToolInput(input) {
|
|
2052
|
-
|
|
1028
|
+
return JSON.stringify(input ?? {});
|
|
2053
1029
|
}
|
|
2054
1030
|
function isNativeBuiltinToolCall(input) {
|
|
2055
|
-
|
|
1031
|
+
return Object.keys(NATIVE_TOOL_KIND).includes(input.toolCall.name);
|
|
2056
1032
|
}
|
|
2057
1033
|
function isInactiveBuiltinToolCall(input) {
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
1034
|
+
return isNativeBuiltinToolCall({ toolCall: input.toolCall }) && !isBuiltinToolIncluded({
|
|
1035
|
+
nativeName: input.toolCall.name,
|
|
1036
|
+
toolFiltering: input.builtinToolFiltering
|
|
1037
|
+
});
|
|
2062
1038
|
}
|
|
2063
1039
|
function createBuiltinToolFilteringMiddleware(input) {
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
}
|
|
2117
|
-
};
|
|
1040
|
+
if (input.builtinToolFiltering == null) return void 0;
|
|
1041
|
+
return {
|
|
1042
|
+
[MIDDLEWARE_BRAND]: true,
|
|
1043
|
+
name: "HarnessBuiltinToolFilteringMiddleware",
|
|
1044
|
+
afterModel: {
|
|
1045
|
+
canJumpTo: ["model"],
|
|
1046
|
+
hook: (state) => {
|
|
1047
|
+
const lastMessage = [...state.messages].reverse().find((message) => AIMessage.isInstance(message));
|
|
1048
|
+
if (!lastMessage?.tool_calls?.length) return void 0;
|
|
1049
|
+
let hasActiveToolCalls = false;
|
|
1050
|
+
const deniedToolMessages = [];
|
|
1051
|
+
for (const toolCall of lastMessage.tool_calls) {
|
|
1052
|
+
if (!isInactiveBuiltinToolCall({
|
|
1053
|
+
toolCall,
|
|
1054
|
+
builtinToolFiltering: input.builtinToolFiltering
|
|
1055
|
+
})) {
|
|
1056
|
+
hasActiveToolCalls = true;
|
|
1057
|
+
continue;
|
|
1058
|
+
}
|
|
1059
|
+
const nativeName = toolCall.name;
|
|
1060
|
+
toolCall.id ??= `${nativeName}-filtered-${deniedToolMessages.length}`;
|
|
1061
|
+
const toolName = toCommonName$1(nativeName);
|
|
1062
|
+
const reason = getBuiltinToolFilteringDenialReason({ toolName });
|
|
1063
|
+
input.emit({
|
|
1064
|
+
type: "tool-call",
|
|
1065
|
+
toolCallId: toolCall.id,
|
|
1066
|
+
toolName,
|
|
1067
|
+
input: stringifyToolInput(toolCall.args),
|
|
1068
|
+
providerExecuted: true,
|
|
1069
|
+
nativeName
|
|
1070
|
+
});
|
|
1071
|
+
input.emit({
|
|
1072
|
+
type: "tool-result",
|
|
1073
|
+
toolCallId: toolCall.id,
|
|
1074
|
+
toolName,
|
|
1075
|
+
result: reason
|
|
1076
|
+
});
|
|
1077
|
+
deniedToolMessages.push(new ToolMessage({
|
|
1078
|
+
content: reason,
|
|
1079
|
+
name: nativeName,
|
|
1080
|
+
tool_call_id: toolCall.id,
|
|
1081
|
+
status: "error"
|
|
1082
|
+
}));
|
|
1083
|
+
}
|
|
1084
|
+
if (deniedToolMessages.length === 0) return void 0;
|
|
1085
|
+
return {
|
|
1086
|
+
messages: [lastMessage, ...deniedToolMessages],
|
|
1087
|
+
...hasActiveToolCalls ? {} : { jumpTo: "model" }
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
2118
1092
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/bridge/index.ts
|
|
1095
|
+
const HARNESS_CLIENT_APP = env.AI_SDK_HARNESS_CLIENT_APP;
|
|
2122
1096
|
function parseArgs(rawArgs) {
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
1097
|
+
const out = {};
|
|
1098
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
1099
|
+
const arg = rawArgs[i];
|
|
1100
|
+
if (arg.startsWith("--")) {
|
|
1101
|
+
const key = arg.slice(2).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
1102
|
+
out[key] = rawArgs[i + 1];
|
|
1103
|
+
i++;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return out;
|
|
2133
1107
|
}
|
|
2134
|
-
function buildModel({
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
...headers,
|
|
2153
|
-
...procEnv2.AI_GATEWAY_API_KEY && HARNESS_CLIENT_APP ? {
|
|
2154
|
-
"User-Agent": HARNESS_CLIENT_APP,
|
|
2155
|
-
"x-client-app": HARNESS_CLIENT_APP
|
|
2156
|
-
} : {}
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
2159
|
-
} : {}
|
|
2160
|
-
});
|
|
1108
|
+
function buildModel({ rawModel, thinking, effort, headers }) {
|
|
1109
|
+
if (!rawModel) return void 0;
|
|
1110
|
+
const baseUrl = env.ANTHROPIC_BASE_URL;
|
|
1111
|
+
const model = baseUrl ? rawModel : rawModel.replace(/^anthropic[/:]/, "");
|
|
1112
|
+
return new ChatAnthropic({
|
|
1113
|
+
model,
|
|
1114
|
+
...thinking ? { thinking } : {},
|
|
1115
|
+
...effort ? { outputConfig: { effort } } : {},
|
|
1116
|
+
...env.ANTHROPIC_API_KEY ? { apiKey: env.ANTHROPIC_API_KEY } : {},
|
|
1117
|
+
...baseUrl ? { anthropicApiUrl: baseUrl } : {},
|
|
1118
|
+
...headers != null || env.AI_GATEWAY_API_KEY ? { clientOptions: { defaultHeaders: {
|
|
1119
|
+
...headers,
|
|
1120
|
+
...env.AI_GATEWAY_API_KEY && HARNESS_CLIENT_APP ? {
|
|
1121
|
+
"User-Agent": HARNESS_CLIENT_APP,
|
|
1122
|
+
"x-client-app": HARNESS_CLIENT_APP
|
|
1123
|
+
} : {}
|
|
1124
|
+
} } } : {}
|
|
1125
|
+
});
|
|
2161
1126
|
}
|
|
2162
1127
|
function createModelMiddleware() {
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
1128
|
+
return createMiddleware({
|
|
1129
|
+
name: "harnessModel",
|
|
1130
|
+
wrapModelCall: async (request, handler) => {
|
|
1131
|
+
if (!activeModel && !activeThinking && !activeEffort && !activeHeaders) return handler(request);
|
|
1132
|
+
if (activeModel) {
|
|
1133
|
+
const configuredModel = buildModel({
|
|
1134
|
+
rawModel: activeModel,
|
|
1135
|
+
thinking: activeThinking,
|
|
1136
|
+
effort: activeEffort,
|
|
1137
|
+
headers: activeHeaders
|
|
1138
|
+
});
|
|
1139
|
+
if (!configuredModel) throw new Error("Deep Agents model is missing");
|
|
1140
|
+
return handler({
|
|
1141
|
+
...request,
|
|
1142
|
+
model: configuredModel
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
let model = request.model;
|
|
1146
|
+
if ("_getModelInstance" in model && typeof model._getModelInstance === "function") model = await model._getModelInstance();
|
|
1147
|
+
if (!(model instanceof ChatAnthropic)) throw new Error("Deep Agents reasoning requires ChatAnthropic");
|
|
1148
|
+
const configuredModel = buildModel({
|
|
1149
|
+
rawModel: model.model,
|
|
1150
|
+
thinking: activeThinking,
|
|
1151
|
+
effort: activeEffort,
|
|
1152
|
+
headers: activeHeaders
|
|
1153
|
+
});
|
|
1154
|
+
if (!configuredModel) throw new Error("Deep Agents model is missing");
|
|
1155
|
+
return handler({
|
|
1156
|
+
...request,
|
|
1157
|
+
model: configuredModel
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
2196
1161
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
1162
|
+
const args = parseArgs(argv.slice(2));
|
|
1163
|
+
const workdir = args.workdir;
|
|
1164
|
+
const bridgeStateDir = args.bridgeStateDir;
|
|
2200
1165
|
if (!workdir || !bridgeStateDir) {
|
|
2201
|
-
|
|
2202
|
-
|
|
1166
|
+
console.error("deepagents bridge: missing --workdir / --bridge-state-dir");
|
|
1167
|
+
process.exit(1);
|
|
2203
1168
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
if (args.resume === "true") {
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
...currentResponseFormat == null ? {} : { responseFormat: currentResponseFormat }
|
|
2231
|
-
});
|
|
2232
|
-
}
|
|
1169
|
+
const conversationCheckpointPath = `${bridgeStateDir}/conversation.checkpoint`;
|
|
1170
|
+
let agent;
|
|
1171
|
+
let currentTurn;
|
|
1172
|
+
let mcpClient;
|
|
1173
|
+
let mcpToolNames = /* @__PURE__ */ new Set();
|
|
1174
|
+
let currentResponseFormat;
|
|
1175
|
+
const checkpointer = new MemorySaver();
|
|
1176
|
+
if (args.resume === "true") await loadMemorySaver({
|
|
1177
|
+
path: conversationCheckpointPath,
|
|
1178
|
+
saver: checkpointer
|
|
1179
|
+
});
|
|
1180
|
+
else await removeMemorySaverSnapshot(conversationCheckpointPath);
|
|
1181
|
+
let agentConfigurationSignature;
|
|
1182
|
+
let activeModel;
|
|
1183
|
+
let activeThinking;
|
|
1184
|
+
let activeEffort;
|
|
1185
|
+
let activeHeaders;
|
|
1186
|
+
const modelMiddleware = createModelMiddleware();
|
|
1187
|
+
const responseFormatMiddleware = createMiddleware({
|
|
1188
|
+
name: "HarnessResponseFormat",
|
|
1189
|
+
wrapModelCall(request, handler) {
|
|
1190
|
+
return handler({
|
|
1191
|
+
...request,
|
|
1192
|
+
...currentResponseFormat == null ? {} : { responseFormat: currentResponseFormat }
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
2233
1195
|
});
|
|
2234
1196
|
function buildHostTools(toolSchemas) {
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
description: schema.description ?? "",
|
|
2261
|
-
schema: jsonSchemaToZodObject(schema.inputSchema)
|
|
2262
|
-
}
|
|
2263
|
-
)
|
|
2264
|
-
);
|
|
1197
|
+
return (toolSchemas ?? []).map((schema) => tool(async (input) => {
|
|
1198
|
+
const turn = currentTurn;
|
|
1199
|
+
if (!turn) throw new Error("no active turn");
|
|
1200
|
+
const toolCallId = `${schema.name}-${randomUUID()}`;
|
|
1201
|
+
turn.emit({
|
|
1202
|
+
type: "tool-call",
|
|
1203
|
+
toolCallId,
|
|
1204
|
+
toolName: schema.name,
|
|
1205
|
+
input: JSON.stringify(input),
|
|
1206
|
+
providerExecuted: false
|
|
1207
|
+
});
|
|
1208
|
+
const { output, isError } = await turn.requestToolResult(toolCallId);
|
|
1209
|
+
turn.emit({
|
|
1210
|
+
type: "tool-result",
|
|
1211
|
+
toolCallId,
|
|
1212
|
+
toolName: schema.name,
|
|
1213
|
+
result: output ?? null,
|
|
1214
|
+
...isError !== void 0 ? { isError } : {}
|
|
1215
|
+
});
|
|
1216
|
+
return typeof output === "string" ? output : JSON.stringify(output);
|
|
1217
|
+
}, {
|
|
1218
|
+
name: schema.name,
|
|
1219
|
+
description: schema.description ?? "",
|
|
1220
|
+
schema: jsonSchemaToZodObject(schema.inputSchema)
|
|
1221
|
+
}));
|
|
2265
1222
|
}
|
|
2266
1223
|
async function runTurn(start, turn) {
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
}
|
|
2438
|
-
});
|
|
1224
|
+
currentTurn = turn;
|
|
1225
|
+
if (start.model) activeModel = start.model;
|
|
1226
|
+
activeThinking = start.thinking;
|
|
1227
|
+
activeEffort = start.effort;
|
|
1228
|
+
activeHeaders = start.headers;
|
|
1229
|
+
currentResponseFormat = start.responseFormat?.type === "json" && start.responseFormat.schema != null ? toolStrategy(start.responseFormat.schema) : void 0;
|
|
1230
|
+
const emit = (event) => turn.emit(event);
|
|
1231
|
+
const interruptOn = buildInterruptOn(start.permissionMode, start.builtinToolFiltering);
|
|
1232
|
+
const config = {
|
|
1233
|
+
version: "v2",
|
|
1234
|
+
configurable: { thread_id: "bridge-session" },
|
|
1235
|
+
...start.recursionLimit != null ? { recursionLimit: start.recursionLimit } : {},
|
|
1236
|
+
signal: turn.abortSignal
|
|
1237
|
+
};
|
|
1238
|
+
const nextAgentConfigurationSignature = JSON.stringify({
|
|
1239
|
+
instructions: start.instructions,
|
|
1240
|
+
tools: start.tools,
|
|
1241
|
+
skillsPaths: start.skillsPaths
|
|
1242
|
+
});
|
|
1243
|
+
if (agent == null || agentConfigurationSignature !== nextAgentConfigurationSignature || start.skillsChanged === true) {
|
|
1244
|
+
if (agent != null && start.skillsChanged === true) await agent.updateState(config, { skillsMetadata: new Overwrite([]) });
|
|
1245
|
+
await closeMcpClient();
|
|
1246
|
+
const builtinToolFilteringMiddleware = createBuiltinToolFilteringMiddleware({
|
|
1247
|
+
builtinToolFiltering: start.builtinToolFiltering,
|
|
1248
|
+
emit: (event) => {
|
|
1249
|
+
const turn = currentTurn;
|
|
1250
|
+
if (!turn) throw new Error("no active turn");
|
|
1251
|
+
turn.emit(event);
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
const middleware = [
|
|
1255
|
+
responseFormatMiddleware,
|
|
1256
|
+
modelMiddleware,
|
|
1257
|
+
...builtinToolFilteringMiddleware ? [builtinToolFilteringMiddleware] : []
|
|
1258
|
+
];
|
|
1259
|
+
const hostTools = buildHostTools(start.tools);
|
|
1260
|
+
const hostToolNames = new Set(hostTools.map((hostTool) => hostTool.name));
|
|
1261
|
+
const mcpTools = (await loadMcpTools({ mcpServers: start.mcpServers })).filter((externalTool) => !hostToolNames.has(externalTool.name));
|
|
1262
|
+
mcpToolNames = new Set(mcpTools.map((mcpTool) => mcpTool.name));
|
|
1263
|
+
agent = createDeepAgent({
|
|
1264
|
+
tools: [...mcpTools, ...hostTools],
|
|
1265
|
+
backend: createLocalShellBackend({ rootDir: workdir }),
|
|
1266
|
+
systemPrompt: start.instructions ? { suffix: start.instructions } : void 0,
|
|
1267
|
+
...start.skillsPaths?.length ? { skills: start.skillsPaths } : {},
|
|
1268
|
+
...middleware.length > 0 ? { middleware } : {},
|
|
1269
|
+
...interruptOn ? { interruptOn } : {},
|
|
1270
|
+
checkpointer
|
|
1271
|
+
});
|
|
1272
|
+
agentConfigurationSignature = nextAgentConfigurationSignature;
|
|
1273
|
+
}
|
|
1274
|
+
const activeAgent = agent;
|
|
1275
|
+
if (activeAgent == null) throw new Error("Deep Agents runtime was not initialized");
|
|
1276
|
+
const hostToolNames = new Set((start.tools ?? []).map((t) => t.name));
|
|
1277
|
+
const streamEventState = createDeepAgentsStreamEventState();
|
|
1278
|
+
const emitStreamEvent = createEmitStreamEvent({
|
|
1279
|
+
state: streamEventState,
|
|
1280
|
+
configuredModel: activeModel,
|
|
1281
|
+
hostToolNames,
|
|
1282
|
+
mcpToolNames,
|
|
1283
|
+
structuredOutputToolNames: new Set(currentResponseFormat?.map((format) => format.name)),
|
|
1284
|
+
emit
|
|
1285
|
+
});
|
|
1286
|
+
const readPendingApprovals = async () => {
|
|
1287
|
+
try {
|
|
1288
|
+
return collectActionRequests(((await activeAgent.getState({ configurable: { thread_id: "bridge-session" } })).tasks ?? []).flatMap((t) => t.interrupts ?? []));
|
|
1289
|
+
} catch {
|
|
1290
|
+
return [];
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
let resumeInput = { messages: [{
|
|
1294
|
+
role: "user",
|
|
1295
|
+
content: start.prompt
|
|
1296
|
+
}] };
|
|
1297
|
+
let emittedStructuredOutput = false;
|
|
1298
|
+
while (true) {
|
|
1299
|
+
const stream = await activeAgent.streamEvents(resumeInput, config);
|
|
1300
|
+
for await (const event of stream) {
|
|
1301
|
+
emitStreamEvent(event);
|
|
1302
|
+
const streamEvent = event;
|
|
1303
|
+
const namespace = streamEvent.metadata?.langgraph_checkpoint_ns ?? "";
|
|
1304
|
+
const output = streamEvent.data?.output;
|
|
1305
|
+
if (!emittedStructuredOutput && streamEvent.event === "on_chain_end" && !namespace.includes("|") && output?.structuredResponse !== void 0) {
|
|
1306
|
+
const id = `structured-output-${randomUUID()}`;
|
|
1307
|
+
emit({
|
|
1308
|
+
type: "text-start",
|
|
1309
|
+
id
|
|
1310
|
+
});
|
|
1311
|
+
emit({
|
|
1312
|
+
type: "text-delta",
|
|
1313
|
+
id,
|
|
1314
|
+
delta: JSON.stringify(output.structuredResponse)
|
|
1315
|
+
});
|
|
1316
|
+
emit({
|
|
1317
|
+
type: "text-end",
|
|
1318
|
+
id
|
|
1319
|
+
});
|
|
1320
|
+
emittedStructuredOutput = true;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
const actionRequests = await readPendingApprovals();
|
|
1324
|
+
if (actionRequests.length === 0) break;
|
|
1325
|
+
const decisions = [];
|
|
1326
|
+
for (const action of actionRequests) {
|
|
1327
|
+
const approvalId = `approval-${randomUUID()}`;
|
|
1328
|
+
endTextBlock({
|
|
1329
|
+
state: streamEventState,
|
|
1330
|
+
emit
|
|
1331
|
+
});
|
|
1332
|
+
endReasoningBlock({
|
|
1333
|
+
state: streamEventState,
|
|
1334
|
+
emit
|
|
1335
|
+
});
|
|
1336
|
+
emit({
|
|
1337
|
+
type: "tool-call",
|
|
1338
|
+
toolCallId: approvalId,
|
|
1339
|
+
toolName: toCommonName(action.name),
|
|
1340
|
+
input: JSON.stringify(action.args ?? {}),
|
|
1341
|
+
providerExecuted: true,
|
|
1342
|
+
nativeName: action.name
|
|
1343
|
+
});
|
|
1344
|
+
emit({
|
|
1345
|
+
type: "tool-approval-request",
|
|
1346
|
+
approvalId,
|
|
1347
|
+
toolCallId: approvalId
|
|
1348
|
+
});
|
|
1349
|
+
flushStep({
|
|
1350
|
+
state: streamEventState,
|
|
1351
|
+
emit
|
|
1352
|
+
});
|
|
1353
|
+
const decision = await turn.requestToolApproval(approvalId);
|
|
1354
|
+
if (decision.approved) {
|
|
1355
|
+
const queue = streamEventState.approvedToolQueue.get(action.name) ?? [];
|
|
1356
|
+
queue.push(approvalId);
|
|
1357
|
+
streamEventState.approvedToolQueue.set(action.name, queue);
|
|
1358
|
+
decisions.push({ type: "approve" });
|
|
1359
|
+
} else {
|
|
1360
|
+
emit({
|
|
1361
|
+
type: "tool-result",
|
|
1362
|
+
toolCallId: approvalId,
|
|
1363
|
+
toolName: toCommonName(action.name),
|
|
1364
|
+
result: decision.reason ?? "Rejected by user."
|
|
1365
|
+
});
|
|
1366
|
+
decisions.push({
|
|
1367
|
+
type: "reject",
|
|
1368
|
+
...decision.reason ? { message: decision.reason } : {}
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
resumeInput = new Command({ resume: { decisions } });
|
|
1373
|
+
}
|
|
1374
|
+
endTextBlock({
|
|
1375
|
+
state: streamEventState,
|
|
1376
|
+
emit
|
|
1377
|
+
});
|
|
1378
|
+
endReasoningBlock({
|
|
1379
|
+
state: streamEventState,
|
|
1380
|
+
emit
|
|
1381
|
+
});
|
|
1382
|
+
flushStep({
|
|
1383
|
+
state: streamEventState,
|
|
1384
|
+
emit
|
|
1385
|
+
});
|
|
1386
|
+
emit({
|
|
1387
|
+
type: "finish",
|
|
1388
|
+
finishReason: { unified: "stop" },
|
|
1389
|
+
totalUsage: {
|
|
1390
|
+
inputTokens: { total: streamEventState.inputTokens },
|
|
1391
|
+
outputTokens: { total: streamEventState.outputTokens }
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
2439
1394
|
}
|
|
2440
1395
|
await runBridge({
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
1396
|
+
bridgeType: "deepagents",
|
|
1397
|
+
bridgeStateDir,
|
|
1398
|
+
onStart: runTurn,
|
|
1399
|
+
onStop: async () => {
|
|
1400
|
+
await closeMcpClient();
|
|
1401
|
+
await saveMemorySaver({
|
|
1402
|
+
path: conversationCheckpointPath,
|
|
1403
|
+
saver: checkpointer
|
|
1404
|
+
});
|
|
1405
|
+
return {};
|
|
1406
|
+
},
|
|
1407
|
+
onDestroy: async () => {
|
|
1408
|
+
await closeMcpClient();
|
|
1409
|
+
await removeMemorySaverSnapshot(conversationCheckpointPath);
|
|
1410
|
+
}
|
|
2456
1411
|
});
|
|
2457
|
-
async function loadMcpTools({
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
}
|
|
2467
|
-
}
|
|
2468
|
-
mcpClient = new MultiServerMCPClient({
|
|
2469
|
-
mcpServers,
|
|
2470
|
-
prefixToolNameWithServerName: true,
|
|
2471
|
-
additionalToolNamePrefix: "mcp"
|
|
2472
|
-
});
|
|
2473
|
-
return mcpClient.getTools();
|
|
1412
|
+
async function loadMcpTools({ mcpServers }) {
|
|
1413
|
+
if (mcpServers == null || Object.keys(mcpServers).length === 0) return [];
|
|
1414
|
+
for (const [name, value] of Object.entries(mcpServers)) if (value == null || typeof value !== "object" || Array.isArray(value)) throw new Error(`DeepAgents MCP server ${JSON.stringify(name)} must be configured with an object value.`);
|
|
1415
|
+
mcpClient = new MultiServerMCPClient({
|
|
1416
|
+
mcpServers,
|
|
1417
|
+
prefixToolNameWithServerName: true,
|
|
1418
|
+
additionalToolNamePrefix: "mcp"
|
|
1419
|
+
});
|
|
1420
|
+
return mcpClient.getTools();
|
|
2474
1421
|
}
|
|
2475
1422
|
async function closeMcpClient() {
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
1423
|
+
const client = mcpClient;
|
|
1424
|
+
mcpClient = void 0;
|
|
1425
|
+
mcpToolNames = /* @__PURE__ */ new Set();
|
|
1426
|
+
await client?.close();
|
|
2480
1427
|
}
|
|
1428
|
+
//#endregion
|
|
1429
|
+
export {};
|
|
1430
|
+
|
|
2481
1431
|
//# sourceMappingURL=index.mjs.map
|