stitchkit 0.99.0 → 0.100.1
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 +124 -1
- package/dist/agent-runtime/contained-darwin.d.ts +0 -17
- package/dist/agent-runtime/contained-darwin.d.ts.map +1 -1
- package/dist/agent-runtime/contained-write.d.ts.map +1 -1
- package/dist/agent-runtime/invocation-attempt.d.ts +28 -0
- package/dist/agent-runtime/invocation-attempt.d.ts.map +1 -0
- package/dist/agent-runtime/invocation-failure.d.ts +6 -0
- package/dist/agent-runtime/invocation-failure.d.ts.map +1 -0
- package/dist/agent-runtime/invocation-payload.d.ts +20 -0
- package/dist/agent-runtime/invocation-payload.d.ts.map +1 -0
- package/dist/agent-runtime/invocation-read.d.ts +131 -0
- package/dist/agent-runtime/invocation-read.d.ts.map +1 -0
- package/dist/agent-runtime/invocation-schema.d.ts +378 -0
- package/dist/agent-runtime/invocation-schema.d.ts.map +1 -0
- package/dist/agent-runtime/invocations.d.ts +52 -0
- package/dist/agent-runtime/invocations.d.ts.map +1 -0
- package/dist/agent-runtime/projections.d.ts.map +1 -1
- package/dist/agent-runtime/run-acquisition.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution-state.d.ts +4 -2
- package/dist/agent-runtime/run-execution-state.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/run-failure.d.ts.map +1 -1
- package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -1
- package/dist/agent-runtime/run-operation-lifecycle.d.ts +2 -2
- package/dist/agent-runtime/run-operation-lifecycle.d.ts.map +1 -1
- package/dist/agent-runtime/run-provider-ledger.d.ts +1 -0
- package/dist/agent-runtime/run-provider-ledger.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts +11 -0
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schedule-dispatch.d.ts +9 -2
- package/dist/agent-runtime/schedule-dispatch.d.ts.map +1 -1
- package/dist/agent-runtime/schedule-records.d.ts +8 -2
- package/dist/agent-runtime/schedule-records.d.ts.map +1 -1
- package/dist/agent-runtime/schedules.d.ts +5 -0
- package/dist/agent-runtime/schedules.d.ts.map +1 -1
- package/dist/agent-runtime/sqlite-events.d.ts.map +1 -1
- package/dist/agent-runtime/store-create.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver-contract.d.ts +9 -0
- package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -1
- package/dist/agent-runtime/store-event-once.d.ts +37 -0
- package/dist/agent-runtime/store-event-once.d.ts.map +1 -0
- package/dist/agent-runtime/store-memory.d.ts.map +1 -1
- package/dist/agent-runtime/store.d.ts +11 -0
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/application/change-subscription.d.ts +36 -0
- package/dist/application/change-subscription.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-contract.d.ts +3 -6
- package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
- package/dist/application/notification-delivery.d.ts +55 -0
- package/dist/application/notification-delivery.d.ts.map +1 -0
- package/dist/application/notification-outbox-state.d.ts +41 -0
- package/dist/application/notification-outbox-state.d.ts.map +1 -0
- package/dist/application/notification-outbox.d.ts +7 -1
- package/dist/application/notification-outbox.d.ts.map +1 -1
- package/dist/application/watch-hub-core.d.ts +14 -84
- package/dist/application/watch-hub-core.d.ts.map +1 -1
- package/dist/application/watch-hub-source.d.ts +98 -0
- package/dist/application/watch-hub-source.d.ts.map +1 -0
- package/dist/application/watch-hub.d.ts +10 -2
- package/dist/application/watch-hub.d.ts.map +1 -1
- package/dist/browser/session-credentials.d.ts +26 -0
- package/dist/browser/session-credentials.d.ts.map +1 -0
- package/dist/browser/session.d.ts +33 -0
- package/dist/browser/session.d.ts.map +1 -0
- package/dist/durability/events.d.ts +6 -0
- package/dist/durability/events.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +3 -2
- package/dist/entrypoints/agent-runtime/harness.js +5 -3
- package/dist/entrypoints/agent-runtime/sandbox.js +3 -2
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
- package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
- package/dist/entrypoints/agent-runtime/testing.js +3 -3
- package/dist/entrypoints/agent-runtime.d.ts +3 -0
- package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime.js +65 -20
- package/dist/entrypoints/application/diagnostic-journal.js +2 -1
- package/dist/entrypoints/application.d.ts +3 -1
- package/dist/entrypoints/application.d.ts.map +1 -1
- package/dist/entrypoints/application.js +820 -294
- package/dist/entrypoints/files.js +9 -2
- package/dist/entrypoints/index.d.ts +2 -0
- package/dist/entrypoints/index.d.ts.map +1 -1
- package/dist/entrypoints/index.js +199 -0
- package/dist/entrypoints/live.js +78 -19
- package/dist/entrypoints/node.js +1 -1
- package/dist/entrypoints/react.d.ts +1 -1
- package/dist/entrypoints/react.d.ts.map +1 -1
- package/dist/entrypoints/react.js +59 -16
- package/dist/entrypoints/server.js +4 -4
- package/dist/{index-sp1tzwnb.js → index-10x2hbx0.js} +5 -2
- package/dist/{index-8p52kd5p.js → index-c6bxbsnc.js} +100 -14
- package/dist/{index-gxrt5h6v.js → index-cyktc4bp.js} +3 -0
- package/dist/{index-1m2thnq0.js → index-eaysmdtq.js} +11 -2
- package/dist/{index-jhx828hc.js → index-f4fx2tza.js} +948 -279
- package/dist/{index-px2gm2jp.js → index-fhwqwxe0.js} +17 -55
- package/dist/{index-e4hkgm5t.js → index-gw8bmyaj.js} +4 -2
- package/dist/{index-p3vsv1fb.js → index-hadmp193.js} +14 -5
- package/dist/{index-wt743f7f.js → index-k6gpggb9.js} +2 -1
- package/dist/index-q3pyb9n0.js +22 -0
- package/dist/{index-wsm5w4ee.js → index-vqr7f7v8.js} +51 -3
- package/dist/index-zjjyynm3.js +42 -0
- package/dist/internal/coalesced-task.d.ts +17 -0
- package/dist/internal/coalesced-task.d.ts.map +1 -0
- package/dist/internal/darwin-binding.d.ts +19 -0
- package/dist/internal/darwin-binding.d.ts.map +1 -0
- package/dist/internal/exclusive-lock.d.ts +20 -7
- package/dist/internal/exclusive-lock.d.ts.map +1 -1
- package/dist/internal/mutation-queue.d.ts +4 -0
- package/dist/internal/mutation-queue.d.ts.map +1 -0
- package/dist/internal/process-identity.d.ts +1 -1
- package/dist/internal/process-identity.d.ts.map +1 -1
- package/dist/internal/process-instance.d.ts +26 -0
- package/dist/internal/process-instance.d.ts.map +1 -0
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
- package/dist/live/watch-client-state.d.ts +71 -0
- package/dist/live/watch-client-state.d.ts.map +1 -0
- package/dist/live/watch-client.d.ts +5 -1
- package/dist/live/watch-client.d.ts.map +1 -1
- package/dist/live/watch-contract.d.ts +12 -0
- package/dist/live/watch-contract.d.ts.map +1 -1
- package/dist/react/cache-bridge.d.ts +10 -0
- package/dist/react/cache-bridge.d.ts.map +1 -1
- package/dist/server/realtime.d.ts.map +1 -1
- package/llms/agent-runtime.2.txt +102 -0
- package/llms/agent-runtime.3.txt +30 -1
- package/llms/agent-runtime.txt +8 -3
- package/llms/application.2.txt +84 -2
- package/llms/application.txt +32 -2
- package/llms/files.txt +1 -1
- package/llms/live.txt +8 -0
- package/llms/react.txt +8 -0
- package/llms/server.3.txt +57 -0
- package/llms/stitchkit.2.txt +41 -0
- package/llms/stitchkit.3.txt +26 -0
- package/llms/stitchkit.txt +3 -3
- package/llms/upgrading-0.37.0.txt +176 -0
- package/llms/{upgrading-0.37.0-0.58.0.txt → upgrading-0.44.0-0.60.0.txt} +229 -169
- package/llms/{upgrading-0.59.0-0.71.0.txt → upgrading-0.61.0-0.73.0.txt} +122 -229
- package/llms/{upgrading-0.72.0-0.99.0.txt → upgrading-0.74.0-0.100.0.txt} +80 -123
- package/llms/upgrading.txt +4 -3
- package/llms-full.txt +471 -11
- package/llms.txt +10 -9
- package/native/darwin-arm64.node +0 -0
- package/native/darwin-x64.node +0 -0
- package/package.json +1 -1
- package/dist/agent-runtime/run-mutation-queue.d.ts +0 -21
- package/dist/agent-runtime/run-mutation-queue.d.ts.map +0 -1
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
createToolChronology,
|
|
17
17
|
isAssistantHistoryEvidence,
|
|
18
18
|
isCompleteAgentHistoryTurn
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-cyktc4bp.js";
|
|
20
20
|
import {
|
|
21
21
|
AgentAssistantPlaceholderSchema,
|
|
22
22
|
AgentJsonObjectSchema,
|
|
@@ -27,8 +27,12 @@ import {
|
|
|
27
27
|
AgentRunOperationSchema,
|
|
28
28
|
AgentRunSchema,
|
|
29
29
|
AgentSnapshotSchema,
|
|
30
|
+
AgentUsageSchema,
|
|
30
31
|
runStateForTerminalReason
|
|
31
32
|
} from "./index-gtj3zc53.js";
|
|
33
|
+
import {
|
|
34
|
+
createMutationQueue
|
|
35
|
+
} from "./index-q3pyb9n0.js";
|
|
32
36
|
import {
|
|
33
37
|
createLocalStepDurability,
|
|
34
38
|
createToolDurabilityContext,
|
|
@@ -38,6 +42,9 @@ import {
|
|
|
38
42
|
ToolExecutionControlError,
|
|
39
43
|
isToolExecutionControlError
|
|
40
44
|
} from "./index-8qt2m66q.js";
|
|
45
|
+
import {
|
|
46
|
+
serializeCanonicalJson
|
|
47
|
+
} from "./index-k5hsfc3j.js";
|
|
41
48
|
import {
|
|
42
49
|
isRecord,
|
|
43
50
|
transportResult
|
|
@@ -596,15 +603,891 @@ async function projectAgentHistoryDetailed(messages, options = {}) {
|
|
|
596
603
|
decisions.push(decide(message, "omitted", "incomplete-tool-turn"));
|
|
597
604
|
continue;
|
|
598
605
|
}
|
|
599
|
-
const assistant = assistantMessages(message, interrupted ? "interrupted" : message.status === "failed" ? "failed" : undefined);
|
|
600
|
-
chronology = nextChronology;
|
|
601
|
-
projected.push(...assistant.messages);
|
|
602
|
-
decisions.push(assistant.messages.length > 0 ? decide(message, "projected", "projected", assistant.rendered) : decide(message, "omitted", "empty"));
|
|
603
|
-
}
|
|
604
|
-
return { messages: projected, decisions, system };
|
|
605
|
-
}
|
|
606
|
-
async function projectAgentHistory(messages, options = {}) {
|
|
607
|
-
return [...(await projectAgentHistoryDetailed(messages, options)).messages];
|
|
606
|
+
const assistant = assistantMessages(message, interrupted ? "interrupted" : message.status === "failed" ? "failed" : undefined);
|
|
607
|
+
chronology = nextChronology;
|
|
608
|
+
projected.push(...assistant.messages);
|
|
609
|
+
decisions.push(assistant.messages.length > 0 ? decide(message, "projected", "projected", assistant.rendered) : decide(message, "omitted", "empty"));
|
|
610
|
+
}
|
|
611
|
+
return { messages: projected, decisions, system };
|
|
612
|
+
}
|
|
613
|
+
async function projectAgentHistory(messages, options = {}) {
|
|
614
|
+
return [...(await projectAgentHistoryDetailed(messages, options)).messages];
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// src/agent-runtime/invocation-schema.ts
|
|
618
|
+
import { z } from "zod";
|
|
619
|
+
var Id = z.string().min(1).max(512);
|
|
620
|
+
var Hash = z.string().regex(/^[a-f0-9]{64}$/);
|
|
621
|
+
var ModelInvocationTraceSchema = z.object({
|
|
622
|
+
operationId: Id,
|
|
623
|
+
purpose: Id,
|
|
624
|
+
project: Id,
|
|
625
|
+
parent: z.object({ traceId: Id, invocationId: Id.optional() }).strict().optional(),
|
|
626
|
+
experiment: Id.optional(),
|
|
627
|
+
case: Id.optional(),
|
|
628
|
+
profile: Id.optional()
|
|
629
|
+
}).strict();
|
|
630
|
+
var CompletionInvocationInputSchema = z.object({
|
|
631
|
+
conversationId: Id,
|
|
632
|
+
idempotencyKey: Id,
|
|
633
|
+
trace: ModelInvocationTraceSchema,
|
|
634
|
+
prompt: z.string().min(1),
|
|
635
|
+
models: z.array(Id).min(1).max(8),
|
|
636
|
+
settings: z.object({
|
|
637
|
+
maxOutputTokens: z.int().positive().optional(),
|
|
638
|
+
temperature: z.number().finite().optional(),
|
|
639
|
+
topP: z.number().min(0).max(1).optional(),
|
|
640
|
+
seed: z.int().optional()
|
|
641
|
+
}).strict().optional(),
|
|
642
|
+
timeoutMs: z.int().positive().max(3600000)
|
|
643
|
+
}).strict();
|
|
644
|
+
var Identity = z.object({
|
|
645
|
+
provider: Id.nullable(),
|
|
646
|
+
modelId: Id.nullable(),
|
|
647
|
+
responseId: Id.nullable()
|
|
648
|
+
}).strict();
|
|
649
|
+
var InvocationCallerSchema = z.object({ subject: Id }).strict();
|
|
650
|
+
var InvocationProcessSchema = z.object({
|
|
651
|
+
instanceId: Id,
|
|
652
|
+
pid: z.int().positive(),
|
|
653
|
+
hostname: Id
|
|
654
|
+
}).strict();
|
|
655
|
+
var Base = z.object({
|
|
656
|
+
conversationId: Id,
|
|
657
|
+
invocationId: Id,
|
|
658
|
+
operationId: Id,
|
|
659
|
+
runId: Id.optional()
|
|
660
|
+
});
|
|
661
|
+
var InvocationStartedSchema = Base.extend({
|
|
662
|
+
type: z.literal("invocation/started"),
|
|
663
|
+
mode: z.enum(["completion", "agent"]),
|
|
664
|
+
trace: ModelInvocationTraceSchema,
|
|
665
|
+
caller: InvocationCallerSchema,
|
|
666
|
+
executingProcess: InvocationProcessSchema,
|
|
667
|
+
fingerprint: Hash,
|
|
668
|
+
requested: z.object({ models: z.array(Id), payloadSha256: Hash }).strict()
|
|
669
|
+
}).strict();
|
|
670
|
+
var InvocationAttemptContextSchema = Base.extend({
|
|
671
|
+
attemptId: Id,
|
|
672
|
+
step: z.int().nonnegative()
|
|
673
|
+
}).strict();
|
|
674
|
+
var Attempt = Base.extend({ attemptId: Id, step: z.int().nonnegative() });
|
|
675
|
+
var InvocationRequestSchema = Attempt.extend({
|
|
676
|
+
type: z.literal("provider/request"),
|
|
677
|
+
requested: z.object({ modelId: Id, provider: Id }).strict(),
|
|
678
|
+
executingProcess: InvocationProcessSchema,
|
|
679
|
+
sent: z.object({
|
|
680
|
+
modelId: Id,
|
|
681
|
+
provider: Id,
|
|
682
|
+
payloadSha256: Hash,
|
|
683
|
+
artifactId: Id,
|
|
684
|
+
tools: z.int().nonnegative()
|
|
685
|
+
}).strict()
|
|
686
|
+
}).strict();
|
|
687
|
+
var InvocationResponseSchema = Attempt.extend({
|
|
688
|
+
type: z.literal("provider/response"),
|
|
689
|
+
status: z.enum(["succeeded", "failed", "cancelled"]),
|
|
690
|
+
effective: Identity,
|
|
691
|
+
usage: AgentUsageSchema,
|
|
692
|
+
artifactId: Id,
|
|
693
|
+
payloadSha256: Hash
|
|
694
|
+
}).strict();
|
|
695
|
+
var InvocationFinishedSchema = Base.extend({
|
|
696
|
+
type: z.literal("invocation/finished"),
|
|
697
|
+
failure: z.object({ artifactId: Id, payloadSha256: Hash }).strict().optional(),
|
|
698
|
+
status: z.enum(["succeeded", "failed", "cancelled"])
|
|
699
|
+
}).strict();
|
|
700
|
+
var ModelInvocationRecordSchema = z.discriminatedUnion("type", [
|
|
701
|
+
InvocationStartedSchema,
|
|
702
|
+
InvocationRequestSchema,
|
|
703
|
+
InvocationResponseSchema,
|
|
704
|
+
InvocationFinishedSchema
|
|
705
|
+
]);
|
|
706
|
+
var InvocationPayloadSchema = Base.extend({
|
|
707
|
+
artifactId: Id,
|
|
708
|
+
sha256: Hash,
|
|
709
|
+
bytes: z.int().nonnegative(),
|
|
710
|
+
iv: z.string(),
|
|
711
|
+
tag: z.string(),
|
|
712
|
+
ciphertext: z.string()
|
|
713
|
+
}).strict();
|
|
714
|
+
|
|
715
|
+
// src/agent-runtime/invocation-attempt.ts
|
|
716
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
717
|
+
import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
|
|
718
|
+
import { wrapLanguageModel } from "ai";
|
|
719
|
+
|
|
720
|
+
// src/agent-runtime/invocation-failure.ts
|
|
721
|
+
class InvocationReceiptError extends Error {
|
|
722
|
+
constructor(cause) {
|
|
723
|
+
super("Model invocation receipt could not be recorded", { cause });
|
|
724
|
+
this.name = "InvocationReceiptError";
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
async function invocationAudit(work) {
|
|
728
|
+
try {
|
|
729
|
+
return await work();
|
|
730
|
+
} catch (error) {
|
|
731
|
+
throw error instanceof InvocationReceiptError ? error : new InvocationReceiptError(error);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// src/agent-runtime/invocation-payload.ts
|
|
736
|
+
import {
|
|
737
|
+
createCipheriv,
|
|
738
|
+
createDecipheriv,
|
|
739
|
+
createHash,
|
|
740
|
+
randomBytes,
|
|
741
|
+
randomUUID
|
|
742
|
+
} from "node:crypto";
|
|
743
|
+
import { z as z2 } from "zod";
|
|
744
|
+
function invocationJson(value) {
|
|
745
|
+
const errors = new WeakSet;
|
|
746
|
+
return z2.json().parse(JSON.parse(JSON.stringify(value, (_key, item) => {
|
|
747
|
+
if (item instanceof Uint8Array)
|
|
748
|
+
return { base64: Buffer.from(item).toString("base64") };
|
|
749
|
+
if (item instanceof ArrayBuffer)
|
|
750
|
+
return { base64: Buffer.from(item).toString("base64") };
|
|
751
|
+
if (item instanceof Error) {
|
|
752
|
+
if (errors.has(item))
|
|
753
|
+
return { name: item.name, message: item.message };
|
|
754
|
+
errors.add(item);
|
|
755
|
+
return { name: item.name, message: item.message, cause: item.cause };
|
|
756
|
+
}
|
|
757
|
+
return item;
|
|
758
|
+
})));
|
|
759
|
+
}
|
|
760
|
+
function invocationHash(value) {
|
|
761
|
+
return createHash("sha256").update(serializeCanonicalJson(invocationJson(value))).digest("hex");
|
|
762
|
+
}
|
|
763
|
+
function createInvocationPayloads(store, key, maxBytes) {
|
|
764
|
+
if (key.byteLength !== 32)
|
|
765
|
+
throw new TypeError("Invocation payload key must contain 32 bytes");
|
|
766
|
+
const encryptionKey = Uint8Array.from(key);
|
|
767
|
+
return {
|
|
768
|
+
maxBytes,
|
|
769
|
+
async write(identity, value) {
|
|
770
|
+
const data = Buffer.from(serializeCanonicalJson(invocationJson(value)));
|
|
771
|
+
if (data.byteLength > maxBytes)
|
|
772
|
+
throw new RangeError("Invocation payload exceeds maxPayloadBytes");
|
|
773
|
+
const artifactId = randomUUID();
|
|
774
|
+
const sha256 = createHash("sha256").update(data).digest("hex");
|
|
775
|
+
const iv = randomBytes(12);
|
|
776
|
+
const cipher = createCipheriv("aes-256-gcm", encryptionKey, iv);
|
|
777
|
+
cipher.setAAD(Buffer.from(JSON.stringify([identity.conversationId, identity.invocationId, artifactId])));
|
|
778
|
+
const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
779
|
+
const { conversationId } = identity;
|
|
780
|
+
if (!store.appendEventOnce)
|
|
781
|
+
throw new TypeError("Invocation payloads require atomic store.appendEventOnce");
|
|
782
|
+
await store.appendEventOnce({
|
|
783
|
+
conversationId,
|
|
784
|
+
kind: "provider/payload",
|
|
785
|
+
payload: {
|
|
786
|
+
...identity,
|
|
787
|
+
artifactId,
|
|
788
|
+
sha256,
|
|
789
|
+
bytes: data.byteLength,
|
|
790
|
+
iv: iv.toString("base64"),
|
|
791
|
+
tag: cipher.getAuthTag().toString("base64"),
|
|
792
|
+
ciphertext: ciphertext.toString("base64")
|
|
793
|
+
}
|
|
794
|
+
}, artifactId);
|
|
795
|
+
return { artifactId, sha256 };
|
|
796
|
+
},
|
|
797
|
+
decrypt(conversationId, value) {
|
|
798
|
+
const payload = InvocationPayloadSchema.parse(value);
|
|
799
|
+
if (payload.bytes > maxBytes || payload.ciphertext.length > Math.ceil(maxBytes / 3) * 4) {
|
|
800
|
+
throw new RangeError("Invocation payload exceeds maxPayloadBytes");
|
|
801
|
+
}
|
|
802
|
+
const decipher = createDecipheriv("aes-256-gcm", encryptionKey, Buffer.from(payload.iv, "base64"));
|
|
803
|
+
decipher.setAAD(Buffer.from(JSON.stringify([conversationId, payload.invocationId, payload.artifactId])));
|
|
804
|
+
decipher.setAuthTag(Buffer.from(payload.tag, "base64"));
|
|
805
|
+
const data = Buffer.concat([
|
|
806
|
+
decipher.update(Buffer.from(payload.ciphertext, "base64")),
|
|
807
|
+
decipher.final()
|
|
808
|
+
]);
|
|
809
|
+
if (data.length !== payload.bytes || createHash("sha256").update(data).digest("hex") !== payload.sha256) {
|
|
810
|
+
throw new Error("Invocation payload integrity mismatch");
|
|
811
|
+
}
|
|
812
|
+
return z2.json().parse(JSON.parse(data.toString("utf8")));
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/agent-runtime/provider-origin.ts
|
|
818
|
+
import {
|
|
819
|
+
InvalidToolApprovalError,
|
|
820
|
+
InvalidToolApprovalSignatureError,
|
|
821
|
+
ToolCallNotFoundForApprovalError
|
|
822
|
+
} from "ai";
|
|
823
|
+
var providerOrigin = new WeakSet;
|
|
824
|
+
function isOwnInputRefusal(error) {
|
|
825
|
+
return InvalidToolApprovalSignatureError.isInstance(error) || InvalidToolApprovalError.isInstance(error) || ToolCallNotFoundForApprovalError.isInstance(error);
|
|
826
|
+
}
|
|
827
|
+
function markProviderOrigin(error) {
|
|
828
|
+
if (typeof error === "object" && error !== null)
|
|
829
|
+
providerOrigin.add(error);
|
|
830
|
+
return error;
|
|
831
|
+
}
|
|
832
|
+
function hasProviderOrigin(error) {
|
|
833
|
+
return typeof error === "object" && error !== null && providerOrigin.has(error);
|
|
834
|
+
}
|
|
835
|
+
function markProviderStream(stream) {
|
|
836
|
+
const reader = stream.getReader();
|
|
837
|
+
return new ReadableStream({
|
|
838
|
+
async pull(controller) {
|
|
839
|
+
let read;
|
|
840
|
+
try {
|
|
841
|
+
read = await reader.read();
|
|
842
|
+
} catch (error) {
|
|
843
|
+
controller.error(isOwnInputRefusal(error) ? error : markProviderOrigin(error));
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
if (read.done)
|
|
847
|
+
controller.close();
|
|
848
|
+
else
|
|
849
|
+
controller.enqueue(read.value);
|
|
850
|
+
},
|
|
851
|
+
cancel(reason) {
|
|
852
|
+
return reader.cancel(reason);
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// src/agent-runtime/runtime-internals.ts
|
|
858
|
+
import { z as z3 } from "zod";
|
|
859
|
+
function findRun(runs, runId) {
|
|
860
|
+
const run = runs.find((candidate) => candidate.id === runId);
|
|
861
|
+
if (!run)
|
|
862
|
+
throw new AgentRuntimeConflictError("run lookup");
|
|
863
|
+
return run;
|
|
864
|
+
}
|
|
865
|
+
function jsonValue(value) {
|
|
866
|
+
const parsed = z3.json().safeParse(value);
|
|
867
|
+
return parsed.success ? parsed.data : { message: "Non-JSON tool output omitted" };
|
|
868
|
+
}
|
|
869
|
+
function providerEnvelope(value) {
|
|
870
|
+
const parsed = AgentJsonObjectSchema.safeParse(value);
|
|
871
|
+
if (!parsed.success)
|
|
872
|
+
return;
|
|
873
|
+
return { schemaVersion: 1, provider: "ai-sdk", data: parsed.data };
|
|
874
|
+
}
|
|
875
|
+
function providerResponseIdentity(id, provider) {
|
|
876
|
+
return AgentProviderResponseSchema.parse({
|
|
877
|
+
id,
|
|
878
|
+
...typeof provider === "string" && provider.length > 0 ? { provider } : {}
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
function appendText(parts, text) {
|
|
882
|
+
const previous = parts.at(-1);
|
|
883
|
+
if (previous?.type === "text") {
|
|
884
|
+
const next = AgentMessagePartSchema.parse({ ...previous, text: previous.text + text });
|
|
885
|
+
parts.splice(parts.length - 1, 1, next);
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
parts.push(AgentMessagePartSchema.parse({ type: "text", text }));
|
|
889
|
+
}
|
|
890
|
+
function abortTerminalReason(signal) {
|
|
891
|
+
if (signal.reason === "shutdown")
|
|
892
|
+
return "shutdown";
|
|
893
|
+
if (signal.reason === "timeout")
|
|
894
|
+
return "timeout";
|
|
895
|
+
if (signal.reason === "supersede")
|
|
896
|
+
return "superseded";
|
|
897
|
+
return "interrupted";
|
|
898
|
+
}
|
|
899
|
+
function addUsage(total, step) {
|
|
900
|
+
const sum = (left, right) => {
|
|
901
|
+
if (left?.value === undefined && right?.value === undefined) {
|
|
902
|
+
return { provenance: "unavailable" };
|
|
903
|
+
}
|
|
904
|
+
if (left?.value === undefined)
|
|
905
|
+
return { ...right, provenance: "computed" };
|
|
906
|
+
if (right?.value === undefined)
|
|
907
|
+
return { ...left, provenance: "computed" };
|
|
908
|
+
return { value: left.value + right.value, provenance: "computed" };
|
|
909
|
+
};
|
|
910
|
+
const sumCost = (left, right) => {
|
|
911
|
+
if (left?.value === undefined || right?.value === undefined) {
|
|
912
|
+
return { provenance: "unavailable" };
|
|
913
|
+
}
|
|
914
|
+
if (left.currency !== right.currency)
|
|
915
|
+
return { provenance: "unavailable" };
|
|
916
|
+
return {
|
|
917
|
+
value: left.value + right.value,
|
|
918
|
+
...left.currency && { currency: left.currency },
|
|
919
|
+
provenance: "computed"
|
|
920
|
+
};
|
|
921
|
+
};
|
|
922
|
+
if (!total)
|
|
923
|
+
return step;
|
|
924
|
+
const cost = sumCost(total.cost, step.cost);
|
|
925
|
+
return {
|
|
926
|
+
inputTokens: sum(total.inputTokens, step.inputTokens),
|
|
927
|
+
outputTokens: sum(total.outputTokens, step.outputTokens),
|
|
928
|
+
reasoningTokens: sum(total.reasoningTokens, step.reasoningTokens),
|
|
929
|
+
cacheReadTokens: sum(total.cacheReadTokens, step.cacheReadTokens),
|
|
930
|
+
cacheWriteTokens: sum(total.cacheWriteTokens, step.cacheWriteTokens),
|
|
931
|
+
...cost && { cost }
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
function mergeModelTotals(sdkTotal, accumulated) {
|
|
935
|
+
const pick = (total, ours) => {
|
|
936
|
+
if (ours?.provenance === "unavailable")
|
|
937
|
+
return ours;
|
|
938
|
+
return total?.value !== undefined ? { value: total.value, provenance: "computed" } : ours ?? { provenance: "unavailable" };
|
|
939
|
+
};
|
|
940
|
+
return {
|
|
941
|
+
inputTokens: pick(sdkTotal.inputTokens, accumulated?.inputTokens),
|
|
942
|
+
outputTokens: pick(sdkTotal.outputTokens, accumulated?.outputTokens),
|
|
943
|
+
reasoningTokens: pick(sdkTotal.reasoningTokens, accumulated?.reasoningTokens),
|
|
944
|
+
cacheReadTokens: pick(sdkTotal.cacheReadTokens, accumulated?.cacheReadTokens),
|
|
945
|
+
cacheWriteTokens: pick(sdkTotal.cacheWriteTokens, accumulated?.cacheWriteTokens),
|
|
946
|
+
cost: accumulated?.cost ?? { provenance: "unavailable" }
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
function statedUsage(usage) {
|
|
950
|
+
const stated = (value) => value ?? { provenance: "unavailable" };
|
|
951
|
+
if (!usage)
|
|
952
|
+
return unknownUsage();
|
|
953
|
+
return {
|
|
954
|
+
inputTokens: stated(usage.inputTokens),
|
|
955
|
+
outputTokens: stated(usage.outputTokens),
|
|
956
|
+
reasoningTokens: stated(usage.reasoningTokens),
|
|
957
|
+
cacheReadTokens: stated(usage.cacheReadTokens),
|
|
958
|
+
cacheWriteTokens: stated(usage.cacheWriteTokens),
|
|
959
|
+
cost: stated(usage.cost)
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function unknownUsage() {
|
|
963
|
+
const nothing = { provenance: "unavailable" };
|
|
964
|
+
return {
|
|
965
|
+
inputTokens: nothing,
|
|
966
|
+
outputTokens: nothing,
|
|
967
|
+
reasoningTokens: nothing,
|
|
968
|
+
cacheReadTokens: nothing,
|
|
969
|
+
cacheWriteTokens: nothing,
|
|
970
|
+
cost: nothing
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
function normalizeSdkUsage(value) {
|
|
974
|
+
const reported = (tokens) => tokens === undefined || !Number.isSafeInteger(tokens) || tokens < 0 ? { provenance: "unavailable" } : { value: tokens, provenance: "provider-reported" };
|
|
975
|
+
return {
|
|
976
|
+
inputTokens: reported(value.inputTokens),
|
|
977
|
+
outputTokens: reported(value.outputTokens),
|
|
978
|
+
reasoningTokens: reported(value.outputTokenDetails.reasoningTokens),
|
|
979
|
+
cacheReadTokens: reported(value.inputTokenDetails.cacheReadTokens),
|
|
980
|
+
cacheWriteTokens: reported(value.inputTokenDetails.cacheWriteTokens)
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
function createIdleDeadline(parent, timeoutMs) {
|
|
984
|
+
if (timeoutMs === undefined) {
|
|
985
|
+
const noop = () => {
|
|
986
|
+
return;
|
|
987
|
+
};
|
|
988
|
+
return {
|
|
989
|
+
signal: parent,
|
|
990
|
+
touch: noop,
|
|
991
|
+
start: noop,
|
|
992
|
+
stop: noop,
|
|
993
|
+
suspend: noop,
|
|
994
|
+
resume: noop,
|
|
995
|
+
dispose: noop
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
const controller = new AbortController;
|
|
999
|
+
let timer;
|
|
1000
|
+
let active = false;
|
|
1001
|
+
let suspended = 0;
|
|
1002
|
+
const clear = () => {
|
|
1003
|
+
if (timer !== undefined)
|
|
1004
|
+
clearTimeout(timer);
|
|
1005
|
+
timer = undefined;
|
|
1006
|
+
};
|
|
1007
|
+
const touch = () => {
|
|
1008
|
+
clear();
|
|
1009
|
+
if (!active || suspended > 0 || controller.signal.aborted)
|
|
1010
|
+
return;
|
|
1011
|
+
timer = setTimeout(() => controller.abort("timeout"), timeoutMs);
|
|
1012
|
+
};
|
|
1013
|
+
return {
|
|
1014
|
+
signal: AbortSignal.any([parent, controller.signal]),
|
|
1015
|
+
touch,
|
|
1016
|
+
start() {
|
|
1017
|
+
active = true;
|
|
1018
|
+
touch();
|
|
1019
|
+
},
|
|
1020
|
+
stop() {
|
|
1021
|
+
active = false;
|
|
1022
|
+
clear();
|
|
1023
|
+
},
|
|
1024
|
+
suspend() {
|
|
1025
|
+
suspended += 1;
|
|
1026
|
+
clear();
|
|
1027
|
+
},
|
|
1028
|
+
resume() {
|
|
1029
|
+
suspended = Math.max(0, suspended - 1);
|
|
1030
|
+
touch();
|
|
1031
|
+
},
|
|
1032
|
+
dispose() {
|
|
1033
|
+
active = false;
|
|
1034
|
+
clear();
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// src/agent-runtime/invocation-attempt.ts
|
|
1040
|
+
var currentAttempt = new AsyncLocalStorage;
|
|
1041
|
+
function currentModelInvocationAttempt() {
|
|
1042
|
+
const value = currentAttempt.getStore();
|
|
1043
|
+
return value && { ...value };
|
|
1044
|
+
}
|
|
1045
|
+
function wrapInvocationModel(writer, selected, step, model = selected.model) {
|
|
1046
|
+
if (typeof model === "string")
|
|
1047
|
+
throw new TypeError("Invocation receipts require a resolved model object");
|
|
1048
|
+
const begin = async (params) => invocationAudit(async () => {
|
|
1049
|
+
const context = { ...writer.identity, step, attemptId: randomUUID2() };
|
|
1050
|
+
const { headers: _headers, abortSignal: _signal, ...payload } = params;
|
|
1051
|
+
const artifact = await writer.payloads.write(writer.identity, payload);
|
|
1052
|
+
await writer.append({
|
|
1053
|
+
...writer.identity,
|
|
1054
|
+
type: "provider/request",
|
|
1055
|
+
attemptId: context.attemptId,
|
|
1056
|
+
step,
|
|
1057
|
+
executingProcess: writer.process,
|
|
1058
|
+
requested: {
|
|
1059
|
+
modelId: selected.descriptor.modelId,
|
|
1060
|
+
provider: selected.descriptor.provider
|
|
1061
|
+
},
|
|
1062
|
+
sent: {
|
|
1063
|
+
modelId: model.modelId,
|
|
1064
|
+
provider: model.provider,
|
|
1065
|
+
payloadSha256: artifact.sha256,
|
|
1066
|
+
artifactId: artifact.artifactId,
|
|
1067
|
+
tools: params.tools?.length ?? 0
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
try {
|
|
1071
|
+
await writer.onAttempt?.({ ...context });
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
await finish(context, "failed", { phase: "transport-audit", error });
|
|
1074
|
+
throw error;
|
|
1075
|
+
}
|
|
1076
|
+
return context;
|
|
1077
|
+
});
|
|
1078
|
+
const finish = (...args) => recordResponse(...args).catch((error) => {
|
|
1079
|
+
writer.receiptErrors.push(error);
|
|
1080
|
+
});
|
|
1081
|
+
const recordResponse = async (context, status, payload, usage, response, providerMetadata) => invocationAudit(async () => {
|
|
1082
|
+
const artifact = await writer.payloads.write(writer.identity, boundedEvidence(payload, Math.floor(writer.payloads.maxBytes / 2)));
|
|
1083
|
+
await writer.append({
|
|
1084
|
+
...writer.identity,
|
|
1085
|
+
type: "provider/response",
|
|
1086
|
+
attemptId: context.attemptId,
|
|
1087
|
+
step,
|
|
1088
|
+
status,
|
|
1089
|
+
effective: {
|
|
1090
|
+
provider: selected.resolveResponseProvider?.({ providerMetadata }) ?? null,
|
|
1091
|
+
modelId: response?.modelId ?? null,
|
|
1092
|
+
responseId: response?.id ?? null
|
|
1093
|
+
},
|
|
1094
|
+
usage: reportedUsage(selected, usage, providerMetadata),
|
|
1095
|
+
artifactId: artifact.artifactId,
|
|
1096
|
+
payloadSha256: artifact.sha256
|
|
1097
|
+
});
|
|
1098
|
+
});
|
|
1099
|
+
return wrapLanguageModel({
|
|
1100
|
+
model,
|
|
1101
|
+
middleware: {
|
|
1102
|
+
specificationVersion: "v4",
|
|
1103
|
+
async wrapGenerate({ doGenerate, params }) {
|
|
1104
|
+
const context = await begin(params);
|
|
1105
|
+
let result;
|
|
1106
|
+
try {
|
|
1107
|
+
result = await currentAttempt.run(context, doGenerate);
|
|
1108
|
+
} catch (error) {
|
|
1109
|
+
await finish(context, params.abortSignal?.aborted ? "cancelled" : "failed", {
|
|
1110
|
+
error
|
|
1111
|
+
});
|
|
1112
|
+
throw markProviderOrigin(error);
|
|
1113
|
+
}
|
|
1114
|
+
await finish(context, result.finishReason.unified === "error" ? "failed" : "succeeded", {
|
|
1115
|
+
content: result.content,
|
|
1116
|
+
usage: result.usage,
|
|
1117
|
+
response: result.response,
|
|
1118
|
+
providerMetadata: result.providerMetadata
|
|
1119
|
+
}, result.usage, result.response, result.providerMetadata);
|
|
1120
|
+
if (result.finishReason.unified === "error") {
|
|
1121
|
+
throw markProviderOrigin(new Error("Provider returned an error finish reason"));
|
|
1122
|
+
}
|
|
1123
|
+
return result;
|
|
1124
|
+
},
|
|
1125
|
+
async wrapStream({ doStream, params }) {
|
|
1126
|
+
const context = await begin(params);
|
|
1127
|
+
let result;
|
|
1128
|
+
try {
|
|
1129
|
+
result = await currentAttempt.run(context, doStream);
|
|
1130
|
+
} catch (error) {
|
|
1131
|
+
await finish(context, params.abortSignal?.aborted ? "cancelled" : "failed", {
|
|
1132
|
+
error
|
|
1133
|
+
});
|
|
1134
|
+
throw markProviderOrigin(error);
|
|
1135
|
+
}
|
|
1136
|
+
const reader = result.stream.getReader();
|
|
1137
|
+
let ended = false;
|
|
1138
|
+
let failed = false;
|
|
1139
|
+
let response;
|
|
1140
|
+
const evidence = streamEvidence(Math.floor(writer.payloads.maxBytes / 2));
|
|
1141
|
+
const end = async (status, value, usage, metadata) => {
|
|
1142
|
+
if (ended)
|
|
1143
|
+
return;
|
|
1144
|
+
ended = true;
|
|
1145
|
+
await finish(context, status, evidence.payload(value), usage, response, metadata);
|
|
1146
|
+
};
|
|
1147
|
+
return {
|
|
1148
|
+
...result,
|
|
1149
|
+
stream: new ReadableStream({
|
|
1150
|
+
async pull(controller) {
|
|
1151
|
+
let next;
|
|
1152
|
+
try {
|
|
1153
|
+
next = await currentAttempt.run(context, () => reader.read());
|
|
1154
|
+
} catch (error) {
|
|
1155
|
+
await end(params.abortSignal?.aborted ? "cancelled" : "failed", { error });
|
|
1156
|
+
controller.error(markProviderOrigin(error));
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
if (next.done) {
|
|
1160
|
+
await end("failed", { reason: "stream-ended-without-finish" });
|
|
1161
|
+
controller.close();
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
const part = next.value;
|
|
1165
|
+
if (part.type === "response-metadata")
|
|
1166
|
+
response = part;
|
|
1167
|
+
if (part.type === "finish") {
|
|
1168
|
+
await end(failed || part.finishReason.unified === "error" ? "failed" : "succeeded", part, part.usage, part.providerMetadata);
|
|
1169
|
+
} else {
|
|
1170
|
+
if (part.type === "error")
|
|
1171
|
+
failed = true;
|
|
1172
|
+
evidence.record(part);
|
|
1173
|
+
}
|
|
1174
|
+
controller.enqueue(part);
|
|
1175
|
+
},
|
|
1176
|
+
async cancel(reason) {
|
|
1177
|
+
try {
|
|
1178
|
+
await currentAttempt.run(context, () => reader.cancel(reason));
|
|
1179
|
+
} finally {
|
|
1180
|
+
await end("cancelled", { reason: "consumer-cancelled" });
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
})
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
function boundedEvidence(payload, limit) {
|
|
1190
|
+
const serialized = JSON.stringify(invocationJson(payload));
|
|
1191
|
+
const bytes = Buffer.byteLength(serialized);
|
|
1192
|
+
if (bytes <= limit)
|
|
1193
|
+
return payload;
|
|
1194
|
+
return {
|
|
1195
|
+
truncated: { bytes, sha256: createHash2("sha256").update(serialized).digest("hex") }
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
function streamEvidence(limit) {
|
|
1199
|
+
const output = [];
|
|
1200
|
+
const whole = createHash2("sha256");
|
|
1201
|
+
let bytes = 0;
|
|
1202
|
+
let parts = 0;
|
|
1203
|
+
let truncated = false;
|
|
1204
|
+
return {
|
|
1205
|
+
record(part) {
|
|
1206
|
+
const json = invocationJson(part);
|
|
1207
|
+
const serialized = JSON.stringify(json);
|
|
1208
|
+
whole.update(serialized).update(`
|
|
1209
|
+
`);
|
|
1210
|
+
parts += 1;
|
|
1211
|
+
const size = Buffer.byteLength(serialized);
|
|
1212
|
+
if (!truncated && bytes + size > limit)
|
|
1213
|
+
truncated = true;
|
|
1214
|
+
if (truncated)
|
|
1215
|
+
return;
|
|
1216
|
+
bytes += size;
|
|
1217
|
+
output.push(json);
|
|
1218
|
+
},
|
|
1219
|
+
payload(terminal) {
|
|
1220
|
+
return {
|
|
1221
|
+
output,
|
|
1222
|
+
terminal,
|
|
1223
|
+
...truncated && { truncated: { parts, sha256: whole.digest("hex") } }
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
function reportedUsage(selected, value, providerMetadata) {
|
|
1229
|
+
const usage = {
|
|
1230
|
+
inputTokens: value?.inputTokens.total,
|
|
1231
|
+
outputTokens: value?.outputTokens.total,
|
|
1232
|
+
totalTokens: undefined,
|
|
1233
|
+
inputTokenDetails: {
|
|
1234
|
+
noCacheTokens: value?.inputTokens.noCache,
|
|
1235
|
+
cacheReadTokens: value?.inputTokens.cacheRead,
|
|
1236
|
+
cacheWriteTokens: value?.inputTokens.cacheWrite
|
|
1237
|
+
},
|
|
1238
|
+
outputTokenDetails: {
|
|
1239
|
+
textTokens: value?.outputTokens.text,
|
|
1240
|
+
reasoningTokens: value?.outputTokens.reasoning
|
|
1241
|
+
},
|
|
1242
|
+
...value?.raw && { raw: value.raw }
|
|
1243
|
+
};
|
|
1244
|
+
return selected.normalizeUsage?.({ usage, providerMetadata }) ?? normalizeSdkUsage(usage);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
// src/agent-runtime/invocations.ts
|
|
1248
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
1249
|
+
import { hostname } from "node:os";
|
|
1250
|
+
import { generateText } from "ai";
|
|
1251
|
+
import { z as z5 } from "zod";
|
|
1252
|
+
|
|
1253
|
+
// src/agent-runtime/invocation-read.ts
|
|
1254
|
+
import { z as z4 } from "zod";
|
|
1255
|
+
var InvocationReadInputSchema = z4.object({
|
|
1256
|
+
conversationId: z4.string().min(1),
|
|
1257
|
+
fromSeq: z4.int().positive().optional(),
|
|
1258
|
+
limit: z4.int().positive().max(1e4)
|
|
1259
|
+
}).strict();
|
|
1260
|
+
async function readInvocationRecords(store, input) {
|
|
1261
|
+
const page = await store.readEvents(InvocationReadInputSchema.parse(input));
|
|
1262
|
+
return {
|
|
1263
|
+
items: page.items.flatMap((event) => {
|
|
1264
|
+
if (![
|
|
1265
|
+
"invocation/started",
|
|
1266
|
+
"invocation/finished",
|
|
1267
|
+
"provider/request",
|
|
1268
|
+
"provider/response"
|
|
1269
|
+
].includes(event.kind))
|
|
1270
|
+
return [];
|
|
1271
|
+
if (!event.payload || typeof event.payload !== "object" || !("invocationId" in event.payload))
|
|
1272
|
+
return [];
|
|
1273
|
+
return [
|
|
1274
|
+
{
|
|
1275
|
+
seq: event.seq,
|
|
1276
|
+
occurredAt: event.occurredAt,
|
|
1277
|
+
record: ModelInvocationRecordSchema.parse(event.payload)
|
|
1278
|
+
}
|
|
1279
|
+
];
|
|
1280
|
+
}),
|
|
1281
|
+
...page.nextSeq !== undefined && { nextSeq: page.nextSeq }
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
async function readInvocationPayload(store, payloads, input) {
|
|
1285
|
+
const keyed = await store.findEventOnce?.({
|
|
1286
|
+
conversationId: input.conversationId,
|
|
1287
|
+
kind: "provider/payload",
|
|
1288
|
+
key: input.artifactId
|
|
1289
|
+
});
|
|
1290
|
+
if (keyed)
|
|
1291
|
+
return payloads.decrypt(input.conversationId, keyed.payload);
|
|
1292
|
+
let fromSeq;
|
|
1293
|
+
do {
|
|
1294
|
+
const page = await store.readEvents({
|
|
1295
|
+
conversationId: input.conversationId,
|
|
1296
|
+
fromSeq,
|
|
1297
|
+
limit: 1000
|
|
1298
|
+
});
|
|
1299
|
+
for (const event of page.items) {
|
|
1300
|
+
if (event.kind !== "provider/payload")
|
|
1301
|
+
continue;
|
|
1302
|
+
const payload = InvocationPayloadSchema.parse(event.payload);
|
|
1303
|
+
if (payload.artifactId === input.artifactId)
|
|
1304
|
+
return payloads.decrypt(input.conversationId, payload);
|
|
1305
|
+
}
|
|
1306
|
+
fromSeq = page.nextSeq;
|
|
1307
|
+
} while (fromSeq !== undefined);
|
|
1308
|
+
throw new Error("Invocation artifact not found");
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
// src/agent-runtime/invocations.ts
|
|
1312
|
+
var executingProcess = { instanceId: randomUUID3(), pid: process.pid, hostname: hostname() };
|
|
1313
|
+
var agentBindings = new WeakMap;
|
|
1314
|
+
function beginAgentInvocation(ledger, store, input, context) {
|
|
1315
|
+
const binding = agentBindings.get(ledger);
|
|
1316
|
+
if (!binding || binding.store !== store)
|
|
1317
|
+
throw new TypeError("Agent and invocations must share the same store");
|
|
1318
|
+
return binding.start(input, context);
|
|
1319
|
+
}
|
|
1320
|
+
function withReceipt(result, writer) {
|
|
1321
|
+
const [receiptError] = writer.receiptErrors;
|
|
1322
|
+
return receiptError === undefined ? result : { ...result, receiptError };
|
|
1323
|
+
}
|
|
1324
|
+
async function generateWithFallback(models, writer, input, abortSignal) {
|
|
1325
|
+
for (const [step, key] of input.models.entries()) {
|
|
1326
|
+
abortSignal.throwIfAborted();
|
|
1327
|
+
const selected = models.resolve(key);
|
|
1328
|
+
try {
|
|
1329
|
+
const result = await generateText({
|
|
1330
|
+
model: wrapInvocationModel(writer, selected, step),
|
|
1331
|
+
prompt: input.prompt,
|
|
1332
|
+
...input.settings,
|
|
1333
|
+
maxRetries: 0,
|
|
1334
|
+
abortSignal
|
|
1335
|
+
});
|
|
1336
|
+
return result.text;
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
if (!hasProviderOrigin(error) || abortSignal.aborted || step === input.models.length - 1)
|
|
1339
|
+
throw error;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
throw new Error("No completion model attempt available");
|
|
1343
|
+
}
|
|
1344
|
+
function createModelInvocationLedger(config) {
|
|
1345
|
+
const { store } = config;
|
|
1346
|
+
const appendOnce = store.appendEventOnce?.bind(store);
|
|
1347
|
+
if (!appendOnce)
|
|
1348
|
+
throw new TypeError("Model invocations require atomic store.appendEventOnce");
|
|
1349
|
+
const maxPayloadBytes = z5.int().min(1024).max(64 * 1024 * 1024).parse(config.maxPayloadBytes ?? 4 * 1024 * 1024);
|
|
1350
|
+
const payloads = createInvocationPayloads(store, config.payloadKey, maxPayloadBytes);
|
|
1351
|
+
const authorize = async (input) => InvocationCallerSchema.parse(await config.authorize(input));
|
|
1352
|
+
const start = async (input) => {
|
|
1353
|
+
const trace = ModelInvocationTraceSchema.parse(input.trace);
|
|
1354
|
+
const caller = await authorize({
|
|
1355
|
+
context: input.context,
|
|
1356
|
+
conversationId: input.conversationId,
|
|
1357
|
+
action: input.mode === "completion" ? "complete" : "agent",
|
|
1358
|
+
trace
|
|
1359
|
+
});
|
|
1360
|
+
const fingerprint = invocationHash({
|
|
1361
|
+
mode: input.mode,
|
|
1362
|
+
caller,
|
|
1363
|
+
trace,
|
|
1364
|
+
requested: input.requested
|
|
1365
|
+
});
|
|
1366
|
+
const identity = {
|
|
1367
|
+
conversationId: input.conversationId,
|
|
1368
|
+
invocationId: randomUUID3(),
|
|
1369
|
+
operationId: trace.operationId,
|
|
1370
|
+
...input.runId && { runId: input.runId }
|
|
1371
|
+
};
|
|
1372
|
+
const started = InvocationStartedSchema.parse({
|
|
1373
|
+
...identity,
|
|
1374
|
+
type: "invocation/started",
|
|
1375
|
+
mode: input.mode,
|
|
1376
|
+
trace,
|
|
1377
|
+
caller,
|
|
1378
|
+
executingProcess,
|
|
1379
|
+
fingerprint,
|
|
1380
|
+
requested: { models: input.models, payloadSha256: invocationHash(input.requested) }
|
|
1381
|
+
});
|
|
1382
|
+
const admission = await appendOnce({ conversationId: input.conversationId, kind: "invocation/started", payload: started }, input.key);
|
|
1383
|
+
const previous = InvocationStartedSchema.parse(admission.event.payload);
|
|
1384
|
+
if (previous.fingerprint !== fingerprint)
|
|
1385
|
+
throw new Error("Invocation idempotency key conflicts with an existing request");
|
|
1386
|
+
const writer = {
|
|
1387
|
+
identity: { ...identity, invocationId: previous.invocationId },
|
|
1388
|
+
process: executingProcess,
|
|
1389
|
+
payloads,
|
|
1390
|
+
onAttempt: config.onAttempt,
|
|
1391
|
+
receiptErrors: [],
|
|
1392
|
+
async append(record) {
|
|
1393
|
+
const parsed = ModelInvocationRecordSchema.parse(record);
|
|
1394
|
+
await store.appendEvent({
|
|
1395
|
+
conversationId: input.conversationId,
|
|
1396
|
+
kind: parsed.type,
|
|
1397
|
+
payload: parsed
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
return { writer, duplicate: admission.outcome === "duplicate" };
|
|
1402
|
+
};
|
|
1403
|
+
const finish = (writer, status, failure) => writer.append({
|
|
1404
|
+
...writer.identity,
|
|
1405
|
+
type: "invocation/finished",
|
|
1406
|
+
status,
|
|
1407
|
+
...failure && { failure }
|
|
1408
|
+
});
|
|
1409
|
+
const ledger = {
|
|
1410
|
+
async complete(rawInput, context, signal) {
|
|
1411
|
+
const input = CompletionInvocationInputSchema.parse(rawInput);
|
|
1412
|
+
const { writer, duplicate } = await start({
|
|
1413
|
+
conversationId: input.conversationId,
|
|
1414
|
+
key: `completion:${input.idempotencyKey}`,
|
|
1415
|
+
trace: input.trace,
|
|
1416
|
+
mode: "completion",
|
|
1417
|
+
context,
|
|
1418
|
+
requested: input,
|
|
1419
|
+
models: input.models
|
|
1420
|
+
});
|
|
1421
|
+
const invocationId = writer.identity.invocationId;
|
|
1422
|
+
if (duplicate)
|
|
1423
|
+
return { invocationId, outcome: "duplicate" };
|
|
1424
|
+
const deadline = AbortSignal.timeout(input.timeoutMs);
|
|
1425
|
+
const abortSignal = signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
1426
|
+
let text;
|
|
1427
|
+
try {
|
|
1428
|
+
text = await generateWithFallback(config.models, writer, input, abortSignal);
|
|
1429
|
+
} catch (error) {
|
|
1430
|
+
const status = abortSignal.aborted ? "cancelled" : "failed";
|
|
1431
|
+
try {
|
|
1432
|
+
const artifact = await payloads.write(writer.identity, { error });
|
|
1433
|
+
await finish(writer, status, {
|
|
1434
|
+
artifactId: artifact.artifactId,
|
|
1435
|
+
payloadSha256: artifact.sha256
|
|
1436
|
+
});
|
|
1437
|
+
} catch (receiptError) {
|
|
1438
|
+
writer.receiptErrors.push(receiptError);
|
|
1439
|
+
await finish(writer, status).catch((error2) => {
|
|
1440
|
+
writer.receiptErrors.push(error2);
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
return withReceipt({ invocationId, outcome: status }, writer);
|
|
1444
|
+
}
|
|
1445
|
+
try {
|
|
1446
|
+
await finish(writer, "succeeded");
|
|
1447
|
+
} catch (receiptError) {
|
|
1448
|
+
writer.receiptErrors.push(receiptError);
|
|
1449
|
+
}
|
|
1450
|
+
return withReceipt({ invocationId, outcome: "succeeded", text }, writer);
|
|
1451
|
+
},
|
|
1452
|
+
async read(rawInput, context) {
|
|
1453
|
+
const input = InvocationReadInputSchema.parse(rawInput);
|
|
1454
|
+
await authorize({ context, conversationId: input.conversationId, action: "read" });
|
|
1455
|
+
return readInvocationRecords(store, input);
|
|
1456
|
+
},
|
|
1457
|
+
async readPayload(input, context) {
|
|
1458
|
+
await authorize({
|
|
1459
|
+
context,
|
|
1460
|
+
conversationId: input.conversationId,
|
|
1461
|
+
action: "read-payload"
|
|
1462
|
+
});
|
|
1463
|
+
return readInvocationPayload(store, payloads, input);
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
agentBindings.set(ledger, {
|
|
1467
|
+
store,
|
|
1468
|
+
async start(input, context) {
|
|
1469
|
+
const { conversationId, id: runId } = input.run;
|
|
1470
|
+
const view = await store.loadRun({ conversationId, runId });
|
|
1471
|
+
if (view?.run.state !== "running" || view.run.ownerId !== input.run.ownerId || view.run.fencingToken !== input.run.fencingToken) {
|
|
1472
|
+
throw new Error("Invocation requires an owned running agent run");
|
|
1473
|
+
}
|
|
1474
|
+
const { writer } = await start({
|
|
1475
|
+
conversationId,
|
|
1476
|
+
runId,
|
|
1477
|
+
trace: input.trace,
|
|
1478
|
+
key: `agent:${runId}`,
|
|
1479
|
+
context,
|
|
1480
|
+
mode: "agent",
|
|
1481
|
+
models: [],
|
|
1482
|
+
requested: { runId }
|
|
1483
|
+
});
|
|
1484
|
+
return {
|
|
1485
|
+
wrap: (selected, step, override) => wrapInvocationModel(writer, selected, step, override),
|
|
1486
|
+
finish: (status) => finish(writer, status)
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
return ledger;
|
|
608
1491
|
}
|
|
609
1492
|
|
|
610
1493
|
// src/agent-runtime/managed-tools.ts
|
|
@@ -632,9 +1515,9 @@ function createAgentToolFenceLifecycle(config) {
|
|
|
632
1515
|
}
|
|
633
1516
|
|
|
634
1517
|
// src/agent-runtime/prompt.ts
|
|
635
|
-
import { z } from "zod";
|
|
636
|
-
var AgentTokenCountSchema =
|
|
637
|
-
value:
|
|
1518
|
+
import { z as z6 } from "zod";
|
|
1519
|
+
var AgentTokenCountSchema = z6.object({
|
|
1520
|
+
value: z6.int().nonnegative().optional(),
|
|
638
1521
|
provenance: AgentProvenanceSchema.extract([
|
|
639
1522
|
"measured",
|
|
640
1523
|
"computed",
|
|
@@ -754,7 +1637,7 @@ function knownValue(value) {
|
|
|
754
1637
|
}
|
|
755
1638
|
function composeAgentPrompt(sections) {
|
|
756
1639
|
return async (options) => {
|
|
757
|
-
const event =
|
|
1640
|
+
const event = z6.enum(["session.started", "turn.started"]).parse(options.event ?? "turn.started");
|
|
758
1641
|
const rendered = [];
|
|
759
1642
|
let systemTotal = 0;
|
|
760
1643
|
let userTotal = 0;
|
|
@@ -957,7 +1840,7 @@ async function recordAgentRetryDecision(input) {
|
|
|
957
1840
|
}
|
|
958
1841
|
|
|
959
1842
|
// src/agent-runtime/state-slots.ts
|
|
960
|
-
import { z as
|
|
1843
|
+
import { z as z7 } from "zod";
|
|
961
1844
|
function defineStateSlot(input) {
|
|
962
1845
|
if (input.name.length === 0)
|
|
963
1846
|
throw new TypeError("State slot name must not be empty");
|
|
@@ -972,11 +1855,11 @@ function defineStateSlot(input) {
|
|
|
972
1855
|
...input.description && { description: input.description }
|
|
973
1856
|
};
|
|
974
1857
|
}
|
|
975
|
-
var StateSetPayloadSchema =
|
|
976
|
-
name:
|
|
977
|
-
version:
|
|
978
|
-
value:
|
|
979
|
-
actor:
|
|
1858
|
+
var StateSetPayloadSchema = z7.object({
|
|
1859
|
+
name: z7.string().min(1),
|
|
1860
|
+
version: z7.int().positive(),
|
|
1861
|
+
value: z7.json(),
|
|
1862
|
+
actor: z7.enum(["agent", "human", "system"])
|
|
980
1863
|
}).strict();
|
|
981
1864
|
function slotRegistry(definitions) {
|
|
982
1865
|
const result = new Map;
|
|
@@ -1058,204 +1941,22 @@ function renderAgentStateSlots(values) {
|
|
|
1058
1941
|
var agentGoalStateSlot = defineStateSlot({
|
|
1059
1942
|
name: "goal",
|
|
1060
1943
|
description: "The durable objective and lifecycle of this conversation.",
|
|
1061
|
-
schema:
|
|
1062
|
-
objective:
|
|
1063
|
-
status:
|
|
1944
|
+
schema: z7.object({
|
|
1945
|
+
objective: z7.string().min(1),
|
|
1946
|
+
status: z7.enum(["active", "complete", "blocked"])
|
|
1064
1947
|
}).strict()
|
|
1065
1948
|
});
|
|
1066
1949
|
var agentTodoStateSlot = defineStateSlot({
|
|
1067
1950
|
name: "todo",
|
|
1068
1951
|
description: "The durable ordered work plan for this conversation.",
|
|
1069
|
-
schema:
|
|
1070
|
-
items:
|
|
1071
|
-
step:
|
|
1072
|
-
status:
|
|
1952
|
+
schema: z7.object({
|
|
1953
|
+
items: z7.array(z7.object({
|
|
1954
|
+
step: z7.string().min(1),
|
|
1955
|
+
status: z7.enum(["pending", "in_progress", "completed"])
|
|
1073
1956
|
}).strict())
|
|
1074
1957
|
}).strict()
|
|
1075
1958
|
});
|
|
1076
1959
|
|
|
1077
|
-
// src/agent-runtime/runtime-internals.ts
|
|
1078
|
-
import { z as z3 } from "zod";
|
|
1079
|
-
function findRun(runs, runId) {
|
|
1080
|
-
const run = runs.find((candidate) => candidate.id === runId);
|
|
1081
|
-
if (!run)
|
|
1082
|
-
throw new AgentRuntimeConflictError("run lookup");
|
|
1083
|
-
return run;
|
|
1084
|
-
}
|
|
1085
|
-
function jsonValue(value) {
|
|
1086
|
-
const parsed = z3.json().safeParse(value);
|
|
1087
|
-
return parsed.success ? parsed.data : { message: "Non-JSON tool output omitted" };
|
|
1088
|
-
}
|
|
1089
|
-
function providerEnvelope(value) {
|
|
1090
|
-
const parsed = AgentJsonObjectSchema.safeParse(value);
|
|
1091
|
-
if (!parsed.success)
|
|
1092
|
-
return;
|
|
1093
|
-
return { schemaVersion: 1, provider: "ai-sdk", data: parsed.data };
|
|
1094
|
-
}
|
|
1095
|
-
function providerResponseIdentity(id, provider) {
|
|
1096
|
-
return AgentProviderResponseSchema.parse({
|
|
1097
|
-
id,
|
|
1098
|
-
...typeof provider === "string" && provider.length > 0 ? { provider } : {}
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
function appendText(parts, text) {
|
|
1102
|
-
const previous = parts.at(-1);
|
|
1103
|
-
if (previous?.type === "text") {
|
|
1104
|
-
const next = AgentMessagePartSchema.parse({ ...previous, text: previous.text + text });
|
|
1105
|
-
parts.splice(parts.length - 1, 1, next);
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
parts.push(AgentMessagePartSchema.parse({ type: "text", text }));
|
|
1109
|
-
}
|
|
1110
|
-
function abortTerminalReason(signal) {
|
|
1111
|
-
if (signal.reason === "shutdown")
|
|
1112
|
-
return "shutdown";
|
|
1113
|
-
if (signal.reason === "timeout")
|
|
1114
|
-
return "timeout";
|
|
1115
|
-
if (signal.reason === "supersede")
|
|
1116
|
-
return "superseded";
|
|
1117
|
-
return "interrupted";
|
|
1118
|
-
}
|
|
1119
|
-
function addUsage(total, step) {
|
|
1120
|
-
const sum = (left, right) => {
|
|
1121
|
-
if (left?.value === undefined && right?.value === undefined) {
|
|
1122
|
-
return { provenance: "unavailable" };
|
|
1123
|
-
}
|
|
1124
|
-
if (left?.value === undefined)
|
|
1125
|
-
return { ...right, provenance: "computed" };
|
|
1126
|
-
if (right?.value === undefined)
|
|
1127
|
-
return { ...left, provenance: "computed" };
|
|
1128
|
-
return { value: left.value + right.value, provenance: "computed" };
|
|
1129
|
-
};
|
|
1130
|
-
const sumCost = (left, right) => {
|
|
1131
|
-
if (left?.value === undefined || right?.value === undefined) {
|
|
1132
|
-
return { provenance: "unavailable" };
|
|
1133
|
-
}
|
|
1134
|
-
if (left.currency !== right.currency)
|
|
1135
|
-
return { provenance: "unavailable" };
|
|
1136
|
-
return {
|
|
1137
|
-
value: left.value + right.value,
|
|
1138
|
-
...left.currency && { currency: left.currency },
|
|
1139
|
-
provenance: "computed"
|
|
1140
|
-
};
|
|
1141
|
-
};
|
|
1142
|
-
if (!total)
|
|
1143
|
-
return step;
|
|
1144
|
-
const cost = sumCost(total.cost, step.cost);
|
|
1145
|
-
return {
|
|
1146
|
-
inputTokens: sum(total.inputTokens, step.inputTokens),
|
|
1147
|
-
outputTokens: sum(total.outputTokens, step.outputTokens),
|
|
1148
|
-
reasoningTokens: sum(total.reasoningTokens, step.reasoningTokens),
|
|
1149
|
-
cacheReadTokens: sum(total.cacheReadTokens, step.cacheReadTokens),
|
|
1150
|
-
cacheWriteTokens: sum(total.cacheWriteTokens, step.cacheWriteTokens),
|
|
1151
|
-
...cost && { cost }
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
function mergeModelTotals(sdkTotal, accumulated) {
|
|
1155
|
-
const pick = (total, ours) => {
|
|
1156
|
-
if (ours?.provenance === "unavailable")
|
|
1157
|
-
return ours;
|
|
1158
|
-
return total?.value !== undefined ? { value: total.value, provenance: "computed" } : ours ?? { provenance: "unavailable" };
|
|
1159
|
-
};
|
|
1160
|
-
return {
|
|
1161
|
-
inputTokens: pick(sdkTotal.inputTokens, accumulated?.inputTokens),
|
|
1162
|
-
outputTokens: pick(sdkTotal.outputTokens, accumulated?.outputTokens),
|
|
1163
|
-
reasoningTokens: pick(sdkTotal.reasoningTokens, accumulated?.reasoningTokens),
|
|
1164
|
-
cacheReadTokens: pick(sdkTotal.cacheReadTokens, accumulated?.cacheReadTokens),
|
|
1165
|
-
cacheWriteTokens: pick(sdkTotal.cacheWriteTokens, accumulated?.cacheWriteTokens),
|
|
1166
|
-
cost: accumulated?.cost ?? { provenance: "unavailable" }
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
function statedUsage(usage) {
|
|
1170
|
-
const stated = (value) => value ?? { provenance: "unavailable" };
|
|
1171
|
-
if (!usage)
|
|
1172
|
-
return unknownUsage();
|
|
1173
|
-
return {
|
|
1174
|
-
inputTokens: stated(usage.inputTokens),
|
|
1175
|
-
outputTokens: stated(usage.outputTokens),
|
|
1176
|
-
reasoningTokens: stated(usage.reasoningTokens),
|
|
1177
|
-
cacheReadTokens: stated(usage.cacheReadTokens),
|
|
1178
|
-
cacheWriteTokens: stated(usage.cacheWriteTokens),
|
|
1179
|
-
cost: stated(usage.cost)
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
function unknownUsage() {
|
|
1183
|
-
const nothing = { provenance: "unavailable" };
|
|
1184
|
-
return {
|
|
1185
|
-
inputTokens: nothing,
|
|
1186
|
-
outputTokens: nothing,
|
|
1187
|
-
reasoningTokens: nothing,
|
|
1188
|
-
cacheReadTokens: nothing,
|
|
1189
|
-
cacheWriteTokens: nothing,
|
|
1190
|
-
cost: nothing
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
function normalizeSdkUsage(value) {
|
|
1194
|
-
const reported = (tokens) => tokens === undefined || !Number.isSafeInteger(tokens) || tokens < 0 ? { provenance: "unavailable" } : { value: tokens, provenance: "provider-reported" };
|
|
1195
|
-
return {
|
|
1196
|
-
inputTokens: reported(value.inputTokens),
|
|
1197
|
-
outputTokens: reported(value.outputTokens),
|
|
1198
|
-
reasoningTokens: reported(value.outputTokenDetails.reasoningTokens),
|
|
1199
|
-
cacheReadTokens: reported(value.inputTokenDetails.cacheReadTokens),
|
|
1200
|
-
cacheWriteTokens: reported(value.inputTokenDetails.cacheWriteTokens)
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
function createIdleDeadline(parent, timeoutMs) {
|
|
1204
|
-
if (timeoutMs === undefined) {
|
|
1205
|
-
const noop = () => {
|
|
1206
|
-
return;
|
|
1207
|
-
};
|
|
1208
|
-
return {
|
|
1209
|
-
signal: parent,
|
|
1210
|
-
touch: noop,
|
|
1211
|
-
start: noop,
|
|
1212
|
-
stop: noop,
|
|
1213
|
-
suspend: noop,
|
|
1214
|
-
resume: noop,
|
|
1215
|
-
dispose: noop
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
1218
|
-
const controller = new AbortController;
|
|
1219
|
-
let timer;
|
|
1220
|
-
let active = false;
|
|
1221
|
-
let suspended = 0;
|
|
1222
|
-
const clear = () => {
|
|
1223
|
-
if (timer !== undefined)
|
|
1224
|
-
clearTimeout(timer);
|
|
1225
|
-
timer = undefined;
|
|
1226
|
-
};
|
|
1227
|
-
const touch = () => {
|
|
1228
|
-
clear();
|
|
1229
|
-
if (!active || suspended > 0 || controller.signal.aborted)
|
|
1230
|
-
return;
|
|
1231
|
-
timer = setTimeout(() => controller.abort("timeout"), timeoutMs);
|
|
1232
|
-
};
|
|
1233
|
-
return {
|
|
1234
|
-
signal: AbortSignal.any([parent, controller.signal]),
|
|
1235
|
-
touch,
|
|
1236
|
-
start() {
|
|
1237
|
-
active = true;
|
|
1238
|
-
touch();
|
|
1239
|
-
},
|
|
1240
|
-
stop() {
|
|
1241
|
-
active = false;
|
|
1242
|
-
clear();
|
|
1243
|
-
},
|
|
1244
|
-
suspend() {
|
|
1245
|
-
suspended += 1;
|
|
1246
|
-
clear();
|
|
1247
|
-
},
|
|
1248
|
-
resume() {
|
|
1249
|
-
suspended = Math.max(0, suspended - 1);
|
|
1250
|
-
touch();
|
|
1251
|
-
},
|
|
1252
|
-
dispose() {
|
|
1253
|
-
active = false;
|
|
1254
|
-
clear();
|
|
1255
|
-
}
|
|
1256
|
-
};
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
1960
|
// src/agent-runtime/runtime-control.ts
|
|
1260
1961
|
async function interruptAgentRun(state, input) {
|
|
1261
1962
|
const { store } = state.config;
|
|
@@ -1744,64 +2445,8 @@ function checkpoint(execution) {
|
|
|
1744
2445
|
});
|
|
1745
2446
|
}
|
|
1746
2447
|
|
|
1747
|
-
// src/agent-runtime/run-mutation-queue.ts
|
|
1748
|
-
function createRunMutationQueue() {
|
|
1749
|
-
let tail = Promise.resolve();
|
|
1750
|
-
return (mutation) => {
|
|
1751
|
-
const result = tail.then(mutation, mutation);
|
|
1752
|
-
tail = result.then(() => {
|
|
1753
|
-
return;
|
|
1754
|
-
}, () => {
|
|
1755
|
-
return;
|
|
1756
|
-
});
|
|
1757
|
-
return result;
|
|
1758
|
-
};
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
// src/agent-runtime/run-operation-lifecycle.ts
|
|
1762
|
-
import { wrapLanguageModel } from "ai";
|
|
1763
|
-
|
|
1764
|
-
// src/agent-runtime/provider-origin.ts
|
|
1765
|
-
import {
|
|
1766
|
-
InvalidToolApprovalError,
|
|
1767
|
-
InvalidToolApprovalSignatureError,
|
|
1768
|
-
ToolCallNotFoundForApprovalError
|
|
1769
|
-
} from "ai";
|
|
1770
|
-
var providerOrigin = new WeakSet;
|
|
1771
|
-
function isOwnInputRefusal(error) {
|
|
1772
|
-
return InvalidToolApprovalSignatureError.isInstance(error) || InvalidToolApprovalError.isInstance(error) || ToolCallNotFoundForApprovalError.isInstance(error);
|
|
1773
|
-
}
|
|
1774
|
-
function markProviderOrigin(error) {
|
|
1775
|
-
if (typeof error === "object" && error !== null)
|
|
1776
|
-
providerOrigin.add(error);
|
|
1777
|
-
return error;
|
|
1778
|
-
}
|
|
1779
|
-
function hasProviderOrigin(error) {
|
|
1780
|
-
return typeof error === "object" && error !== null && providerOrigin.has(error);
|
|
1781
|
-
}
|
|
1782
|
-
function markProviderStream(stream) {
|
|
1783
|
-
const reader = stream.getReader();
|
|
1784
|
-
return new ReadableStream({
|
|
1785
|
-
async pull(controller) {
|
|
1786
|
-
let read;
|
|
1787
|
-
try {
|
|
1788
|
-
read = await reader.read();
|
|
1789
|
-
} catch (error) {
|
|
1790
|
-
controller.error(isOwnInputRefusal(error) ? error : markProviderOrigin(error));
|
|
1791
|
-
return;
|
|
1792
|
-
}
|
|
1793
|
-
if (read.done)
|
|
1794
|
-
controller.close();
|
|
1795
|
-
else
|
|
1796
|
-
controller.enqueue(read.value);
|
|
1797
|
-
},
|
|
1798
|
-
cancel(reason) {
|
|
1799
|
-
return reader.cancel(reason);
|
|
1800
|
-
}
|
|
1801
|
-
});
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
2448
|
// src/agent-runtime/run-operation-lifecycle.ts
|
|
2449
|
+
import { wrapLanguageModel as wrapLanguageModel2 } from "ai";
|
|
1805
2450
|
function createAgentRunOperationLifecycle(config) {
|
|
1806
2451
|
let active;
|
|
1807
2452
|
let providerCallId;
|
|
@@ -1853,7 +2498,7 @@ function createAgentRunOperationLifecycle(config) {
|
|
|
1853
2498
|
await startModelRequest(fallbackCallId, step);
|
|
1854
2499
|
return model;
|
|
1855
2500
|
}
|
|
1856
|
-
return
|
|
2501
|
+
return wrapLanguageModel2({
|
|
1857
2502
|
model,
|
|
1858
2503
|
middleware: {
|
|
1859
2504
|
specificationVersion: "v4",
|
|
@@ -2029,7 +2674,7 @@ async function acquireRun(dependencies, input) {
|
|
|
2029
2674
|
lastPromptTokens: { provenance: "unavailable" }
|
|
2030
2675
|
};
|
|
2031
2676
|
const idleDeadline = createIdleDeadline(input.signal, idleTimeoutMs);
|
|
2032
|
-
const serialize =
|
|
2677
|
+
const serialize = createMutationQueue();
|
|
2033
2678
|
const operationLifecycle = createAgentRunOperationLifecycle({
|
|
2034
2679
|
store: config.store,
|
|
2035
2680
|
runtimeEpoch,
|
|
@@ -2057,6 +2702,8 @@ async function acquireRun(dependencies, input) {
|
|
|
2057
2702
|
|
|
2058
2703
|
// src/agent-runtime/run-failure.ts
|
|
2059
2704
|
function failureThisRuntimeOwns(error) {
|
|
2705
|
+
if (error instanceof InvocationReceiptError)
|
|
2706
|
+
return "runtime_failure";
|
|
2060
2707
|
if (error instanceof AgentContextOverflowError)
|
|
2061
2708
|
return "context_overflow";
|
|
2062
2709
|
if (error instanceof AgentRuntimeConflictError)
|
|
@@ -2174,14 +2821,14 @@ async function* ownedProviderStream(input) {
|
|
|
2174
2821
|
}
|
|
2175
2822
|
|
|
2176
2823
|
// src/agent-runtime/run-provider-ledger.ts
|
|
2177
|
-
import { createHash } from "node:crypto";
|
|
2824
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
2178
2825
|
function withoutBinaryParts(message) {
|
|
2179
2826
|
const reference = (value) => {
|
|
2180
2827
|
if (value instanceof Uint8Array || value instanceof ArrayBuffer) {
|
|
2181
2828
|
const bytes = value instanceof ArrayBuffer ? new Uint8Array(value) : value;
|
|
2182
2829
|
return {
|
|
2183
2830
|
binary: true,
|
|
2184
|
-
sha256:
|
|
2831
|
+
sha256: createHash3("sha256").update(bytes).digest("hex"),
|
|
2185
2832
|
bytes: bytes.byteLength
|
|
2186
2833
|
};
|
|
2187
2834
|
}
|
|
@@ -2201,6 +2848,16 @@ function withoutBinaryParts(message) {
|
|
|
2201
2848
|
}
|
|
2202
2849
|
async function createRunProviderLedger(input) {
|
|
2203
2850
|
const { store, state } = input;
|
|
2851
|
+
if (input.audited) {
|
|
2852
|
+
return {
|
|
2853
|
+
async recordRequest() {},
|
|
2854
|
+
async recordResponse(response) {
|
|
2855
|
+
return providerResponseIdentity(response.id, state.selectedModel?.resolveResponseProvider?.({
|
|
2856
|
+
providerMetadata: response.providerMetadata
|
|
2857
|
+
}));
|
|
2858
|
+
}
|
|
2859
|
+
};
|
|
2860
|
+
}
|
|
2204
2861
|
const requestModelId = input.selectedModel.descriptor.modelId;
|
|
2205
2862
|
const knownMessageShas = new Set;
|
|
2206
2863
|
{
|
|
@@ -2226,7 +2883,7 @@ async function createRunProviderLedger(input) {
|
|
|
2226
2883
|
const messageShas = [];
|
|
2227
2884
|
for (const message of request.messages) {
|
|
2228
2885
|
const body = canonicalAgentJson(JSON.parse(JSON.stringify(withoutBinaryParts(message))));
|
|
2229
|
-
const sha256 =
|
|
2886
|
+
const sha256 = createHash3("sha256").update(body).digest("hex");
|
|
2230
2887
|
messageShas.push(sha256);
|
|
2231
2888
|
if (knownMessageShas.has(sha256))
|
|
2232
2889
|
continue;
|
|
@@ -2237,8 +2894,8 @@ async function createRunProviderLedger(input) {
|
|
|
2237
2894
|
});
|
|
2238
2895
|
knownMessageShas.add(sha256);
|
|
2239
2896
|
}
|
|
2240
|
-
const instructionsSha256 =
|
|
2241
|
-
const bodySha256 =
|
|
2897
|
+
const instructionsSha256 = createHash3("sha256").update(typeof request.instructions === "string" ? request.instructions : canonicalAgentJson(JSON.parse(JSON.stringify(withoutBinaryParts(request.instructions))))).digest("hex");
|
|
2898
|
+
const bodySha256 = createHash3("sha256").update(instructionsSha256).update(messageShas.join(",")).digest("hex");
|
|
2242
2899
|
await store.appendEvent({
|
|
2243
2900
|
conversationId: state.run.conversationId,
|
|
2244
2901
|
kind: "provider/request",
|
|
@@ -2637,7 +3294,7 @@ async function prepareAttemptStep(context, attempt, options) {
|
|
|
2637
3294
|
messages: [...prepared?.messages ?? options.messages, ...injected]
|
|
2638
3295
|
};
|
|
2639
3296
|
const providerMessages = preparedStep?.messages ?? options.messages;
|
|
2640
|
-
const model = await execution.operationLifecycle.prepareModel(preparedStep?.model ?? turn.selectedModel.model, options.stepNumber, generateId());
|
|
3297
|
+
const model = await execution.operationLifecycle.prepareModel(execution.invocation ? execution.invocation.wrap(turn.selectedModel, options.stepNumber, preparedStep?.model) : preparedStep?.model ?? turn.selectedModel.model, options.stepNumber, generateId());
|
|
2641
3298
|
const override = preparedStep;
|
|
2642
3299
|
if (override?.instructions !== undefined)
|
|
2643
3300
|
loop.instructionsOverride = override.instructions;
|
|
@@ -2825,7 +3482,8 @@ async function runModelAttempts(execution, turn) {
|
|
|
2825
3482
|
const ledger = await createRunProviderLedger({
|
|
2826
3483
|
store: config.store,
|
|
2827
3484
|
state,
|
|
2828
|
-
selectedModel: turn.selectedModel
|
|
3485
|
+
selectedModel: turn.selectedModel,
|
|
3486
|
+
audited: execution.invocation !== undefined
|
|
2829
3487
|
});
|
|
2830
3488
|
const context = { execution, turn, loop, ledger };
|
|
2831
3489
|
for (;; ) {
|
|
@@ -3008,7 +3666,7 @@ async function commitRunTerminal(execution) {
|
|
|
3008
3666
|
}
|
|
3009
3667
|
|
|
3010
3668
|
// src/agent-runtime/run-prompt-history.ts
|
|
3011
|
-
import { createHash as
|
|
3669
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
3012
3670
|
function snapshotForRunPrompt(snapshot, runId) {
|
|
3013
3671
|
const runIndex = snapshot.runs.findIndex((candidate) => candidate.id === runId);
|
|
3014
3672
|
if (runIndex < 0)
|
|
@@ -3027,7 +3685,7 @@ var USER_INSTRUCTION_SEED_KEY = "prompt.user-instructions";
|
|
|
3027
3685
|
function seededInstructionMessage(input) {
|
|
3028
3686
|
return AgentMessageSchema.parse({
|
|
3029
3687
|
schemaVersion: 1,
|
|
3030
|
-
id:
|
|
3688
|
+
id: createHash4("sha256").update(`${input.conversationId}\x00${input.seedKey}\x00${input.index}`).digest("hex"),
|
|
3031
3689
|
conversationId: input.conversationId,
|
|
3032
3690
|
role: "user",
|
|
3033
3691
|
status: "committed",
|
|
@@ -3250,6 +3908,15 @@ function createRunExecutor(dependencies) {
|
|
|
3250
3908
|
return acquisition.result;
|
|
3251
3909
|
const { execution } = acquisition;
|
|
3252
3910
|
try {
|
|
3911
|
+
const invocations = dependencies.config.invocations;
|
|
3912
|
+
if (invocations) {
|
|
3913
|
+
const trace = await invocations.trace({
|
|
3914
|
+
context: input.context,
|
|
3915
|
+
conversationId: execution.state.run.conversationId,
|
|
3916
|
+
run: execution.state.run
|
|
3917
|
+
});
|
|
3918
|
+
execution.invocation = await beginAgentInvocation(invocations.ledger, dependencies.config.store, { run: execution.state.run, trace }, input.context);
|
|
3919
|
+
}
|
|
3253
3920
|
const turn = await prepareTurn(execution);
|
|
3254
3921
|
await runModelAttempts(execution, turn);
|
|
3255
3922
|
await settleStreamOutcome(execution);
|
|
@@ -3258,7 +3925,9 @@ function createRunExecutor(dependencies) {
|
|
|
3258
3925
|
} finally {
|
|
3259
3926
|
execution.idleDeadline.dispose();
|
|
3260
3927
|
}
|
|
3261
|
-
|
|
3928
|
+
const result = await commitRunTerminal(execution);
|
|
3929
|
+
await execution.invocation?.finish(result.reason === "success" ? "succeeded" : ["interrupted", "cancelled", "timeout", "shutdown"].includes(result.reason) ? "cancelled" : "failed");
|
|
3930
|
+
return result;
|
|
3262
3931
|
};
|
|
3263
3932
|
}
|
|
3264
3933
|
|
|
@@ -3641,4 +4310,4 @@ function createAgentRuntime(config) {
|
|
|
3641
4310
|
};
|
|
3642
4311
|
}
|
|
3643
4312
|
|
|
3644
|
-
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 };
|
|
4313
|
+
export { AgentRuntimeConflictError, normalizeSdkUsage, AgentContextOverflowError, createAgentSessionCoordinator, registerDeferredToolRepair, registerDeferredToolCatalog, deferredToolCatalog, repairedSearchCall, createAgentRuntimeEventSink, projectAgentHistoryDetailed, projectAgentHistory, ModelInvocationTraceSchema, CompletionInvocationInputSchema, ModelInvocationRecordSchema, currentModelInvocationAttempt, createModelInvocationLedger, createAgentToolFenceLifecycle, AgentTokenCountSchema, selectAgentHistory, composeAgentPrompt, AgentProviderStreamCutError, classifyProviderFailure, isToolResultFailure, recordAgentRetryDecision, defineStateSlot, createAgentStateSlotStore, renderAgentStateSlots, agentGoalStateSlot, agentTodoStateSlot, createAgentRuntime };
|