@yielded/agent 0.1.0-beta.172 → 0.1.0-beta.174
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/{Admin-BX9ns28E.d.mts → Admin-BHmp2V9p.d.mts} +25 -16
- package/dist/{Agent-9aBoIi74.d.mts → Agent-B39jRnFv.d.mts} +2 -2
- package/dist/{Agent-0WvBWWbM.mjs → Agent-BiRbr73L.mjs} +7 -6
- package/dist/Agent-BiRbr73L.mjs.map +1 -0
- package/dist/{AgentRuntime-CQ-qcETl.mjs → AgentRuntime-B6qZlD3f.mjs} +199 -191
- package/dist/AgentRuntime-B6qZlD3f.mjs.map +1 -0
- package/dist/{AgentRuntime-BfP14534.d.mts → AgentRuntime-BD3ZHAMq.d.mts} +10 -10
- package/dist/{Digest-DCuPlhNk.mjs → Digest-EpeqWEdv.mjs} +41 -14
- package/dist/Digest-EpeqWEdv.mjs.map +1 -0
- package/dist/{DurableAgentRuntime-BAmSkWYr.mjs → DurableAgentRuntime-CBBjRNJN.mjs} +1447 -1424
- package/dist/DurableAgentRuntime-CBBjRNJN.mjs.map +1 -0
- package/dist/{EventSource-BwliwQz9.d.mts → EventSource-C9aaJaXT.d.mts} +2 -2
- package/dist/{MessageDelivery-CeSDfHZa.d.mts → MessageDelivery-BGDm-c46.d.mts} +4 -4
- package/dist/{Messaging-C_6OOg_s.d.mts → Messaging-SVu6rWV8.d.mts} +12 -6
- package/dist/{MessagingHost-B8oKM7AC.d.mts → MessagingHost-C6SOAcoG.d.mts} +2 -2
- package/dist/{Output-Dsx6k52t.d.mts → Output-CRamN1Fy.d.mts} +2 -2
- package/dist/{PreparedInputAdmission-CxSJSiTl.d.mts → PreparedInputAdmission-BvDqlgiP.d.mts} +3 -3
- package/dist/{RunContinuation-DHYNAQFi.mjs → RunContinuation-4ZATcVLB.mjs} +113 -56
- package/dist/RunContinuation-4ZATcVLB.mjs.map +1 -0
- package/dist/{RunContinuation-FHM7XPjq.d.mts → RunContinuation-CTJ1jGrO.d.mts} +6 -6
- package/dist/{RunJournal-kfKVxJj7.mjs → RunJournal-CNZqA3Ge.mjs} +33 -5
- package/dist/RunJournal-CNZqA3Ge.mjs.map +1 -0
- package/dist/{RunOptions-D8zxFIrZ.d.mts → RunOptions-Be77lKVZ.d.mts} +2 -2
- package/dist/{RunStorage-uqPxps09.mjs → RunStorage-BHjuuERI.mjs} +9 -6
- package/dist/RunStorage-BHjuuERI.mjs.map +1 -0
- package/dist/{Scheduling-CVyfXlBR.mjs → Scheduling-NG8slKdI.mjs} +11 -11
- package/dist/Scheduling-NG8slKdI.mjs.map +1 -0
- package/dist/{Subagent-vpffemql.mjs → Subagent-CTIpnzlB.mjs} +53 -40
- package/dist/Subagent-CTIpnzlB.mjs.map +1 -0
- package/dist/{Subagent-E6tvd7-k.d.mts → Subagent-DKhZA72u.d.mts} +19 -8
- package/dist/{SubagentHost-B6w2m-SI.d.mts → SubagentHost-D1xBgn9g.d.mts} +2 -2
- package/dist/{Subscription-DONig54Q.d.mts → Subscription-BNg9VCRl.d.mts} +2 -2
- package/dist/{SubscriptionInput-mJIRxWJM.d.mts → SubscriptionInput-BUoXv-_K.d.mts} +2 -2
- package/dist/{ThreadImport-CoQTZywm.d.mts → ThreadImport-CMgzttvr.d.mts} +43 -43
- package/dist/{ThreadImport-DckUMEqJ.mjs → ThreadImport-CodYoJoa.mjs} +7 -7
- package/dist/ThreadImport-CodYoJoa.mjs.map +1 -0
- package/dist/{ThreadStore-CEekRa80.mjs → ThreadStore-59uDGXul.mjs} +163 -84
- package/dist/ThreadStore-59uDGXul.mjs.map +1 -0
- package/dist/{ThreadTransfer-B4gTQLIl.mjs → ThreadTransfer-3jigUl3g.mjs} +3 -3
- package/dist/{ThreadTransfer-B4gTQLIl.mjs.map → ThreadTransfer-3jigUl3g.mjs.map} +1 -1
- package/dist/{WorkerAdmission-DFVbbVh2.mjs → WorkerAdmission-DDYJdOsU.mjs} +4 -4
- package/dist/{WorkerAdmission-DFVbbVh2.mjs.map → WorkerAdmission-DDYJdOsU.mjs.map} +1 -1
- package/dist/{agent-registration-ByMZ_cK5.mjs → agent-registration-DRbyhAu-.mjs} +69 -56
- package/dist/agent-registration-DRbyhAu-.mjs.map +1 -0
- package/dist/capabilities/Approval.mjs +2 -2
- package/dist/capabilities/Approval.mjs.map +1 -1
- package/dist/capabilities/BrowserUse.d.mts +102 -1867
- package/dist/capabilities/BrowserUse.mjs +74 -798
- package/dist/capabilities/BrowserUse.mjs.map +1 -1
- package/dist/capabilities/Budget.mjs +3 -1
- package/dist/capabilities/Budget.mjs.map +1 -1
- package/dist/capabilities/CodeMode.d.mts +1 -1
- package/dist/capabilities/CodeMode.mjs +16 -9
- package/dist/capabilities/CodeMode.mjs.map +1 -1
- package/dist/capabilities/Commands.d.mts +1 -1
- package/dist/capabilities/McpClient.mjs +1 -1
- package/dist/capabilities/McpClient.mjs.map +1 -1
- package/dist/capabilities/Messaging.d.mts +1 -1
- package/dist/capabilities/Messaging.mjs +4 -4
- package/dist/capabilities/Messaging.mjs.map +1 -1
- package/dist/capabilities/ModelContext.mjs +7 -5
- package/dist/capabilities/ModelContext.mjs.map +1 -1
- package/dist/capabilities/Redaction.mjs +49 -19
- package/dist/capabilities/Redaction.mjs.map +1 -1
- package/dist/capabilities/RunHooks.d.mts +1 -1
- package/dist/capabilities/RunHooks.mjs +1 -1
- package/dist/capabilities/RunHooks.mjs.map +1 -1
- package/dist/capabilities/Subagent.d.mts +1 -1
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/capabilities/SubagentReservations.mjs +3 -1
- package/dist/capabilities/SubagentReservations.mjs.map +1 -1
- package/dist/capabilities/WebCapture.mjs.map +1 -1
- package/dist/capabilities/WebSearch.mjs +7 -7
- package/dist/capabilities/WebSearch.mjs.map +1 -1
- package/dist/core/Agent.d.mts +1 -1
- package/dist/core/Agent.mjs +1 -1
- package/dist/core/AgentUpdates.mjs +8 -8
- package/dist/core/AgentUpdates.mjs.map +1 -1
- package/dist/core/Thread.mjs +1 -1
- package/dist/core/Thread.mjs.map +1 -1
- package/dist/core/Usage.mjs +2 -2
- package/dist/core/Usage.mjs.map +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/AgentRegistration.d.mts +1 -1
- package/dist/durable/AgentRegistration.mjs +1 -1
- package/dist/durable/Certification.d.mts +1 -1
- package/dist/durable/CommittedActivity.d.mts +1 -1
- package/dist/durable/CommittedActivity.mjs +2 -2
- package/dist/durable/Digest.mjs +1 -1
- package/dist/durable/DurableAgentRuntime.d.mts +1 -1
- package/dist/durable/DurableAgentRuntime.mjs +2 -2
- package/dist/durable/EventSource.d.mts +1 -1
- package/dist/durable/EventSource.mjs +6 -6
- package/dist/durable/EventSource.mjs.map +1 -1
- package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
- package/dist/durable/LifecyclePublication.d.mts +1 -1
- package/dist/durable/LifecyclePublication.mjs +1 -1
- package/dist/durable/MessageDelivery.d.mts +1 -1
- package/dist/durable/MessageDelivery.mjs +1 -1
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +2 -2
- package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
- package/dist/durable/PersistentHistory.d.mts +1 -1
- package/dist/durable/PersistentHistory.mjs +3 -3
- package/dist/durable/PreparedInputAdmission.d.mts +1 -1
- package/dist/durable/RecordFormat.mjs +2 -2
- package/dist/durable/RecordFormat.mjs.map +1 -1
- package/dist/durable/Recovery.d.mts +1 -1
- package/dist/durable/RunContinuation.d.mts +2 -2
- package/dist/durable/RunContinuation.mjs +2 -2
- package/dist/durable/RunJournal.d.mts +1 -1
- package/dist/durable/RunJournal.mjs +1 -1
- package/dist/durable/RunStorage.d.mts +1 -1
- package/dist/durable/RunStorage.mjs +1 -1
- package/dist/durable/Scheduling.d.mts +1 -1
- package/dist/durable/Scheduling.mjs +1 -1
- package/dist/durable/SettlementPublisher.d.mts +1 -1
- package/dist/durable/SettlementPublisher.mjs +2 -2
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedger.mjs +5 -1
- package/dist/durable/SubmissionLedger.mjs.map +1 -1
- package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.mjs +4 -4
- package/dist/durable/SubmissionStatus.d.mts +1 -1
- package/dist/durable/Subscription.d.mts +1 -1
- package/dist/durable/SubscriptionInput.d.mts +1 -1
- package/dist/durable/SubscriptionInput.mjs +3 -3
- package/dist/durable/SubscriptionInput.mjs.map +1 -1
- package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
- package/dist/durable/SubscriptionStoreConformance.mjs +2 -2
- package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -1
- package/dist/durable/SubscriptionTools.d.mts +2 -2
- package/dist/durable/SubscriptionTransition.d.mts +1 -1
- package/dist/durable/Subscriptions.d.mts +5 -5
- package/dist/durable/Subscriptions.mjs +2 -2
- package/dist/durable/Subscriptions.mjs.map +1 -1
- package/dist/durable/ThreadArchiveRange.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.mjs +1 -1
- package/dist/durable/ThreadImport.d.mts +1 -1
- package/dist/durable/ThreadImport.mjs +1 -1
- package/dist/durable/ThreadInvariants.d.mts +3 -3
- package/dist/durable/ThreadInvariants.mjs +4 -4
- package/dist/durable/ThreadInvariants.mjs.map +1 -1
- package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
- package/dist/durable/ThreadReader.d.mts +1 -1
- package/dist/durable/ThreadReader.mjs +1 -1
- package/dist/durable/ThreadStore.d.mts +1 -1
- package/dist/durable/ThreadStore.mjs +1 -1
- package/dist/durable/ThreadStoreConformance.d.mts +1 -1
- package/dist/durable/ThreadStoreConformance.mjs +3 -3
- package/dist/durable/ThreadTransfer.d.mts +1 -1
- package/dist/durable/ThreadTransfer.mjs +1 -1
- package/dist/durable/ThreadWork.d.mts +1 -1
- package/dist/durable/ThreadWork.mjs +4 -4
- package/dist/durable/ThreadWork.mjs.map +1 -1
- package/dist/durable/WorkerAdmission.d.mts +1 -1
- package/dist/durable/WorkerAdmission.mjs +1 -1
- package/dist/durable/WorkerHost.d.mts +2 -2
- package/dist/engine/AgentRuntime.d.mts +1 -1
- package/dist/engine/AgentRuntime.mjs +1 -1
- package/dist/engine/MessagingHost.d.mts +1 -1
- package/dist/engine/Output.d.mts +1 -1
- package/dist/engine/RunOptions.d.mts +1 -1
- package/dist/engine/SubagentHost.d.mts +1 -1
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +14 -14
- package/dist/{run-context-reader-OcsZr4bk.d.mts → run-context-reader-CC7ZD95F.d.mts} +2 -2
- package/package.json +1 -1
- package/src/capabilities/Approval.ts +58 -60
- package/src/capabilities/BrowserUse.ts +89 -944
- package/src/capabilities/Budget.ts +8 -1
- package/src/capabilities/CodeMode.ts +57 -33
- package/src/capabilities/McpClient.ts +2 -2
- package/src/capabilities/Messaging.ts +51 -55
- package/src/capabilities/ModelContext.ts +5 -2
- package/src/capabilities/Redaction.ts +64 -34
- package/src/capabilities/RunHooks.ts +52 -55
- package/src/capabilities/Subagent.ts +33 -33
- package/src/capabilities/SubagentReservations.ts +9 -1
- package/src/capabilities/WebCapture.ts +6 -0
- package/src/capabilities/WebSearch.ts +10 -7
- package/src/capabilities/internal/subagent-background.ts +202 -158
- package/src/core/Agent.ts +11 -6
- package/src/core/AgentUpdates.ts +8 -8
- package/src/core/Thread.ts +9 -10
- package/src/core/Usage.ts +7 -8
- package/src/core/internal/agent-updates.ts +1 -0
- package/src/durable/DurableAgentRuntime.ts +645 -625
- package/src/durable/EventSource.ts +15 -9
- package/src/durable/RecordFormat.ts +5 -3
- package/src/durable/RunContinuation.ts +233 -81
- package/src/durable/RunJournal.ts +10 -9
- package/src/durable/RunStorage.ts +122 -124
- package/src/durable/Scheduling.ts +639 -651
- package/src/durable/SubmissionLedger.ts +4 -0
- package/src/durable/SubscriptionInput.ts +5 -3
- package/src/durable/SubscriptionStoreConformance.ts +23 -23
- package/src/durable/Subscriptions.ts +18 -19
- package/src/durable/ThreadImport.ts +18 -19
- package/src/durable/ThreadInvariants.ts +2 -1
- package/src/durable/ThreadStore.ts +215 -111
- package/src/durable/ThreadWork.ts +1 -2
- package/src/durable/internal/StorageOwner.ts +10 -4
- package/src/durable/internal/agent-registration.ts +96 -89
- package/src/durable/internal/canonical-json.ts +61 -20
- package/src/durable/internal/prompt-history-cache.ts +13 -4
- package/src/durable/internal/record-encoding.ts +120 -64
- package/src/durable/internal/schedule-time.ts +6 -6
- package/src/durable/internal/usage-totals.ts +38 -0
- package/src/durable/internal/worker-host.ts +69 -74
- package/src/engine/internal/agent-runtime.ts +1067 -1018
- package/src/engine/internal/provisional-text.ts +12 -10
- package/src/engine/internal/tool-exposure.ts +22 -18
- package/src/engine/internal/tool-telemetry.ts +12 -7
- package/dist/Agent-0WvBWWbM.mjs.map +0 -1
- package/dist/AgentRuntime-CQ-qcETl.mjs.map +0 -1
- package/dist/Digest-DCuPlhNk.mjs.map +0 -1
- package/dist/DurableAgentRuntime-BAmSkWYr.mjs.map +0 -1
- package/dist/RunContinuation-DHYNAQFi.mjs.map +0 -1
- package/dist/RunJournal-kfKVxJj7.mjs.map +0 -1
- package/dist/RunStorage-uqPxps09.mjs.map +0 -1
- package/dist/Scheduling-CVyfXlBR.mjs.map +0 -1
- package/dist/Subagent-vpffemql.mjs.map +0 -1
- package/dist/ThreadImport-DckUMEqJ.mjs.map +0 -1
- package/dist/ThreadStore-CEekRa80.mjs.map +0 -1
- package/dist/agent-registration-ByMZ_cK5.mjs.map +0 -1
|
@@ -228,6 +228,10 @@ export class SubmissionSnapshot extends Schema.Class<SubmissionSnapshot>(
|
|
|
228
228
|
inputPayload: PersistedJson,
|
|
229
229
|
inputDigest: Digest,
|
|
230
230
|
settledOutcome: Schema.optionalKey(SettlementOutcome),
|
|
231
|
+
/** First committed finalization time; paired with settledRecordId by native adapters. */
|
|
232
|
+
settledAt: Schema.optionalKey(Schema.DateTimeUtcFromString),
|
|
233
|
+
/** Exact canonical settlement behind the finalized projection; not a substitute for reading it. */
|
|
234
|
+
settledRecordId: Schema.optionalKey(RecordId),
|
|
231
235
|
createdAt: Schema.DateTimeUtcFromString,
|
|
232
236
|
readyAt: Schema.optionalKey(Schema.DateTimeUtcFromString),
|
|
233
237
|
admissionGroup: Schema.optionalKey(AdmissionGroup),
|
|
@@ -122,8 +122,8 @@ export const makeSubscriptionInputBinding = Effect.fnUntraced(function* <
|
|
|
122
122
|
Effect.scoped,
|
|
123
123
|
Effect.provideContext(services),
|
|
124
124
|
),
|
|
125
|
-
prepare: (
|
|
126
|
-
|
|
125
|
+
prepare: Effect.fnUntraced(
|
|
126
|
+
function* (event, subscription) {
|
|
127
127
|
const e = yield* Schema.decodeEffect(options.event)(event.payload).pipe(
|
|
128
128
|
Effect.mapError(invalid),
|
|
129
129
|
);
|
|
@@ -137,6 +137,8 @@ export const makeSubscriptionInputBinding = Effect.fnUntraced(function* <
|
|
|
137
137
|
).pipe(Effect.mapError(invalid));
|
|
138
138
|
|
|
139
139
|
return yield* encode(options.input, yield* options.prepare(e, p, c));
|
|
140
|
-
}
|
|
140
|
+
},
|
|
141
|
+
(effect) => effect.pipe(Effect.scoped, Effect.provideContext(services)),
|
|
142
|
+
),
|
|
141
143
|
};
|
|
142
144
|
});
|
|
@@ -860,21 +860,20 @@ const lifetimeCapacity = conformanceCase(
|
|
|
860
860
|
);
|
|
861
861
|
}
|
|
862
862
|
|
|
863
|
-
const assertHostGuard = <A>(
|
|
863
|
+
const assertHostGuard = Effect.fnUntraced(function* <A>(
|
|
864
864
|
effect: Effect.Effect<A, SubscriptionStoreFailure>,
|
|
865
865
|
code: string,
|
|
866
|
-
)
|
|
867
|
-
Effect.
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
});
|
|
866
|
+
) {
|
|
867
|
+
const result = yield* Effect.result(effect);
|
|
868
|
+
|
|
869
|
+
yield* ensure(
|
|
870
|
+
Result.isFailure(result) &&
|
|
871
|
+
result.failure._tag === "SubscriptionError" &&
|
|
872
|
+
result.failure.reason === "capacity" &&
|
|
873
|
+
result.failure.code === code,
|
|
874
|
+
`host ${code} guard ignored live work`,
|
|
875
|
+
);
|
|
876
|
+
});
|
|
878
877
|
|
|
879
878
|
const active = yield* store.register(record("host-active"), limits);
|
|
880
879
|
const activeEvent = yield* store.accept(event("host-active"), limits);
|
|
@@ -934,17 +933,18 @@ const capacityReactivation = conformanceCase(
|
|
|
934
933
|
maxDeliveriesPerOwner: 1,
|
|
935
934
|
};
|
|
936
935
|
|
|
937
|
-
const expectCapacity =
|
|
938
|
-
Effect.
|
|
939
|
-
|
|
936
|
+
const expectCapacity = Effect.fnUntraced(function* <A>(
|
|
937
|
+
effect: Effect.Effect<A, SubscriptionStoreFailure>,
|
|
938
|
+
) {
|
|
939
|
+
const result = yield* Effect.result(effect);
|
|
940
940
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
941
|
+
yield* ensure(
|
|
942
|
+
Result.isFailure(result) &&
|
|
943
|
+
result.failure._tag === "SubscriptionError" &&
|
|
944
|
+
result.failure.reason === "capacity",
|
|
945
|
+
"live work did not reserve capacity",
|
|
946
|
+
);
|
|
947
|
+
});
|
|
948
948
|
|
|
949
949
|
const expiring = record("expiring");
|
|
950
950
|
|
|
@@ -584,25 +584,24 @@ const makeManagement = Effect.fnUntraced(function* (requested: SubscriptionLimit
|
|
|
584
584
|
|
|
585
585
|
return Subscriptions.of({
|
|
586
586
|
getSubscription,
|
|
587
|
-
recoverSubscription: (scopeValue, key, expectedRevision)
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
yield*
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}),
|
|
587
|
+
recoverSubscription: Effect.fnUntraced(function* (scopeValue, key, expectedRevision) {
|
|
588
|
+
const owner = yield* scope(scopeValue);
|
|
589
|
+
|
|
590
|
+
yield* authorizer.manage("recover", owner);
|
|
591
|
+
|
|
592
|
+
return snapshot(
|
|
593
|
+
yield* store.change(
|
|
594
|
+
yield* ownedKey(owner, key),
|
|
595
|
+
expectedRevision,
|
|
596
|
+
{
|
|
597
|
+
_tag: "Recover",
|
|
598
|
+
nowMillis: yield* now,
|
|
599
|
+
},
|
|
600
|
+
limits,
|
|
601
|
+
),
|
|
602
|
+
yield* now,
|
|
603
|
+
);
|
|
604
|
+
}),
|
|
606
605
|
recoverDelivery,
|
|
607
606
|
subscribe,
|
|
608
607
|
updateSubscription,
|
|
@@ -701,28 +701,27 @@ export const prepareImportPage = Effect.fnUntraced(function* (
|
|
|
701
701
|
return { archive, records, batches: prepared } satisfies PreparedImportPage;
|
|
702
702
|
});
|
|
703
703
|
|
|
704
|
-
export const finishThreadImport = (state: ThreadImportProgress)
|
|
705
|
-
|
|
706
|
-
const page = state.manifest;
|
|
704
|
+
export const finishThreadImport = Effect.fnUntraced(function* (state: ThreadImportProgress) {
|
|
705
|
+
const page = state.manifest;
|
|
707
706
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
707
|
+
if (
|
|
708
|
+
page === undefined ||
|
|
709
|
+
!state.ended ||
|
|
710
|
+
state.sequence !== page.tailSequence ||
|
|
711
|
+
transferSections.some((section) => state.counts[section] !== page.snapshot[section])
|
|
712
|
+
)
|
|
713
|
+
return yield* invalid(
|
|
714
|
+
"Transfer stream ended before its complete canonical sequence and fact sections",
|
|
715
|
+
);
|
|
717
716
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
});
|
|
717
|
+
return ThreadImportResult.make({
|
|
718
|
+
threadId: page.threadId,
|
|
719
|
+
format: page.format,
|
|
720
|
+
tailSequence: page.tailSequence,
|
|
721
|
+
recordCount: state.sequence,
|
|
722
|
+
submissionCount: state.counts.admissions,
|
|
725
723
|
});
|
|
724
|
+
});
|
|
726
725
|
|
|
727
726
|
/** An executed receipt must settle strictly after its own input. FIFO inputs are checked in one pass. */
|
|
728
727
|
export const verifyImportedInputOrder = Effect.fnUntraced(function* (
|
|
@@ -130,7 +130,8 @@ export const verifyThreadInvariants = Effect.fnUntraced(function* <E, R>(
|
|
|
130
130
|
selected === undefined ||
|
|
131
131
|
selected.sequence !== entry.sequence ||
|
|
132
132
|
selected.batchId !== entry.batchId ||
|
|
133
|
-
recordEncoding(selected.record).json !==
|
|
133
|
+
(yield* Effect.fromResult(recordEncoding(selected.record))).json !==
|
|
134
|
+
(yield* Effect.fromResult(recordEncoding(entry.record))).json
|
|
134
135
|
)
|
|
135
136
|
fail(
|
|
136
137
|
"continuation-evidence",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context, Effect, Layer, Option,
|
|
1
|
+
import { Context, Effect, Layer, Option, Result, Schema, Stream, Struct } from "effect";
|
|
2
2
|
|
|
3
3
|
import { ReceiptId, RunId, SubmissionId, ThreadId, ToolCallId } from "../core/Identifiers.ts";
|
|
4
4
|
import { utf8ByteLength } from "../core/internal/utf8.ts";
|
|
@@ -189,10 +189,10 @@ const selectedRecords = Effect.fnUntraced(function* (
|
|
|
189
189
|
)
|
|
190
190
|
return yield* incomplete("read selection identity");
|
|
191
191
|
afterSequence = entry.sequence;
|
|
192
|
-
bytes += yield* Effect.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
bytes += yield* Effect.fromResult(recordEncoding(entry.record)).pipe(
|
|
193
|
+
Effect.map((record) => record.bytes),
|
|
194
|
+
Effect.mapError(() => incomplete("read selection bytes")),
|
|
195
|
+
);
|
|
196
196
|
if (bytes > MAX_THREAD_EXPORT_PAGE_BYTES)
|
|
197
197
|
return yield* incomplete("read selection byte limit");
|
|
198
198
|
records.push(entry);
|
|
@@ -356,11 +356,101 @@ const validateRecordCount = Schema.decodeUnknownSync(
|
|
|
356
356
|
Schema.Array(Schema.Unknown).check(Schema.isMaxLength(256)),
|
|
357
357
|
);
|
|
358
358
|
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
359
|
+
const validateExecutionHeader = Schema.decodeUnknownSync(
|
|
360
|
+
Schema.Struct({
|
|
361
|
+
previousRevision: ExecutionUpdate.fields.previousRevision,
|
|
362
|
+
retire: ExecutionUpdate.fields.retire,
|
|
363
|
+
checkpoint: Schema.Struct({
|
|
364
|
+
version: ExecutionCheckpoint.fields.version,
|
|
365
|
+
canonicalRecords: ExecutionCheckpoint.fields.canonicalRecords,
|
|
366
|
+
originalSequence: ExecutionCheckpoint.fields.originalSequence,
|
|
367
|
+
throughSequence: ExecutionCheckpoint.fields.throughSequence,
|
|
368
|
+
batchId: ExecutionCheckpoint.fields.batchId,
|
|
369
|
+
}),
|
|
370
|
+
}),
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const validateExecutionRecordCount = Schema.decodeUnknownSync(
|
|
374
|
+
Schema.Array(Schema.Unknown).check(Schema.isMaxLength(8)),
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
/** Capture records once; wrapper fields retain their owning Schema's constraints. */
|
|
378
|
+
const captureExecution = (input: ExecutionUpdate) => {
|
|
379
|
+
const header = validateExecutionHeader(input);
|
|
380
|
+
const operationalInput = input.checkpoint.operational;
|
|
381
|
+
const factsInput = input.facts;
|
|
382
|
+
|
|
383
|
+
const operationalLength = validateExecutionRecordCount(operationalInput).length;
|
|
384
|
+
const factsLength = validateExecutionRecordCount(factsInput).length;
|
|
362
385
|
|
|
363
|
-
const
|
|
386
|
+
const progress = captureRecord(input.checkpoint.progressRecord);
|
|
387
|
+
|
|
388
|
+
if (Result.isFailure(progress)) return Result.fail(progress.failure);
|
|
389
|
+
const progressRecord = progress.success.canonical;
|
|
390
|
+
|
|
391
|
+
if (!isExecutionProgressRecord(progressRecord))
|
|
392
|
+
return Result.fail(
|
|
393
|
+
ThreadStoreError.make({
|
|
394
|
+
operation: "prepare durable commit",
|
|
395
|
+
message: "Expected a Run continuation record",
|
|
396
|
+
}),
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
// Use the Schema-validated indexed lengths, never a caller's iterator. Sparse slots
|
|
400
|
+
// still visit the record boundary, where undefined is refused.
|
|
401
|
+
const operational = [];
|
|
402
|
+
|
|
403
|
+
for (let index = 0; index < operationalLength; index++) {
|
|
404
|
+
const record = captureRecord(operationalInput[index]!);
|
|
405
|
+
|
|
406
|
+
if (Result.isFailure(record)) return Result.fail(record.failure);
|
|
407
|
+
operational.push(record.success);
|
|
408
|
+
}
|
|
409
|
+
const facts = [];
|
|
410
|
+
|
|
411
|
+
for (let index = 0; index < factsLength; index++) {
|
|
412
|
+
const record = captureRecord(factsInput[index]!);
|
|
413
|
+
|
|
414
|
+
if (Result.isFailure(record)) return Result.fail(record.failure);
|
|
415
|
+
facts.push(record.success);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Keep the actual owned arrays within the persisted bounds as well.
|
|
419
|
+
validateExecutionRecordCount(operational);
|
|
420
|
+
validateExecutionRecordCount(facts);
|
|
421
|
+
|
|
422
|
+
const checkpoint = Object.freeze(
|
|
423
|
+
ExecutionCheckpoint.make(
|
|
424
|
+
{
|
|
425
|
+
...header.checkpoint,
|
|
426
|
+
progressRecord,
|
|
427
|
+
operational: Object.freeze(operational.map(({ canonical }) => canonical)),
|
|
428
|
+
},
|
|
429
|
+
{ disableChecks: true },
|
|
430
|
+
),
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
const update = Object.freeze(
|
|
434
|
+
ExecutionUpdate.make(
|
|
435
|
+
{
|
|
436
|
+
previousRevision: header.previousRevision,
|
|
437
|
+
retire: header.retire,
|
|
438
|
+
checkpoint,
|
|
439
|
+
facts: Object.freeze(facts.map(({ canonical }) => canonical)),
|
|
440
|
+
},
|
|
441
|
+
{ disableChecks: true },
|
|
442
|
+
),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
const checkpointJson = `{"version":${checkpoint.version},"progressRecord":${progress.success.json},"operational":[${operational.map(({ json }) => json).join(",")}],"canonicalRecords":${checkpoint.canonicalRecords},"originalSequence":${checkpoint.originalSequence},"throughSequence":${checkpoint.throughSequence},"batchId":${JSON.stringify(checkpoint.batchId)}}`;
|
|
446
|
+
const json = `{"previousRevision":${update.previousRevision},"checkpoint":${checkpointJson},"facts":[${facts.map(({ json }) => json).join(",")}],"retire":${update.retire}}`;
|
|
447
|
+
|
|
448
|
+
return Result.succeed(
|
|
449
|
+
Object.freeze({ update, json, checkpointJson, bytes: utf8ByteLength(json) }),
|
|
450
|
+
);
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const capturedAppends = new WeakMap<AppendRequest, CapturedAppend>();
|
|
364
454
|
|
|
365
455
|
/**
|
|
366
456
|
* Admission reserves one complete batch's envelope, references, snapshot and continuation cursor.
|
|
@@ -418,122 +508,125 @@ export interface PreparedAppend extends AppendRequest {
|
|
|
418
508
|
}>;
|
|
419
509
|
}
|
|
420
510
|
|
|
511
|
+
interface CapturedAppend extends PreparedAppend {
|
|
512
|
+
readonly records: ReadonlyArray<
|
|
513
|
+
Omit<PreparedAppend["records"][number], "wire"> & {
|
|
514
|
+
readonly wire: typeof RecordEnvelope.Encoded;
|
|
515
|
+
}
|
|
516
|
+
>;
|
|
517
|
+
}
|
|
518
|
+
|
|
421
519
|
export const PreparedAppend = {
|
|
422
|
-
capture: (input: AppendRequest): Effect.Effect<
|
|
520
|
+
capture: (input: AppendRequest): Effect.Effect<CapturedAppend, ThreadStoreError> =>
|
|
423
521
|
Effect.suspend(() => {
|
|
424
522
|
const existing = capturedAppends.get(input);
|
|
425
523
|
|
|
426
524
|
if (existing !== undefined) return Effect.succeed(existing);
|
|
427
525
|
|
|
428
526
|
return Effect.try({
|
|
429
|
-
try: () =>
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
validateRecordCount(input.batch.records);
|
|
437
|
-
validateRecordCount(input.executions ?? []);
|
|
438
|
-
|
|
439
|
-
const executionWrites = Object.freeze(
|
|
440
|
-
(input.executions ?? []).map((update) => {
|
|
441
|
-
const json = encodeExecution(update);
|
|
442
|
-
const wire: unknown = JSON.parse(json);
|
|
443
|
-
const decoded = decodeExecution(wire);
|
|
444
|
-
|
|
445
|
-
if (!Predicate.hasProperty(wire, "checkpoint"))
|
|
446
|
-
throw ThreadStoreError.make({
|
|
447
|
-
operation: "prepare durable commit",
|
|
448
|
-
message: "Captured execution has no checkpoint wire",
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
return Object.freeze({
|
|
452
|
-
update: decoded,
|
|
453
|
-
json,
|
|
454
|
-
checkpointJson: JSON.stringify(wire.checkpoint),
|
|
455
|
-
bytes: utf8ByteLength(json),
|
|
456
|
-
});
|
|
457
|
-
}),
|
|
458
|
-
);
|
|
459
|
-
|
|
460
|
-
if (input.batch.records.length === 0 && executionWrites.length === 0)
|
|
461
|
-
throw ThreadStoreError.make({
|
|
462
|
-
operation: "prepare durable commit",
|
|
463
|
-
message: "A commit must contain history facts or an active execution transition",
|
|
464
|
-
});
|
|
465
|
-
if (executionWrites.some(({ bytes }) => !transferPageFits(header.threadId, bytes)))
|
|
466
|
-
throw ThreadStoreError.make({
|
|
467
|
-
operation: "prepare durable commit",
|
|
468
|
-
message: "Active state exceeds its bounded transfer representation",
|
|
469
|
-
});
|
|
470
|
-
// Visit sparse slots too: capture owns each record's validation boundary.
|
|
471
|
-
const encodings = Array.from(input.batch.records, captureRecord);
|
|
472
|
-
const prefix = `{"batchId":${JSON.stringify(header.batchId)},"producerId":${JSON.stringify(header.producerId)},"records":[`;
|
|
473
|
-
const batchJson = `${prefix}${encodings.map(({ json }) => json).join(",")}]}`;
|
|
474
|
-
|
|
475
|
-
const batchBytes = encodings.reduce(
|
|
476
|
-
(total, record) => total + record.bytes,
|
|
477
|
-
utf8ByteLength(prefix) + (encodings.length === 0 ? 2 : encodings.length + 1),
|
|
478
|
-
);
|
|
479
|
-
|
|
480
|
-
if (batchBytes > MAX_CANONICAL_BATCH_BYTES)
|
|
481
|
-
throw ThreadStoreError.make({
|
|
482
|
-
operation: "prepare canonical append",
|
|
483
|
-
message: `Canonical batch exceeds ${MAX_CANONICAL_BATCH_BYTES} bytes`,
|
|
527
|
+
try: () =>
|
|
528
|
+
Result.gen(function* () {
|
|
529
|
+
const header = validateHeader({
|
|
530
|
+
...input,
|
|
531
|
+
batchId: input.batch.batchId,
|
|
532
|
+
producerId: input.batch.producerId,
|
|
484
533
|
});
|
|
485
534
|
|
|
486
|
-
|
|
487
|
-
|
|
535
|
+
validateRecordCount(input.batch.records);
|
|
536
|
+
const executions = input.executions ?? [];
|
|
537
|
+
const executionLength = validateRecordCount(executions).length;
|
|
538
|
+
|
|
539
|
+
const executionWrites: Array<PreparedAppend["executionWrites"][number]> = [];
|
|
540
|
+
|
|
541
|
+
for (let index = 0; index < executionLength; index++)
|
|
542
|
+
executionWrites.push(yield* captureExecution(executions[index]!));
|
|
543
|
+
Object.freeze(executionWrites);
|
|
544
|
+
|
|
545
|
+
validateRecordCount(executionWrites);
|
|
546
|
+
|
|
547
|
+
if (input.batch.records.length === 0 && executionWrites.length === 0)
|
|
548
|
+
return yield* Result.fail(
|
|
549
|
+
ThreadStoreError.make({
|
|
550
|
+
operation: "prepare durable commit",
|
|
551
|
+
message: "A commit must contain history facts or an active execution transition",
|
|
552
|
+
}),
|
|
553
|
+
);
|
|
554
|
+
if (executionWrites.some(({ bytes }) => !transferPageFits(header.threadId, bytes)))
|
|
555
|
+
return yield* Result.fail(
|
|
556
|
+
ThreadStoreError.make({
|
|
557
|
+
operation: "prepare durable commit",
|
|
558
|
+
message: "Active state exceeds its bounded transfer representation",
|
|
559
|
+
}),
|
|
560
|
+
);
|
|
561
|
+
// Visit sparse slots too: capture owns each record's validation boundary.
|
|
562
|
+
const encodings = yield* Result.all(Array.from(input.batch.records, captureRecord));
|
|
563
|
+
const prefix = `{"batchId":${JSON.stringify(header.batchId)},"producerId":${JSON.stringify(header.producerId)},"records":[`;
|
|
564
|
+
const batchJson = `${prefix}${encodings.map(({ json }) => json).join(",")}]}`;
|
|
565
|
+
|
|
566
|
+
const batchBytes = encodings.reduce(
|
|
567
|
+
(total, record) => total + record.bytes,
|
|
568
|
+
utf8ByteLength(prefix) + (encodings.length === 0 ? 2 : encodings.length + 1),
|
|
569
|
+
);
|
|
570
|
+
|
|
571
|
+
if (batchBytes > MAX_CANONICAL_BATCH_BYTES)
|
|
572
|
+
return yield* Result.fail(
|
|
573
|
+
ThreadStoreError.make({
|
|
574
|
+
operation: "prepare canonical append",
|
|
575
|
+
message: `Canonical batch exceeds ${MAX_CANONICAL_BATCH_BYTES} bytes`,
|
|
576
|
+
}),
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
const batch = Object.freeze(
|
|
580
|
+
CommitBatch.make(
|
|
581
|
+
{
|
|
582
|
+
batchId: header.batchId,
|
|
583
|
+
producerId: header.producerId,
|
|
584
|
+
records: Object.freeze(encodings.map(({ canonical }) => canonical)),
|
|
585
|
+
},
|
|
586
|
+
{ disableChecks: true },
|
|
587
|
+
),
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
const request = AppendRequest.make(
|
|
488
591
|
{
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
592
|
+
threadId: header.threadId,
|
|
593
|
+
expectedTailSequence: header.expectedTailSequence,
|
|
594
|
+
batch,
|
|
595
|
+
...(executionWrites.length === 0
|
|
596
|
+
? {}
|
|
597
|
+
: { executions: Object.freeze(executionWrites.map(({ update }) => update)) }),
|
|
492
598
|
},
|
|
493
599
|
{ disableChecks: true },
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
Object.
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
600
|
+
);
|
|
601
|
+
|
|
602
|
+
const records = Object.freeze(
|
|
603
|
+
encodings.map(({ canonical, json, wire, bytes }) =>
|
|
604
|
+
Object.freeze({
|
|
605
|
+
recordId: canonical.recordId,
|
|
606
|
+
recordJson: json,
|
|
607
|
+
recordBytes: bytes,
|
|
608
|
+
wire,
|
|
609
|
+
canonical,
|
|
610
|
+
}),
|
|
611
|
+
),
|
|
612
|
+
);
|
|
613
|
+
|
|
614
|
+
const progress = Object.freeze(encodings.map(({ progress }) => progress));
|
|
615
|
+
|
|
616
|
+
const captured = Object.freeze(
|
|
617
|
+
Object.assign(request, {
|
|
618
|
+
batchJson,
|
|
619
|
+
batchBytes,
|
|
620
|
+
records,
|
|
621
|
+
progress,
|
|
622
|
+
executionWrites,
|
|
517
623
|
}),
|
|
518
|
-
)
|
|
519
|
-
);
|
|
520
|
-
|
|
521
|
-
const progress = Object.freeze(encodings.map(({ progress }) => progress));
|
|
624
|
+
);
|
|
522
625
|
|
|
523
|
-
|
|
524
|
-
Object.assign(request, {
|
|
525
|
-
batchJson,
|
|
526
|
-
batchBytes,
|
|
527
|
-
records,
|
|
528
|
-
progress,
|
|
529
|
-
executionWrites,
|
|
530
|
-
}),
|
|
531
|
-
);
|
|
626
|
+
capturedAppends.set(captured, captured);
|
|
532
627
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return captured;
|
|
536
|
-
},
|
|
628
|
+
return captured;
|
|
629
|
+
}),
|
|
537
630
|
catch: (cause) =>
|
|
538
631
|
Schema.is(ThreadStoreError)(cause)
|
|
539
632
|
? cause
|
|
@@ -544,7 +637,18 @@ export const PreparedAppend = {
|
|
|
544
637
|
: "Canonical append capture failed",
|
|
545
638
|
cause,
|
|
546
639
|
}),
|
|
547
|
-
})
|
|
640
|
+
}).pipe(
|
|
641
|
+
Effect.flatMap(Effect.fromResult),
|
|
642
|
+
Effect.mapError((cause) =>
|
|
643
|
+
Schema.is(ThreadStoreError)(cause)
|
|
644
|
+
? cause
|
|
645
|
+
: ThreadStoreError.make({
|
|
646
|
+
operation: "prepare canonical append",
|
|
647
|
+
message: cause.message,
|
|
648
|
+
cause,
|
|
649
|
+
}),
|
|
650
|
+
),
|
|
651
|
+
);
|
|
548
652
|
}),
|
|
549
653
|
};
|
|
550
654
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Crypto } from "effect";
|
|
2
1
|
import { Context, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
3
2
|
|
|
4
3
|
import { ReceiptId, RunId, SubmissionId, ThreadId, ToolCallId } from "../core/Identifiers.ts";
|
|
@@ -487,7 +486,7 @@ export type WorkIndexChange =
|
|
|
487
486
|
export const workIndexChanges = Effect.fnUntraced(function* (
|
|
488
487
|
envelope: CanonicalRecordEnvelope,
|
|
489
488
|
reporting: WorkerReportingMode,
|
|
490
|
-
): Effect.fn.Return<ReadonlyArray<WorkIndexChange>, ThreadStoreError
|
|
489
|
+
): Effect.fn.Return<ReadonlyArray<WorkIndexChange>, ThreadStoreError> {
|
|
491
490
|
const { record, sequence } = envelope;
|
|
492
491
|
const payload = record.payload;
|
|
493
492
|
|
|
@@ -52,9 +52,13 @@ export const makeStorageOwner = Effect.fnUntraced(function* (gate: MutationGate)
|
|
|
52
52
|
const active = new Map<string, { readonly claim: Claim; closed: boolean }>();
|
|
53
53
|
|
|
54
54
|
const withMutation: MutationGate = (effect) =>
|
|
55
|
-
Effect.
|
|
56
|
-
current
|
|
57
|
-
|
|
55
|
+
Effect.withFiber((fiber) => {
|
|
56
|
+
const current = fiber.getRef(ActiveOwner);
|
|
57
|
+
|
|
58
|
+
return current === identity
|
|
59
|
+
? effect
|
|
60
|
+
: gate(Effect.provideService(effect, ActiveOwner, identity));
|
|
61
|
+
});
|
|
58
62
|
|
|
59
63
|
yield* Effect.addFinalizer(() =>
|
|
60
64
|
withMutation(
|
|
@@ -70,7 +74,9 @@ export const makeStorageOwner = Effect.fnUntraced(function* (gate: MutationGate)
|
|
|
70
74
|
identity,
|
|
71
75
|
withMutation,
|
|
72
76
|
withProgress: (threadId, effect) =>
|
|
73
|
-
Effect.
|
|
77
|
+
Effect.withFiber((fiber) => {
|
|
78
|
+
const current = fiber.getRef(ActiveProgress);
|
|
79
|
+
|
|
74
80
|
if (current?.owner === identity && current.threadId === threadId) return effect;
|
|
75
81
|
|
|
76
82
|
return Effect.suspend(() => {
|