effect-agent 0.1.0-beta.160 → 0.1.0-beta.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DurableAgentRuntime-pr7cCaZw.mjs → DurableAgentRuntime-BpB5rBcu.mjs} +41 -35
- package/dist/DurableAgentRuntime-BpB5rBcu.mjs.map +1 -0
- package/dist/durable/DurableAgentRuntime.mjs +1 -1
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +38 -38
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/durable/DurableAgentRuntime.ts +63 -50
- package/src/durable/internal/journal-checkpoint.ts +8 -7
- package/dist/DurableAgentRuntime-pr7cCaZw.mjs.map +0 -1
|
@@ -90,15 +90,16 @@ var RecoveryCheckpointContents = class extends Schema.Class("@effect-agent/threa
|
|
|
90
90
|
state: RecoveryCheckpointState,
|
|
91
91
|
digest: Digest
|
|
92
92
|
}) {};
|
|
93
|
-
const RECOVERY_ENGINE_VERSION = "effect-agent/recovery@
|
|
93
|
+
const RECOVERY_ENGINE_VERSION = "effect-agent/recovery@4";
|
|
94
94
|
/**
|
|
95
95
|
* Prove that indexed original-input absence also means absent prefix Run/control evidence.
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
96
|
+
* A certificate covers only Run IDs with the given length. Every possible control marker for
|
|
97
|
+
* those IDs is exactly :<run-id>:, including markers nested inside opaque IDs. Cache consumers
|
|
98
|
+
* must have the checkpoint owner's ID length; shorter/longer aliases require full replay.
|
|
99
|
+
* Parsing here can only decline caching; it never supplies an execution identity.
|
|
99
100
|
* The temporary anchor set is discarded after certification, not persisted with the context.
|
|
100
101
|
*/
|
|
101
|
-
const makeThreadContextCertificate = () => {
|
|
102
|
+
const makeThreadContextCertificate = (runIdLength) => {
|
|
102
103
|
const anchored = /* @__PURE__ */ new Set();
|
|
103
104
|
let valid = true;
|
|
104
105
|
return {
|
|
@@ -114,8 +115,8 @@ const makeThreadContextCertificate = () => {
|
|
|
114
115
|
if (originalInput) anchored.add(payload.runId);
|
|
115
116
|
}
|
|
116
117
|
for (let start = record.recordId.indexOf(":run:"); start !== -1; start = record.recordId.indexOf(":run:", start + 1)) {
|
|
117
|
-
const end =
|
|
118
|
-
if (end
|
|
118
|
+
const end = start + 1 + runIdLength;
|
|
119
|
+
if (record.recordId[end] === ":" && !anchored.has(record.recordId.slice(start + 1, end))) {
|
|
119
120
|
valid = false;
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
@@ -2547,7 +2548,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2547
2548
|
})).pipe(Effect.catchTag("CheckpointRejected", () => Effect.succeed(Option.none())));
|
|
2548
2549
|
if (Option.isNone(loaded)) return Option.none();
|
|
2549
2550
|
const checkpoint = loaded.value;
|
|
2550
|
-
if (checkpoint.engineVersion !== "effect-agent/recovery@
|
|
2551
|
+
if (checkpoint.engineVersion !== "effect-agent/recovery@4" || checkpoint.threadId !== threadId || checkpoint.throughSequence > throughSequence) return Option.none();
|
|
2551
2552
|
const decoded = yield* Schema.decodeUnknownEffect(RecoveryCheckpointContents)(checkpoint.state).pipe(Effect.option);
|
|
2552
2553
|
if (Option.isNone(decoded)) return Option.none();
|
|
2553
2554
|
const { state, digest } = decoded.value;
|
|
@@ -2581,7 +2582,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2581
2582
|
/** Late/foreign evidence and new compactions require the original canonical proof. */
|
|
2582
2583
|
const contextSuffixCompatible = (records, submissionId) => {
|
|
2583
2584
|
const runId = runIdForSubmission(submissionId);
|
|
2584
|
-
const certificate = makeThreadContextCertificate();
|
|
2585
|
+
const certificate = makeThreadContextCertificate(runId.length);
|
|
2585
2586
|
for (const entry of records) {
|
|
2586
2587
|
const { payload, recordId } = entry.record;
|
|
2587
2588
|
if (payload._tag === "CompactionCreated" || retainThreadIdentity(entry)) return false;
|
|
@@ -2604,7 +2605,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2604
2605
|
const { checkpoint, state } = loaded.value;
|
|
2605
2606
|
if (throughSequence - checkpoint.throughSequence > 4096) return full;
|
|
2606
2607
|
const submissionId = submissionIds.length === 1 ? submissionIds[0] : void 0;
|
|
2607
|
-
if (state.context !== void 0 && submissionId !== void 0 &&
|
|
2608
|
+
if (state.context !== void 0 && submissionId !== void 0 && submissionId.length === state.submissionId.length && (journalOwner === void 0 || journalOwner === runIdForSubmission(submissionId))) {
|
|
2608
2609
|
const runId = runIdForSubmission(submissionId);
|
|
2609
2610
|
if ([yield* getRunInput({
|
|
2610
2611
|
threadId,
|
|
@@ -2636,16 +2637,17 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2636
2637
|
seed: state.seed
|
|
2637
2638
|
};
|
|
2638
2639
|
});
|
|
2639
|
-
const
|
|
2640
|
-
if (store.recoveryCheckpoints === void 0) return;
|
|
2640
|
+
const encodeRecoveryCheckpoint = Effect.fnUntraced(function* (state) {
|
|
2641
2641
|
const encoded = yield* Schema.encodeEffect(RecoveryCheckpointState)(state).pipe(Effect.option);
|
|
2642
|
-
if (Option.isNone(encoded)) return;
|
|
2642
|
+
if (Option.isNone(encoded)) return Option.none();
|
|
2643
2643
|
const digest = yield* withCrypto(digestJson(encoded.value));
|
|
2644
|
-
|
|
2644
|
+
return yield* Schema.encodeEffect(Schema.fromJsonString(RecoveryCheckpointContents))(RecoveryCheckpointContents.make({
|
|
2645
2645
|
state,
|
|
2646
2646
|
digest
|
|
2647
2647
|
})).pipe(Effect.flatMap(Schema.decodeUnknownEffect(Schema.fromJsonString(PersistedJson))), Effect.option);
|
|
2648
|
-
|
|
2648
|
+
});
|
|
2649
|
+
const persistRecoveryCheckpoint = Effect.fn("DurableAgentRuntime.persistRecoveryCheckpoint")(function* (ctx, submission, contents, tail, createdAt) {
|
|
2650
|
+
if (store.recoveryCheckpoints === void 0) return;
|
|
2649
2651
|
const checkpoint = ThreadCheckpoint.make({
|
|
2650
2652
|
schemaVersion: 1,
|
|
2651
2653
|
threadId: ctx.threadId,
|
|
@@ -2655,7 +2657,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2655
2657
|
agentDefinitionDigest: submission.agentDigests.agent,
|
|
2656
2658
|
modelDigest: submission.agentDigests.model,
|
|
2657
2659
|
toolDigest: submission.agentDigests.tools,
|
|
2658
|
-
state: contents
|
|
2660
|
+
state: contents,
|
|
2659
2661
|
createdAt
|
|
2660
2662
|
});
|
|
2661
2663
|
yield* hit("checkpoint:before-save");
|
|
@@ -2680,7 +2682,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2680
2682
|
}
|
|
2681
2683
|
if (projection === void 0) {
|
|
2682
2684
|
const source = canonicalRange(ctx.threadId, tail.sequence);
|
|
2683
|
-
const certificate = makeThreadContextCertificate();
|
|
2685
|
+
const certificate = makeThreadContextCertificate(runIdForSubmission(submission.submissionId).length);
|
|
2684
2686
|
const metadata = makeJournalMetadata(void 0);
|
|
2685
2687
|
const retained = [];
|
|
2686
2688
|
yield* Stream.runForEach(source, (entry) => Effect.sync(() => {
|
|
@@ -2695,30 +2697,32 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
2695
2697
|
if (projection === void 0) return;
|
|
2696
2698
|
const prompt = yield* Schema.encodeEffect(Prompt.Prompt)(projection.prompt).pipe(Effect.flatMap(decodePersisted), Effect.option);
|
|
2697
2699
|
if (Option.isNone(prompt)) return;
|
|
2698
|
-
|
|
2699
|
-
let records = identities;
|
|
2700
|
-
let submissionIds = [submission.submissionId];
|
|
2701
|
-
if (previous.state.submissionId === submission.submissionId && previous.state.seed !== void 0 && tail.sequence - previous.checkpoint.throughSequence + previous.state.records.length <= 4096) {
|
|
2702
|
-
const suffix = yield* Stream.runCollect(canonicalRange(ctx.threadId, tail.sequence, previous.checkpoint.throughSequence));
|
|
2703
|
-
if (checkpointSuffixCompatible(previous.state.seed, suffix, previous.state.records)) {
|
|
2704
|
-
seed = previous.state.seed;
|
|
2705
|
-
records = [...previous.state.records, ...suffix];
|
|
2706
|
-
submissionIds = previous.state.submissionIds;
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
yield* persistRecoveryCheckpoint(ctx, submission, RecoveryCheckpointState.make({
|
|
2700
|
+
const contextState = RecoveryCheckpointState.make({
|
|
2710
2701
|
schemaVersion: 2,
|
|
2711
2702
|
policyAccountingVersion: 1,
|
|
2712
2703
|
submissionId: submission.submissionId,
|
|
2713
|
-
submissionIds,
|
|
2714
|
-
...seed === void 0 ? {} : { seed },
|
|
2704
|
+
submissionIds: [submission.submissionId],
|
|
2715
2705
|
context: ThreadContextCheckpoint.make({
|
|
2716
2706
|
throughSequence: tail.sequence,
|
|
2717
2707
|
prompt: prompt.value,
|
|
2718
2708
|
...projection.contextWindowId === void 0 ? {} : { contextWindowId: projection.contextWindowId }
|
|
2719
2709
|
}),
|
|
2720
|
-
records
|
|
2721
|
-
})
|
|
2710
|
+
records: identities
|
|
2711
|
+
});
|
|
2712
|
+
let state = contextState;
|
|
2713
|
+
if (previous.state.submissionId === submission.submissionId && previous.state.seed !== void 0 && tail.sequence - previous.checkpoint.throughSequence + previous.state.records.length <= 4096) {
|
|
2714
|
+
const suffix = yield* Stream.runCollect(canonicalRange(ctx.threadId, tail.sequence, previous.checkpoint.throughSequence));
|
|
2715
|
+
if (checkpointSuffixCompatible(previous.state.seed, suffix, previous.state.records)) state = RecoveryCheckpointState.make({
|
|
2716
|
+
...contextState,
|
|
2717
|
+
seed: previous.state.seed,
|
|
2718
|
+
records: [...previous.state.records, ...suffix],
|
|
2719
|
+
submissionIds: previous.state.submissionIds
|
|
2720
|
+
});
|
|
2721
|
+
}
|
|
2722
|
+
let contents = yield* encodeRecoveryCheckpoint(state);
|
|
2723
|
+
if (Option.isNone(contents) && state.seed !== void 0) contents = yield* encodeRecoveryCheckpoint(contextState);
|
|
2724
|
+
if (Option.isNone(contents)) return;
|
|
2725
|
+
yield* persistRecoveryCheckpoint(ctx, submission, contents.value, tail, yield* DateTime.now);
|
|
2722
2726
|
});
|
|
2723
2727
|
const readAllTolerant = Effect.fn("DurableAgentRuntime.readAllTolerant")((threadId, submissionIds) => readControl(threadId, submissionIds).pipe(Effect.map((records) => ({
|
|
2724
2728
|
records,
|
|
@@ -4451,7 +4455,9 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (bindings) {
|
|
|
4451
4455
|
].some((field) => current.usage[field] !== candidate.usage[field]) || (current.usage.unobservedModelCalls ?? 0) !== (candidate.usage.unobservedModelCalls ?? 0)) return;
|
|
4452
4456
|
const summaries = yield* Effect.forEach([current, candidate], (projection) => summarizeModelUsage(projection.usage.modelUsage, projection.usage.summarizedModelUsage)).pipe(Effect.option);
|
|
4453
4457
|
if (Option.isNone(summaries) || summaries.value[0] === void 0 || summaries.value[1] === void 0 || !Schema.toEquivalence(RunUsageSummary)(summaries.value[0], summaries.value[1])) return;
|
|
4454
|
-
yield*
|
|
4458
|
+
const contents = yield* encodeRecoveryCheckpoint(validated.value);
|
|
4459
|
+
if (Option.isNone(contents)) return;
|
|
4460
|
+
yield* persistRecoveryCheckpoint(ctx, submission, contents.value, tail, replacement.record.createdAt);
|
|
4455
4461
|
});
|
|
4456
4462
|
const childLineage = records.find(({ record }) => record.recordId === subagentLineageRecordId(submission.threadId))?.record.payload;
|
|
4457
4463
|
const inheritedGrant = submission.workerAdmission?.origin.grant ?? (childLineage?._tag === "SubagentLineageRecorded" ? childLineage.grant : void 0);
|
|
@@ -7504,4 +7510,4 @@ var DurableAgentRuntime = class DurableAgentRuntime extends Context.Service()("@
|
|
|
7504
7510
|
//#endregion
|
|
7505
7511
|
export { DurableApprovalSuspension as a, RecoveryFailure as c, childReservationIdFor as d, isolateRecovery as f, DurableApprovalResolver as i, RecoveryReport as l, recoveryRepairRecordId as m, DurableAgentRuntime as n, DurableRuntimeConfig as o, recoveryRepairBatchId as p, DurableAgentRuntime_exports as r, RecoveryBlocked as s, ApprovalSuspensionError as t, RecoverySweepResult as u };
|
|
7506
7512
|
|
|
7507
|
-
//# sourceMappingURL=DurableAgentRuntime-
|
|
7513
|
+
//# sourceMappingURL=DurableAgentRuntime-BpB5rBcu.mjs.map
|