stitchkit 0.90.7 → 0.91.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -0
- package/dist/agent-runtime-coding-tools.js +4 -4
- package/dist/agent-runtime-harness.js +6 -6
- package/dist/agent-runtime-sandbox.js +4 -4
- package/dist/agent-runtime.js +18 -17
- package/dist/application-grammy.js +1 -1
- package/dist/application.js +3 -3
- package/dist/cli.js +7 -7
- package/dist/contract/errors-factory.d.ts +12 -0
- package/dist/contract/errors-factory.d.ts.map +1 -1
- package/dist/contract/errors.d.ts +35 -1
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +4 -2
- package/dist/{index-nrqg8tks.js → index-0a349c33.js} +3 -3
- package/dist/index-0j3vcp5m.js +28 -0
- package/dist/{index-vy2nxwg8.js → index-137jjs4v.js} +2 -2
- package/dist/{index-2hryh65w.js → index-13cjtmrw.js} +54 -13
- package/dist/{index-7gqx71yd.js → index-13e1k7v9.js} +9 -3
- package/dist/{index-1bnkzq95.js → index-1qvdwnp2.js} +10 -3
- package/dist/{index-scs3f1eg.js → index-2vtcmrj9.js} +8 -2
- package/dist/{index-xbppf54a.js → index-6kyksz9y.js} +12 -7
- package/dist/{index-aj9geeez.js → index-709nh7z7.js} +37 -17
- package/dist/{index-zkcqhxx8.js → index-a11g2kry.js} +1 -1
- package/dist/{index-1txvygak.js → index-b971qjes.js} +1 -1
- package/dist/{index-tgh3ksfh.js → index-bh70rk41.js} +3 -3
- package/dist/{index-bva395we.js → index-bv7mytab.js} +2 -2
- package/dist/{index-s208wab5.js → index-bx6yq2m4.js} +23 -495
- package/dist/{index-83fafqw8.js → index-f4p4b8f6.js} +10 -11
- package/dist/index-kw9t5ayn.js +507 -0
- package/dist/{index-8pjqv3zh.js → index-mqhjmadk.js} +43 -21
- package/dist/{index-3yqgj323.js → index-qjeyx5t2.js} +2 -2
- package/dist/{index-gte38nbm.js → index-qmy6zq75.js} +1 -1
- package/dist/{index-zsdgd1tz.js → index-qrbdq8jk.js} +1 -1
- package/dist/{index-fqg5mfk7.js → index-ya611vx3.js} +4 -4
- package/dist/{index-640tz39q.js → index-zsqy3xfn.js} +5 -5
- package/dist/index.js +8 -6
- package/dist/internal/canonical-json.d.ts +20 -0
- package/dist/internal/canonical-json.d.ts.map +1 -0
- package/dist/internal/errors.d.ts +13 -4
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/node.js +6 -6
- package/dist/observability/bounded-logger.d.ts +2 -0
- package/dist/observability/bounded-logger.d.ts.map +1 -1
- package/dist/observability/index.js +7 -4
- package/dist/observability/sanitize.d.ts +15 -0
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/primitives.js +2 -2
- package/dist/realtime/rejected-frame.d.ts +6 -0
- package/dist/realtime/rejected-frame.d.ts.map +1 -1
- package/dist/remote.js +5 -5
- package/dist/server/implement.d.ts +33 -7
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -8
- package/dist/testing/surface-manifest.d.ts +2 -1
- package/dist/testing/surface-manifest.d.ts.map +1 -1
- package/dist/testing.js +11 -27
- package/dist/tool-invoker.js +6 -6
- package/dist/tools/agent.d.ts +12 -0
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/cli-format.d.ts +1 -1
- package/dist/tools/connections/index.js +1 -1
- package/dist/tools/durability-context.d.ts +1 -1
- package/dist/tools/durability-context.d.ts.map +1 -1
- package/dist/tools/durability-port.d.ts +55 -0
- package/dist/tools/durability-port.d.ts.map +1 -0
- package/dist/tools/execute.d.ts +59 -1
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/mcp-catalog.d.ts +68 -0
- package/dist/tools/mcp-catalog.d.ts.map +1 -0
- package/dist/tools/mcp.d.ts +3 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mount.d.ts +2 -2
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-mcp.d.ts +3 -0
- package/dist/tools/native-mcp.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +1 -1
- package/dist/tools/runtime-tool.d.ts.map +1 -1
- package/dist/tools.d.ts +5 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +99 -20
- package/dist/tracking.js +2 -2
- package/llms-full.txt +258 -8
- package/package.json +2 -2
- package/dist/index-7rkhw9ec.js +0 -34
|
@@ -30,13 +30,14 @@ import {
|
|
|
30
30
|
createBoundedSinkManager
|
|
31
31
|
} from "./index-wnfk50r0.js";
|
|
32
32
|
import {
|
|
33
|
+
createLocalStepDurability,
|
|
33
34
|
createToolDurabilityContext,
|
|
34
35
|
isAgentToolError
|
|
35
|
-
} from "./index-
|
|
36
|
+
} from "./index-kw9t5ayn.js";
|
|
36
37
|
import {
|
|
37
38
|
ToolExecutionControlError,
|
|
38
39
|
isToolExecutionControlError
|
|
39
|
-
} from "./index-
|
|
40
|
+
} from "./index-mqhjmadk.js";
|
|
40
41
|
import {
|
|
41
42
|
isRecord,
|
|
42
43
|
transportResult
|
|
@@ -316,479 +317,6 @@ function createAgentSessionCoordinator() {
|
|
|
316
317
|
};
|
|
317
318
|
}
|
|
318
319
|
|
|
319
|
-
// src/agent-runtime/durability-contract.ts
|
|
320
|
-
import { z } from "zod";
|
|
321
|
-
var DURABILITY_STEP_EVENT_KIND = "durability/step";
|
|
322
|
-
var DURABILITY_PARK_EVENT_KIND = "durability/park";
|
|
323
|
-
var DURABILITY_EVENT_EVENT_KIND = "durability/event";
|
|
324
|
-
var StepEventPayloadSchema = z.object({
|
|
325
|
-
runId: z.string().min(1),
|
|
326
|
-
stepName: z.string().min(1),
|
|
327
|
-
encoded: z.string()
|
|
328
|
-
});
|
|
329
|
-
var SleepParkSchema = z.object({
|
|
330
|
-
runId: z.string().min(1),
|
|
331
|
-
kind: z.literal("sleep"),
|
|
332
|
-
name: z.string().min(1),
|
|
333
|
-
deadline: z.number()
|
|
334
|
-
});
|
|
335
|
-
var WaitParkSchema = z.object({
|
|
336
|
-
runId: z.string().min(1),
|
|
337
|
-
kind: z.literal("wait"),
|
|
338
|
-
event: z.string().min(1),
|
|
339
|
-
id: z.string().min(1)
|
|
340
|
-
});
|
|
341
|
-
var ParkEventPayloadSchema = z.discriminatedUnion("kind", [
|
|
342
|
-
SleepParkSchema,
|
|
343
|
-
WaitParkSchema
|
|
344
|
-
]);
|
|
345
|
-
var DeliveredEventPayloadSchema = z.object({
|
|
346
|
-
runId: z.string().min(1),
|
|
347
|
-
event: z.string().min(1),
|
|
348
|
-
id: z.string().min(1),
|
|
349
|
-
encoded: z.string()
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
class StepResultDecodeError extends Error {
|
|
353
|
-
constructor(message, options) {
|
|
354
|
-
super(message, options);
|
|
355
|
-
this.name = "StepResultDecodeError";
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
class StepResultNotSerializableError extends Error {
|
|
360
|
-
constructor(stepName, cause) {
|
|
361
|
-
super(`Step "${stepName}" returned a value that is not JSON-serializable`, {
|
|
362
|
-
cause
|
|
363
|
-
});
|
|
364
|
-
this.name = "StepResultNotSerializableError";
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
class StepAbortedError extends Error {
|
|
369
|
-
constructor(stepName) {
|
|
370
|
-
super(`Step "${stepName}" was aborted before it started`);
|
|
371
|
-
this.name = "StepAbortedError";
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
class ParkRecordDecodeError extends Error {
|
|
376
|
-
constructor(message, options) {
|
|
377
|
-
super(message, options);
|
|
378
|
-
this.name = "ParkRecordDecodeError";
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
class ParkAbortedError extends Error {
|
|
383
|
-
constructor(park) {
|
|
384
|
-
super(`Park "${park}" was aborted before it was satisfied`);
|
|
385
|
-
this.name = "ParkAbortedError";
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// src/agent-runtime/durability-json.ts
|
|
390
|
-
import { z as z2 } from "zod";
|
|
391
|
-
function losslessJson(value, ancestors = new Set, depth = 0) {
|
|
392
|
-
if (depth > 100)
|
|
393
|
-
return false;
|
|
394
|
-
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
395
|
-
return true;
|
|
396
|
-
if (typeof value === "number")
|
|
397
|
-
return Number.isFinite(value) && !Object.is(value, -0);
|
|
398
|
-
if (typeof value !== "object" || ancestors.has(value))
|
|
399
|
-
return false;
|
|
400
|
-
const array = Array.isArray(value);
|
|
401
|
-
const prototype = Object.getPrototypeOf(value);
|
|
402
|
-
if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null)
|
|
403
|
-
return false;
|
|
404
|
-
ancestors.add(value);
|
|
405
|
-
try {
|
|
406
|
-
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
407
|
-
const keys = Reflect.ownKeys(descriptors);
|
|
408
|
-
if (array && keys.length !== value.length + 1)
|
|
409
|
-
return false;
|
|
410
|
-
for (const key of keys) {
|
|
411
|
-
if (array && key === "length")
|
|
412
|
-
continue;
|
|
413
|
-
if (typeof key !== "string")
|
|
414
|
-
return false;
|
|
415
|
-
if (array && (!/^(0|[1-9][0-9]*)$/.test(key) || Number(key) >= value.length))
|
|
416
|
-
return false;
|
|
417
|
-
const descriptor = descriptors[key];
|
|
418
|
-
if (!descriptor?.enumerable || !("value" in descriptor))
|
|
419
|
-
return false;
|
|
420
|
-
if (!losslessJson(descriptor.value, ancestors, depth + 1))
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
return true;
|
|
424
|
-
} finally {
|
|
425
|
-
ancestors.delete(value);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
var DurableJsonSchema = z2.custom((value) => losslessJson(value), "Expected lossless JSON data (finite numbers, plain objects and dense arrays; no accessors)");
|
|
429
|
-
|
|
430
|
-
// src/agent-runtime/durability-ledger.ts
|
|
431
|
-
function stepKey(conversationId, runId, stepName) {
|
|
432
|
-
return JSON.stringify([conversationId, runId, stepName]);
|
|
433
|
-
}
|
|
434
|
-
function sleepParkKey(conversationId, runId, name) {
|
|
435
|
-
return JSON.stringify([conversationId, runId, "sleep", name]);
|
|
436
|
-
}
|
|
437
|
-
function waitParkKey(conversationId, runId, event, id) {
|
|
438
|
-
return JSON.stringify([conversationId, runId, "wait", event, id]);
|
|
439
|
-
}
|
|
440
|
-
function parkEventKey(conversationId, payload) {
|
|
441
|
-
return payload.kind === "sleep" ? sleepParkKey(conversationId, payload.runId, payload.name) : waitParkKey(conversationId, payload.runId, payload.event, payload.id);
|
|
442
|
-
}
|
|
443
|
-
function encodeStepResult(stepName, value) {
|
|
444
|
-
let encoded;
|
|
445
|
-
try {
|
|
446
|
-
encoded = JSON.stringify(DurableJsonSchema.parse(value));
|
|
447
|
-
} catch (cause) {
|
|
448
|
-
throw new StepResultNotSerializableError(stepName, cause);
|
|
449
|
-
}
|
|
450
|
-
if (encoded === undefined) {
|
|
451
|
-
throw new StepResultNotSerializableError(stepName, value);
|
|
452
|
-
}
|
|
453
|
-
return encoded;
|
|
454
|
-
}
|
|
455
|
-
function encodeDeliveredPayload(event, id, payload) {
|
|
456
|
-
let encoded;
|
|
457
|
-
try {
|
|
458
|
-
encoded = JSON.stringify(DurableJsonSchema.parse(payload === undefined ? null : payload));
|
|
459
|
-
} catch (cause) {
|
|
460
|
-
throw new TypeError(`Delivered event "${event}#${id}" payload is not JSON-serializable`, {
|
|
461
|
-
cause
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
if (encoded === undefined) {
|
|
465
|
-
throw new TypeError(`Delivered event "${event}#${id}" payload is not JSON-serializable`);
|
|
466
|
-
}
|
|
467
|
-
return encoded;
|
|
468
|
-
}
|
|
469
|
-
function decodeStepPayload(event) {
|
|
470
|
-
const parsed = StepEventPayloadSchema.safeParse(event.payload);
|
|
471
|
-
if (!parsed.success) {
|
|
472
|
-
throw new StepResultDecodeError(`Recorded step event ${event.eventId} in conversation ${event.conversationId} is malformed`, { cause: parsed.error });
|
|
473
|
-
}
|
|
474
|
-
return parsed.data;
|
|
475
|
-
}
|
|
476
|
-
function decodeRecordedResult(payload, event) {
|
|
477
|
-
try {
|
|
478
|
-
return DurableJsonSchema.parse(JSON.parse(payload.encoded));
|
|
479
|
-
} catch (cause) {
|
|
480
|
-
throw new StepResultDecodeError(`Recorded result for step "${payload.stepName}" (run ${payload.runId}, ` + `event ${event.eventId}) is not decodable JSON`, { cause });
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
function decodeParkPayload(event) {
|
|
484
|
-
const parsed = ParkEventPayloadSchema.safeParse(event.payload);
|
|
485
|
-
if (!parsed.success) {
|
|
486
|
-
throw new ParkRecordDecodeError(`Recorded park event ${event.eventId} in conversation ${event.conversationId} is malformed`, { cause: parsed.error });
|
|
487
|
-
}
|
|
488
|
-
return parsed.data;
|
|
489
|
-
}
|
|
490
|
-
function decodeDeliveredPayload(event) {
|
|
491
|
-
const parsed = DeliveredEventPayloadSchema.safeParse(event.payload);
|
|
492
|
-
if (!parsed.success) {
|
|
493
|
-
throw new ParkRecordDecodeError(`Delivered event ${event.eventId} in conversation ${event.conversationId} is malformed`, { cause: parsed.error });
|
|
494
|
-
}
|
|
495
|
-
return parsed.data;
|
|
496
|
-
}
|
|
497
|
-
function decodeDeliveredResult(payload, event) {
|
|
498
|
-
try {
|
|
499
|
-
return JSON.parse(payload.encoded);
|
|
500
|
-
} catch (cause) {
|
|
501
|
-
throw new ParkRecordDecodeError(`Delivered payload for "${payload.event}#${payload.id}" (run ${payload.runId}, ` + `event ${event.eventId}) is not decodable JSON`, { cause });
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
async function readDurabilityLedger(store, conversationId, view) {
|
|
505
|
-
const { steps, parks, deliveries } = view;
|
|
506
|
-
let fromSeq = view.nextSeq;
|
|
507
|
-
for (;; ) {
|
|
508
|
-
const page = await store.readEvents({
|
|
509
|
-
conversationId,
|
|
510
|
-
...fromSeq !== undefined && { fromSeq },
|
|
511
|
-
limit: 1e4
|
|
512
|
-
});
|
|
513
|
-
for (const event of page.items) {
|
|
514
|
-
if (event.kind === DURABILITY_STEP_EVENT_KIND) {
|
|
515
|
-
const payload = decodeStepPayload(event);
|
|
516
|
-
steps.set(stepKey(event.conversationId, payload.runId, payload.stepName), decodeRecordedResult(payload, event));
|
|
517
|
-
} else if (event.kind === DURABILITY_PARK_EVENT_KIND) {
|
|
518
|
-
const payload = decodeParkPayload(event);
|
|
519
|
-
parks.set(parkEventKey(event.conversationId, payload), payload);
|
|
520
|
-
} else if (event.kind === DURABILITY_EVENT_EVENT_KIND) {
|
|
521
|
-
const payload = decodeDeliveredPayload(event);
|
|
522
|
-
const key = waitParkKey(event.conversationId, payload.runId, payload.event, payload.id);
|
|
523
|
-
if (!deliveries.has(key))
|
|
524
|
-
deliveries.set(key, decodeDeliveredResult(payload, event));
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
const last = page.items.at(-1);
|
|
528
|
-
if (last)
|
|
529
|
-
view.nextSeq = last.seq + 1;
|
|
530
|
-
if (page.nextSeq === undefined)
|
|
531
|
-
break;
|
|
532
|
-
fromSeq = page.nextSeq;
|
|
533
|
-
}
|
|
534
|
-
return view;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// src/agent-runtime/durability-scheduler.ts
|
|
538
|
-
var systemClock = {
|
|
539
|
-
now: () => Date.now(),
|
|
540
|
-
schedule(callback, delayMs) {
|
|
541
|
-
const timer = setTimeout(callback, Math.min(delayMs, 2147483647));
|
|
542
|
-
timer.unref();
|
|
543
|
-
return { cancel: () => clearTimeout(timer) };
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
var stores = new WeakMap;
|
|
547
|
-
function notifyWaiters(parkWaiters, key) {
|
|
548
|
-
const waiters = parkWaiters.get(key);
|
|
549
|
-
if (!waiters)
|
|
550
|
-
return;
|
|
551
|
-
for (const wake of [...waiters])
|
|
552
|
-
wake();
|
|
553
|
-
}
|
|
554
|
-
function waitForTimer(clock, delayMs, signal) {
|
|
555
|
-
return new Promise((resolve) => {
|
|
556
|
-
let timer;
|
|
557
|
-
let settled = false;
|
|
558
|
-
const finish = (outcome) => {
|
|
559
|
-
if (settled)
|
|
560
|
-
return;
|
|
561
|
-
settled = true;
|
|
562
|
-
timer?.cancel();
|
|
563
|
-
signal?.removeEventListener("abort", onAbort);
|
|
564
|
-
resolve(outcome);
|
|
565
|
-
};
|
|
566
|
-
const onAbort = () => finish("aborted");
|
|
567
|
-
timer = clock.schedule(() => finish("elapsed"), delayMs);
|
|
568
|
-
if (signal) {
|
|
569
|
-
if (signal.aborted)
|
|
570
|
-
onAbort();
|
|
571
|
-
else
|
|
572
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
async function waitForDeadline(clock, deadline, park, signal) {
|
|
577
|
-
for (;; ) {
|
|
578
|
-
if (signal?.aborted)
|
|
579
|
-
throw new ParkAbortedError(park);
|
|
580
|
-
const remaining = deadline - clock.now();
|
|
581
|
-
if (remaining <= 0)
|
|
582
|
-
return;
|
|
583
|
-
const outcome = await waitForTimer(clock, remaining, signal);
|
|
584
|
-
if (outcome === "aborted")
|
|
585
|
-
throw new ParkAbortedError(park);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
function createParkWaiter(parkWaiters, key, signal) {
|
|
589
|
-
const waiters = parkWaiters.get(key) ?? new Set;
|
|
590
|
-
parkWaiters.set(key, waiters);
|
|
591
|
-
let settle;
|
|
592
|
-
const outcome = new Promise((resolve) => {
|
|
593
|
-
settle = resolve;
|
|
594
|
-
});
|
|
595
|
-
let settled = false;
|
|
596
|
-
const cleanup = () => {
|
|
597
|
-
waiters.delete(onWake);
|
|
598
|
-
if (waiters.size === 0)
|
|
599
|
-
parkWaiters.delete(key);
|
|
600
|
-
signal?.removeEventListener("abort", onAbort);
|
|
601
|
-
};
|
|
602
|
-
const finish = (result) => {
|
|
603
|
-
if (settled)
|
|
604
|
-
return;
|
|
605
|
-
settled = true;
|
|
606
|
-
cleanup();
|
|
607
|
-
settle(result);
|
|
608
|
-
};
|
|
609
|
-
const onWake = () => finish("woke");
|
|
610
|
-
const onAbort = () => finish("aborted");
|
|
611
|
-
waiters.add(onWake);
|
|
612
|
-
if (signal) {
|
|
613
|
-
if (signal.aborted)
|
|
614
|
-
onAbort();
|
|
615
|
-
else
|
|
616
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
617
|
-
}
|
|
618
|
-
return { outcome, cancel: cleanup };
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
// src/agent-runtime/durability.ts
|
|
622
|
-
function releaseSettled(registry, key, pending) {
|
|
623
|
-
const release = () => {
|
|
624
|
-
if (registry.get(key) === pending)
|
|
625
|
-
registry.delete(key);
|
|
626
|
-
};
|
|
627
|
-
pending.then(release, release);
|
|
628
|
-
}
|
|
629
|
-
function detachedResult(pending) {
|
|
630
|
-
return pending.then((value) => JSON.parse(JSON.stringify(value)));
|
|
631
|
-
}
|
|
632
|
-
function createLocalStepDurability(options) {
|
|
633
|
-
const { store, conversationId, runId } = options;
|
|
634
|
-
const inFlight = stores.get(store) ?? {
|
|
635
|
-
steps: new Map,
|
|
636
|
-
parks: new Map,
|
|
637
|
-
waiters: new Map
|
|
638
|
-
};
|
|
639
|
-
stores.set(store, inFlight);
|
|
640
|
-
const { steps: inFlightSteps, parks: inFlightParks, waiters: parkWaiters } = inFlight;
|
|
641
|
-
const clock = options.clock ?? systemClock;
|
|
642
|
-
const view = {
|
|
643
|
-
steps: new Map,
|
|
644
|
-
parks: new Map,
|
|
645
|
-
deliveries: new Map,
|
|
646
|
-
nextSeq: 1
|
|
647
|
-
};
|
|
648
|
-
let reading = Promise.resolve(view);
|
|
649
|
-
const readLedger = () => {
|
|
650
|
-
reading = reading.catch(() => view).then(() => readDurabilityLedger(store, conversationId, view));
|
|
651
|
-
return reading;
|
|
652
|
-
};
|
|
653
|
-
const readRecordedStep = async (name) => {
|
|
654
|
-
const key = stepKey(conversationId, runId, name);
|
|
655
|
-
const records = await readLedger();
|
|
656
|
-
const value = records.steps.get(key);
|
|
657
|
-
return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
|
|
658
|
-
};
|
|
659
|
-
const execute = async (name, body, runOptions) => {
|
|
660
|
-
const recorded = await readRecordedStep(name);
|
|
661
|
-
if (recorded !== undefined) {
|
|
662
|
-
return recorded;
|
|
663
|
-
}
|
|
664
|
-
if (runOptions?.signal?.aborted || options.signal?.aborted)
|
|
665
|
-
throw new StepAbortedError(name);
|
|
666
|
-
const value = await body();
|
|
667
|
-
const encoded = encodeStepResult(name, value);
|
|
668
|
-
await store.appendEvent({
|
|
669
|
-
conversationId,
|
|
670
|
-
kind: DURABILITY_STEP_EVENT_KIND,
|
|
671
|
-
payload: { runId, stepName: name, encoded }
|
|
672
|
-
});
|
|
673
|
-
return JSON.parse(encoded);
|
|
674
|
-
};
|
|
675
|
-
const step = (name, body, runOptions) => {
|
|
676
|
-
const key = stepKey(conversationId, runId, name);
|
|
677
|
-
const existing = inFlightSteps.get(key);
|
|
678
|
-
if (existing) {
|
|
679
|
-
return detachedResult(existing);
|
|
680
|
-
}
|
|
681
|
-
const pending = execute(name, body, runOptions);
|
|
682
|
-
inFlightSteps.set(key, pending);
|
|
683
|
-
releaseSettled(inFlightSteps, key, pending);
|
|
684
|
-
return detachedResult(pending);
|
|
685
|
-
};
|
|
686
|
-
const executeSleep = async (name, seconds, runOptions) => {
|
|
687
|
-
const key = sleepParkKey(conversationId, runId, name);
|
|
688
|
-
const signal = options.signal && runOptions?.signal ? AbortSignal.any([options.signal, runOptions.signal]) : runOptions?.signal ?? options.signal;
|
|
689
|
-
const ledger = await readLedger();
|
|
690
|
-
const existing = ledger.parks.get(key);
|
|
691
|
-
let deadline;
|
|
692
|
-
if (existing) {
|
|
693
|
-
if (existing.kind !== "sleep") {
|
|
694
|
-
throw new ParkRecordDecodeError(`Recorded park "${name}" is not a sleep record`);
|
|
695
|
-
}
|
|
696
|
-
deadline = existing.deadline;
|
|
697
|
-
} else {
|
|
698
|
-
deadline = clock.now() + seconds * 1000;
|
|
699
|
-
if (!Number.isSafeInteger(Math.ceil(deadline)))
|
|
700
|
-
throw new TypeError("Sleep deadline exceeds the supported clock range");
|
|
701
|
-
await store.appendEvent({
|
|
702
|
-
conversationId,
|
|
703
|
-
kind: DURABILITY_PARK_EVENT_KIND,
|
|
704
|
-
payload: { runId, kind: "sleep", name, deadline }
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
if (signal?.aborted)
|
|
708
|
-
throw new ParkAbortedError(name);
|
|
709
|
-
await waitForDeadline(clock, deadline, name, signal);
|
|
710
|
-
};
|
|
711
|
-
const sleep = (input, runOptions) => {
|
|
712
|
-
const { seconds } = input;
|
|
713
|
-
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
714
|
-
throw new TypeError(`sleep seconds must be a non-negative finite number, got ${String(seconds)}`);
|
|
715
|
-
}
|
|
716
|
-
const name = input.name ?? `sleep:${seconds}`;
|
|
717
|
-
const key = sleepParkKey(conversationId, runId, name);
|
|
718
|
-
const existing = inFlightParks.get(key);
|
|
719
|
-
if (existing) {
|
|
720
|
-
return existing;
|
|
721
|
-
}
|
|
722
|
-
const pending = executeSleep(name, seconds, runOptions);
|
|
723
|
-
inFlightParks.set(key, pending);
|
|
724
|
-
releaseSettled(inFlightParks, key, pending);
|
|
725
|
-
return pending;
|
|
726
|
-
};
|
|
727
|
-
const executeWait = async (eventName, id, runOptions) => {
|
|
728
|
-
const key = waitParkKey(conversationId, runId, eventName, id);
|
|
729
|
-
const park = `${eventName}#${id}`;
|
|
730
|
-
const signal = options.signal && runOptions?.signal ? AbortSignal.any([options.signal, runOptions.signal]) : runOptions?.signal ?? options.signal;
|
|
731
|
-
for (;; ) {
|
|
732
|
-
if (signal?.aborted)
|
|
733
|
-
throw new ParkAbortedError(park);
|
|
734
|
-
const waiter = createParkWaiter(parkWaiters, key, signal);
|
|
735
|
-
let unsubscribe;
|
|
736
|
-
try {
|
|
737
|
-
unsubscribe = options.subscribe?.(() => notifyWaiters(parkWaiters, key));
|
|
738
|
-
const ledger = await readLedger();
|
|
739
|
-
if (ledger.deliveries.has(key)) {
|
|
740
|
-
return JSON.parse(JSON.stringify(ledger.deliveries.get(key)));
|
|
741
|
-
}
|
|
742
|
-
if (!ledger.parks.has(key)) {
|
|
743
|
-
await store.appendEvent({
|
|
744
|
-
conversationId,
|
|
745
|
-
kind: DURABILITY_PARK_EVENT_KIND,
|
|
746
|
-
payload: { runId, kind: "wait", event: eventName, id }
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
const outcome = await waiter.outcome;
|
|
750
|
-
if (outcome === "aborted")
|
|
751
|
-
throw new ParkAbortedError(park);
|
|
752
|
-
} finally {
|
|
753
|
-
waiter.cancel();
|
|
754
|
-
unsubscribe?.();
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
const waitFor = (input, runOptions) => {
|
|
759
|
-
const key = waitParkKey(conversationId, runId, input.event, input.id);
|
|
760
|
-
const existing = inFlightParks.get(key);
|
|
761
|
-
if (existing) {
|
|
762
|
-
return detachedResult(existing);
|
|
763
|
-
}
|
|
764
|
-
const pending = executeWait(input.event, input.id, runOptions);
|
|
765
|
-
inFlightParks.set(key, pending);
|
|
766
|
-
releaseSettled(inFlightParks, key, pending);
|
|
767
|
-
return detachedResult(pending);
|
|
768
|
-
};
|
|
769
|
-
const deliver = async (input) => {
|
|
770
|
-
const key = waitParkKey(conversationId, runId, input.event, input.id);
|
|
771
|
-
const ledger = await readLedger();
|
|
772
|
-
if (!ledger.deliveries.has(key)) {
|
|
773
|
-
const encoded = encodeDeliveredPayload(input.event, input.id, input.payload);
|
|
774
|
-
await store.appendEvent({
|
|
775
|
-
conversationId,
|
|
776
|
-
kind: DURABILITY_EVENT_EVENT_KIND,
|
|
777
|
-
payload: { runId, event: input.event, id: input.id, encoded }
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
notifyWaiters(parkWaiters, key);
|
|
781
|
-
};
|
|
782
|
-
return {
|
|
783
|
-
step,
|
|
784
|
-
readRecordedStep,
|
|
785
|
-
hasRecordedStep: async (name) => await readRecordedStep(name) !== undefined,
|
|
786
|
-
sleep,
|
|
787
|
-
waitFor,
|
|
788
|
-
deliver
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
|
|
792
320
|
// src/agent-runtime/events.ts
|
|
793
321
|
function createAgentRuntimeEventSink(config) {
|
|
794
322
|
const manager = createBoundedSinkManager({
|
|
@@ -1104,9 +632,9 @@ function createAgentToolFenceLifecycle(config) {
|
|
|
1104
632
|
}
|
|
1105
633
|
|
|
1106
634
|
// src/agent-runtime/prompt.ts
|
|
1107
|
-
import { z
|
|
1108
|
-
var AgentTokenCountSchema =
|
|
1109
|
-
value:
|
|
635
|
+
import { z } from "zod";
|
|
636
|
+
var AgentTokenCountSchema = z.object({
|
|
637
|
+
value: z.int().nonnegative().optional(),
|
|
1110
638
|
provenance: AgentProvenanceSchema.extract([
|
|
1111
639
|
"measured",
|
|
1112
640
|
"computed",
|
|
@@ -1226,7 +754,7 @@ function knownValue(value) {
|
|
|
1226
754
|
}
|
|
1227
755
|
function composeAgentPrompt(sections) {
|
|
1228
756
|
return async (options) => {
|
|
1229
|
-
const event =
|
|
757
|
+
const event = z.enum(["session.started", "turn.started"]).parse(options.event ?? "turn.started");
|
|
1230
758
|
const rendered = [];
|
|
1231
759
|
let systemTotal = 0;
|
|
1232
760
|
let userTotal = 0;
|
|
@@ -1429,7 +957,7 @@ async function recordAgentRetryDecision(input) {
|
|
|
1429
957
|
}
|
|
1430
958
|
|
|
1431
959
|
// src/agent-runtime/state-slots.ts
|
|
1432
|
-
import { z as
|
|
960
|
+
import { z as z2 } from "zod";
|
|
1433
961
|
function defineStateSlot(input) {
|
|
1434
962
|
if (input.name.length === 0)
|
|
1435
963
|
throw new TypeError("State slot name must not be empty");
|
|
@@ -1444,11 +972,11 @@ function defineStateSlot(input) {
|
|
|
1444
972
|
...input.description && { description: input.description }
|
|
1445
973
|
};
|
|
1446
974
|
}
|
|
1447
|
-
var StateSetPayloadSchema =
|
|
1448
|
-
name:
|
|
1449
|
-
version:
|
|
1450
|
-
value:
|
|
1451
|
-
actor:
|
|
975
|
+
var StateSetPayloadSchema = z2.object({
|
|
976
|
+
name: z2.string().min(1),
|
|
977
|
+
version: z2.int().positive(),
|
|
978
|
+
value: z2.json(),
|
|
979
|
+
actor: z2.enum(["agent", "human", "system"])
|
|
1452
980
|
}).strict();
|
|
1453
981
|
function slotRegistry(definitions) {
|
|
1454
982
|
const result = new Map;
|
|
@@ -1530,18 +1058,18 @@ function renderAgentStateSlots(values) {
|
|
|
1530
1058
|
var agentGoalStateSlot = defineStateSlot({
|
|
1531
1059
|
name: "goal",
|
|
1532
1060
|
description: "The durable objective and lifecycle of this conversation.",
|
|
1533
|
-
schema:
|
|
1534
|
-
objective:
|
|
1535
|
-
status:
|
|
1061
|
+
schema: z2.object({
|
|
1062
|
+
objective: z2.string().min(1),
|
|
1063
|
+
status: z2.enum(["active", "complete", "blocked"])
|
|
1536
1064
|
}).strict()
|
|
1537
1065
|
});
|
|
1538
1066
|
var agentTodoStateSlot = defineStateSlot({
|
|
1539
1067
|
name: "todo",
|
|
1540
1068
|
description: "The durable ordered work plan for this conversation.",
|
|
1541
|
-
schema:
|
|
1542
|
-
items:
|
|
1543
|
-
step:
|
|
1544
|
-
status:
|
|
1069
|
+
schema: z2.object({
|
|
1070
|
+
items: z2.array(z2.object({
|
|
1071
|
+
step: z2.string().min(1),
|
|
1072
|
+
status: z2.enum(["pending", "in_progress", "completed"])
|
|
1545
1073
|
}).strict())
|
|
1546
1074
|
}).strict()
|
|
1547
1075
|
});
|
|
@@ -1751,7 +1279,7 @@ function createRunMutationQueue() {
|
|
|
1751
1279
|
import { wrapLanguageModel } from "ai";
|
|
1752
1280
|
|
|
1753
1281
|
// src/agent-runtime/runtime-internals.ts
|
|
1754
|
-
import { z as
|
|
1282
|
+
import { z as z3 } from "zod";
|
|
1755
1283
|
function findRun(runs, runId) {
|
|
1756
1284
|
const run = runs.find((candidate) => candidate.id === runId);
|
|
1757
1285
|
if (!run)
|
|
@@ -1759,7 +1287,7 @@ function findRun(runs, runId) {
|
|
|
1759
1287
|
return run;
|
|
1760
1288
|
}
|
|
1761
1289
|
function jsonValue(value) {
|
|
1762
|
-
const parsed =
|
|
1290
|
+
const parsed = z3.json().safeParse(value);
|
|
1763
1291
|
return parsed.success ? parsed.data : { message: "Non-JSON tool output omitted" };
|
|
1764
1292
|
}
|
|
1765
1293
|
function providerEnvelope(value) {
|
|
@@ -3813,4 +3341,4 @@ function createAgentRuntime(config) {
|
|
|
3813
3341
|
};
|
|
3814
3342
|
}
|
|
3815
3343
|
|
|
3816
|
-
export { AgentRuntimeConflictError, normalizeSdkUsage, AgentContextOverflowError, createAgentSessionCoordinator, registerDeferredToolRepair, registerDeferredToolCatalog, deferredToolCatalog, repairedSearchCall,
|
|
3344
|
+
export { AgentRuntimeConflictError, normalizeSdkUsage, AgentContextOverflowError, createAgentSessionCoordinator, registerDeferredToolRepair, registerDeferredToolCatalog, deferredToolCatalog, repairedSearchCall, createAgentRuntimeEventSink, projectAgentHistoryDetailed, projectAgentHistory, createAgentToolFenceLifecycle, AgentTokenCountSchema, selectAgentHistory, composeAgentPrompt, AgentProviderStreamCutError, classifyProviderFailure, isToolResultFailure, recordAgentRetryDecision, defineStateSlot, createAgentStateSlotStore, renderAgentStateSlots, agentGoalStateSlot, agentTodoStateSlot, createAgentRuntime };
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentToolError,
|
|
3
3
|
resolveToolDurability
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-kw9t5ayn.js";
|
|
5
5
|
import {
|
|
6
6
|
collectToolSurface
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-qrbdq8jk.js";
|
|
8
8
|
import {
|
|
9
9
|
createToolRunner,
|
|
10
10
|
formatToolError
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-1qvdwnp2.js";
|
|
12
12
|
import {
|
|
13
13
|
isToolExecutionControlError,
|
|
14
14
|
toolCauseFromResult,
|
|
15
15
|
toolResultFromError
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-mqhjmadk.js";
|
|
17
17
|
import {
|
|
18
18
|
isRecord
|
|
19
19
|
} from "./index-77fekveh.js";
|
|
@@ -49,15 +49,16 @@ function mountAgent(services, config = {}) {
|
|
|
49
49
|
});
|
|
50
50
|
const execute = async (rawArgs, options) => {
|
|
51
51
|
const args = isRecord(rawArgs) ? rawArgs : {};
|
|
52
|
-
const durability = resolveToolDurability(options.context, options.toolCallId, options.abortSignal);
|
|
52
|
+
const durability = resolveToolDurability(options.context, options.toolCallId, options.abortSignal) ?? config.durability?.(options.toolCallId, options.abortSignal);
|
|
53
|
+
const callContext = { signal: options.abortSignal, toolCallId: options.toolCallId };
|
|
53
54
|
const executeTool = durability ? createToolRunner({
|
|
54
55
|
source: "agent",
|
|
55
56
|
extend: config.extend,
|
|
56
57
|
context: {
|
|
57
58
|
...config.context,
|
|
58
|
-
step: durability.step,
|
|
59
|
-
sleep: durability.sleep,
|
|
60
|
-
waitFor: durability.waitFor
|
|
59
|
+
step: durability.step.bind(durability),
|
|
60
|
+
sleep: durability.sleep.bind(durability),
|
|
61
|
+
waitFor: durability.waitFor.bind(durability)
|
|
61
62
|
},
|
|
62
63
|
hooks: config.hooks,
|
|
63
64
|
lifecycle: config.lifecycle,
|
|
@@ -65,9 +66,7 @@ function mountAgent(services, config = {}) {
|
|
|
65
66
|
coerceJsonArgs: config.coerceJsonArgs,
|
|
66
67
|
onOutputStrip: config.onOutputStrip
|
|
67
68
|
}) : runTool;
|
|
68
|
-
const result = await executeTool(mountable, args, {
|
|
69
|
-
signal: options.abortSignal
|
|
70
|
-
}).catch((err) => {
|
|
69
|
+
const result = await executeTool(mountable, args, callContext).catch((err) => {
|
|
71
70
|
if (isToolExecutionControlError(err))
|
|
72
71
|
throw err;
|
|
73
72
|
throw new AgentToolError(formatToolError(toolResultFromError(err), mountable.name, config.errorHint), err);
|