@yielded/agent 0.1.0-beta.173 → 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-B943ebI_.d.mts → MessageDelivery-BGDm-c46.d.mts} +42 -42
- 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-DpHxjBrA.d.mts → ThreadImport-CMgzttvr.d.mts} +5 -5
- 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
|
@@ -1662,6 +1662,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
1662
1662
|
let context: RunJournalContext | undefined;
|
|
1663
1663
|
let progress: RunContinuation | undefined;
|
|
1664
1664
|
let progressThrough: CanonicalSequence | undefined;
|
|
1665
|
+
let operational: ReadonlyArray<RecordEnvelope> = [];
|
|
1665
1666
|
|
|
1666
1667
|
const invalid = (message: string) =>
|
|
1667
1668
|
ThreadStoreError.make({
|
|
@@ -1822,6 +1823,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
1822
1823
|
context = saved;
|
|
1823
1824
|
progress = cursor;
|
|
1824
1825
|
progressThrough = envelope.throughSequence;
|
|
1826
|
+
operational = envelope.operational;
|
|
1825
1827
|
}
|
|
1826
1828
|
}
|
|
1827
1829
|
|
|
@@ -1833,7 +1835,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
1833
1835
|
).values(),
|
|
1834
1836
|
].sort((left, right) => left.sequence - right.sequence);
|
|
1835
1837
|
|
|
1836
|
-
return {
|
|
1838
|
+
return { records, context, progress, progressThrough, operational };
|
|
1837
1839
|
});
|
|
1838
1840
|
|
|
1839
1841
|
const readControl = Effect.fnUntraced(function* (
|
|
@@ -1843,9 +1845,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
1843
1845
|
const tail = yield* store.inspectTail(ThreadTailRequest.make({ threadId }));
|
|
1844
1846
|
const view = yield* recoveryView(threadId, tail.tailSequence, submissionIds);
|
|
1845
1847
|
|
|
1846
|
-
return
|
|
1847
|
-
view.canonical.pipe(Stream.filter(controlRecords(submissionIds))),
|
|
1848
|
-
);
|
|
1848
|
+
return view.records.filter(controlRecords(submissionIds));
|
|
1849
1849
|
});
|
|
1850
1850
|
|
|
1851
1851
|
const readAllTolerant = (
|
|
@@ -1888,9 +1888,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
1888
1888
|
return { records: [], materialized: false, throughSequence: ZERO_SEQUENCE, submissionIds };
|
|
1889
1889
|
|
|
1890
1890
|
const records = yield* recoveryView(threadId, tail.value.tailSequence, submissionIds).pipe(
|
|
1891
|
-
Effect.
|
|
1892
|
-
Stream.runCollect(view.canonical.pipe(Stream.filter(controlRecords(submissionIds)))),
|
|
1893
|
-
),
|
|
1891
|
+
Effect.map((view) => view.records.filter(controlRecords(submissionIds))),
|
|
1894
1892
|
Effect.catchTag("ThreadNotMaterialized", (error) =>
|
|
1895
1893
|
ThreadStoreError.make({
|
|
1896
1894
|
operation: "read recovery history",
|
|
@@ -2629,50 +2627,49 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
2629
2627
|
// also covers a destination handoff written before dispatch or after Run settlement.
|
|
2630
2628
|
const progressStore = ThreadStore.of({
|
|
2631
2629
|
...store,
|
|
2632
|
-
append: (request)
|
|
2633
|
-
|
|
2634
|
-
const active = activeProgress.get(request.threadId);
|
|
2630
|
+
append: Effect.fnUntraced(function* (request) {
|
|
2631
|
+
const active = activeProgress.get(request.threadId);
|
|
2635
2632
|
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2633
|
+
const progress =
|
|
2634
|
+
active?.writer ??
|
|
2635
|
+
(yield* makeProgressWriter(request.threadId, config.deploymentId).pipe(
|
|
2636
|
+
Effect.provideService(ThreadReader, reader),
|
|
2637
|
+
Effect.provideService(Crypto.Crypto, crypto),
|
|
2638
|
+
));
|
|
2642
2639
|
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2640
|
+
let tail = {
|
|
2641
|
+
sequence: request.expectedTailSequence,
|
|
2642
|
+
};
|
|
2646
2643
|
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2644
|
+
return yield* progress.commit(request.batch).pipe(
|
|
2645
|
+
Effect.provideService(CurrentRunWriter, {
|
|
2646
|
+
threadId: request.threadId,
|
|
2647
|
+
tail: Effect.sync(() => tail),
|
|
2648
|
+
withProgress: (effect) => storageOwner.withProgress(request.threadId, effect),
|
|
2649
|
+
append: (batch, executions) =>
|
|
2650
|
+
store
|
|
2651
|
+
.append(
|
|
2652
|
+
AppendRequest.make({
|
|
2653
|
+
...request,
|
|
2654
|
+
expectedTailSequence: tail.sequence,
|
|
2655
|
+
|
|
2656
|
+
batch,
|
|
2657
|
+
executions,
|
|
2658
|
+
}),
|
|
2659
|
+
)
|
|
2660
|
+
.pipe(
|
|
2661
|
+
Effect.tapErrorTag("AppendConflict", (conflict) =>
|
|
2662
|
+
Effect.sync(() => {
|
|
2663
|
+
if (conflict.reason === "tail" && conflict.actualTailSequence !== undefined)
|
|
2664
|
+
tail = {
|
|
2665
|
+
sequence: conflict.actualTailSequence,
|
|
2666
|
+
};
|
|
2661
2667
|
}),
|
|
2662
|
-
)
|
|
2663
|
-
.pipe(
|
|
2664
|
-
Effect.tapErrorTag("AppendConflict", (conflict) =>
|
|
2665
|
-
Effect.sync(() => {
|
|
2666
|
-
if (conflict.reason === "tail" && conflict.actualTailSequence !== undefined)
|
|
2667
|
-
tail = {
|
|
2668
|
-
sequence: conflict.actualTailSequence,
|
|
2669
|
-
};
|
|
2670
|
-
}),
|
|
2671
|
-
),
|
|
2672
2668
|
),
|
|
2673
|
-
|
|
2674
|
-
)
|
|
2675
|
-
|
|
2669
|
+
),
|
|
2670
|
+
}),
|
|
2671
|
+
);
|
|
2672
|
+
}),
|
|
2676
2673
|
});
|
|
2677
2674
|
|
|
2678
2675
|
const appendBatch = (ctx: Pick<RunWriter, "threadId" | "append">, batch: CanonicalBatch) =>
|
|
@@ -2701,51 +2698,49 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
2701
2698
|
threadId: ctx.threadId,
|
|
2702
2699
|
tail: ctx.tail,
|
|
2703
2700
|
withProgress: ctx.withProgress,
|
|
2704
|
-
publishSettlement: (prepared, executions)
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
.
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
executions,
|
|
2720
|
-
}),
|
|
2701
|
+
publishSettlement: Effect.fnUntraced(function* (prepared, executions) {
|
|
2702
|
+
let tail = yield* ctx.tail;
|
|
2703
|
+
|
|
2704
|
+
for (let retries = 0; ; retries++) {
|
|
2705
|
+
const result = yield* runStorage
|
|
2706
|
+
.publishSettlement(
|
|
2707
|
+
SettlementPublication.make({
|
|
2708
|
+
submissionId,
|
|
2709
|
+
authority,
|
|
2710
|
+
append: AppendRequest.make({
|
|
2711
|
+
threadId: ctx.threadId,
|
|
2712
|
+
expectedTailSequence: tail.sequence,
|
|
2713
|
+
|
|
2714
|
+
batch: prepared,
|
|
2715
|
+
executions,
|
|
2721
2716
|
}),
|
|
2722
|
-
)
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
if (executions !== undefined && executions.length > 0)
|
|
2738
|
-
return ctx.refresh.pipe(Effect.andThen(Effect.fail(conflict)));
|
|
2739
|
-
|
|
2740
|
-
return Effect.succeed(undefined);
|
|
2741
|
-
}),
|
|
2742
|
-
);
|
|
2717
|
+
}),
|
|
2718
|
+
)
|
|
2719
|
+
.pipe(
|
|
2720
|
+
(effect) => storageOwner.withMutation(Effect.andThen(ctx.checkActive, effect)),
|
|
2721
|
+
Effect.catchTag("AppendConflict", (conflict) => {
|
|
2722
|
+
if (
|
|
2723
|
+
conflict.reason !== "tail" ||
|
|
2724
|
+
conflict.actualTailSequence === undefined ||
|
|
2725
|
+
retries >= 8
|
|
2726
|
+
)
|
|
2727
|
+
return Effect.fail(conflict);
|
|
2728
|
+
tail = {
|
|
2729
|
+
sequence: conflict.actualTailSequence,
|
|
2730
|
+
};
|
|
2743
2731
|
|
|
2744
|
-
|
|
2732
|
+
if (executions !== undefined && executions.length > 0)
|
|
2733
|
+
return ctx.refresh.pipe(Effect.andThen(Effect.fail(conflict)));
|
|
2745
2734
|
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2735
|
+
return Effect.succeed(undefined);
|
|
2736
|
+
}),
|
|
2737
|
+
);
|
|
2738
|
+
|
|
2739
|
+
if (result === undefined) continue;
|
|
2740
|
+
|
|
2741
|
+
return result;
|
|
2742
|
+
}
|
|
2743
|
+
}),
|
|
2749
2744
|
}),
|
|
2750
2745
|
);
|
|
2751
2746
|
});
|
|
@@ -3207,15 +3202,23 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
3207
3202
|
yield* ownership.markInputApplied({ recordId, sequence: result.firstSequence });
|
|
3208
3203
|
});
|
|
3209
3204
|
|
|
3210
|
-
const readRunStart = Effect.fnUntraced(function* (
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3205
|
+
const readRunStart = Effect.fnUntraced(function* (
|
|
3206
|
+
threadId: ThreadId,
|
|
3207
|
+
runId: RunId,
|
|
3208
|
+
operational?: ReadonlyArray<RecordEnvelope>,
|
|
3209
|
+
) {
|
|
3210
|
+
if (operational === undefined) {
|
|
3211
|
+
const loaded = yield* reader
|
|
3212
|
+
.readExecution({ threadId, runId })
|
|
3213
|
+
.pipe(Effect.catchTag("ThreadNotMaterialized", () => Effect.succeed(Option.none())));
|
|
3214
|
+
|
|
3215
|
+
if (Option.isNone(loaded)) return undefined;
|
|
3216
|
+
operational = loaded.value.operational;
|
|
3217
|
+
}
|
|
3214
3218
|
|
|
3215
|
-
if (Option.isNone(loaded)) return undefined;
|
|
3216
3219
|
const recordId = runStartedRecordId(runId);
|
|
3217
|
-
const starts =
|
|
3218
|
-
const existing =
|
|
3220
|
+
const starts = operational.filter(({ payload }) => payload._tag === "RunStarted");
|
|
3221
|
+
const existing = operational.find((record) => record.recordId === recordId);
|
|
3219
3222
|
|
|
3220
3223
|
if (
|
|
3221
3224
|
starts.length > 1 ||
|
|
@@ -3234,11 +3237,12 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
3234
3237
|
submission: SubmissionSnapshot,
|
|
3235
3238
|
maxDurationMillis: number,
|
|
3236
3239
|
records: ReadonlyArray<CanonicalRecordEnvelope>,
|
|
3240
|
+
operational: ReadonlyArray<RecordEnvelope>,
|
|
3237
3241
|
) {
|
|
3238
3242
|
const writer = yield* CurrentRunWriter;
|
|
3239
3243
|
const runId = runIdForSubmission(submission.submissionId);
|
|
3240
3244
|
const recordId = runStartedRecordId(runId);
|
|
3241
|
-
const existing = yield* readRunStart(submission.threadId, runId);
|
|
3245
|
+
const existing = yield* readRunStart(submission.threadId, runId, operational);
|
|
3242
3246
|
let start: RecordEnvelope;
|
|
3243
3247
|
let allowance = maxDurationMillis;
|
|
3244
3248
|
let committed = existing !== undefined;
|
|
@@ -4762,70 +4766,71 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
4762
4766
|
knownIds.add(recordId);
|
|
4763
4767
|
});
|
|
4764
4768
|
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
Tools extends Record<string, Tool.Any>,
|
|
4782
|
-
Provider,
|
|
4783
|
-
ModelProvides,
|
|
4784
|
-
ModelRequires,
|
|
4785
|
-
InstructionError = InstructionErrorOf<Instructions, InputSchema["Type"]>,
|
|
4786
|
-
InstructionRequirements = InstructionRequirementsOf<Instructions, InputSchema["Type"]>,
|
|
4787
|
-
RunDispositionValue extends
|
|
4788
|
-
| RunDispositionDeclaration<OutputSchema["Type"], Schema.Top>
|
|
4789
|
-
| undefined = undefined,
|
|
4790
|
-
InputPromptValue extends InputPromptSource<InputSchema["Type"], unknown, unknown> | undefined =
|
|
4791
|
-
undefined,
|
|
4792
|
-
UpdatesSchema extends Schema.Top | undefined = undefined,
|
|
4793
|
-
>(
|
|
4794
|
-
agent: RuntimeBinding<
|
|
4795
|
-
InputSchema,
|
|
4796
|
-
OutputSchema,
|
|
4769
|
+
const runModel = Effect.fnUntraced(
|
|
4770
|
+
/**
|
|
4771
|
+
* Drive the shared interpreter Effect with history rebuilt by the run journal, commit
|
|
4772
|
+
* each Turn under the local owner, and watch for durable abort intent. Engine Run failures settle `failed`; coordinator failures abort the
|
|
4773
|
+
* Attempt cleanly with the obligation still owed.
|
|
4774
|
+
*
|
|
4775
|
+
* The interpreter supplies validated response, closed Tool-result, and completion facts.
|
|
4776
|
+
* Responses precede approval and effectful dispatch; readonly responses may join their closed
|
|
4777
|
+
* results. Tool results precede input drains and the next Turn. A no-tool response and Run
|
|
4778
|
+
* completion share one batch. A completion Tool's result
|
|
4779
|
+
* precedes its terminal-only completion batch, so recovery can repeat a pure output projection
|
|
4780
|
+
* without replaying the handler. Pending batches resume from their canonical declarations.
|
|
4781
|
+
*/
|
|
4782
|
+
function* <
|
|
4783
|
+
InputSchema extends Schema.Top,
|
|
4784
|
+
OutputSchema extends Schema.Top,
|
|
4797
4785
|
Instructions,
|
|
4798
|
-
Tools,
|
|
4786
|
+
Tools extends Record<string, Tool.Any>,
|
|
4799
4787
|
Provider,
|
|
4800
4788
|
ModelProvides,
|
|
4801
4789
|
ModelRequires,
|
|
4802
|
-
InstructionError,
|
|
4803
|
-
InstructionRequirements,
|
|
4804
|
-
RunDispositionValue
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4790
|
+
InstructionError = InstructionErrorOf<Instructions, InputSchema["Type"]>,
|
|
4791
|
+
InstructionRequirements = InstructionRequirementsOf<Instructions, InputSchema["Type"]>,
|
|
4792
|
+
RunDispositionValue extends
|
|
4793
|
+
| RunDispositionDeclaration<OutputSchema["Type"], Schema.Top>
|
|
4794
|
+
| undefined = undefined,
|
|
4795
|
+
InputPromptValue extends
|
|
4796
|
+
| InputPromptSource<InputSchema["Type"], unknown, unknown>
|
|
4797
|
+
| undefined = undefined,
|
|
4798
|
+
UpdatesSchema extends Schema.Top | undefined = undefined,
|
|
4799
|
+
>(
|
|
4800
|
+
agent: RuntimeBinding<
|
|
4801
|
+
InputSchema,
|
|
4802
|
+
OutputSchema,
|
|
4803
|
+
Instructions,
|
|
4804
|
+
Tools,
|
|
4805
|
+
Provider,
|
|
4806
|
+
ModelProvides,
|
|
4807
|
+
ModelRequires,
|
|
4808
|
+
InstructionError,
|
|
4809
|
+
InstructionRequirements,
|
|
4810
|
+
RunDispositionValue,
|
|
4811
|
+
InputPromptValue,
|
|
4812
|
+
UpdatesSchema
|
|
4813
|
+
>,
|
|
4814
|
+
ctx: AttemptAppendContext,
|
|
4815
|
+
submission: SubmissionSnapshot,
|
|
4816
|
+
session: RunStorageSession,
|
|
4817
|
+
records: ReadonlyArray<CanonicalRecordEnvelope>,
|
|
4818
|
+
canonical: Stream.Stream<
|
|
4819
|
+
JournalRecordEnvelope,
|
|
4820
|
+
ThreadStoreError | ThreadNotMaterialized | RunJournalError
|
|
4821
|
+
>,
|
|
4822
|
+
initialJournal: InitialJournalSource | undefined,
|
|
4823
|
+
canonicalThrough: CanonicalSequence,
|
|
4824
|
+
progressThrough: CanonicalSequence | undefined,
|
|
4825
|
+
continuation: RunContinuation | undefined,
|
|
4826
|
+
priorContext: RunJournalContext | undefined,
|
|
4827
|
+
journalMetadata: JournalMetadata | undefined,
|
|
4828
|
+
lineage: AttemptLineage,
|
|
4829
|
+
approvalDecisions: ReadonlyArray<ApprovalDecisionIntent>,
|
|
4830
|
+
currentContracts: Readonly<Record<string, Digest>>,
|
|
4831
|
+
runTiming: RunTiming,
|
|
4832
|
+
yieldAfter?: DateTime.Utc,
|
|
4833
|
+
) {
|
|
4829
4834
|
const submissionId = submission.submissionId;
|
|
4830
4835
|
|
|
4831
4836
|
const runId = runIdForSubmission(submissionId);
|
|
@@ -6065,9 +6070,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6065
6070
|
// The interpreter supplies only closed siblings, in declaration order.
|
|
6066
6071
|
// Per-call identities retain each result before the child suspension.
|
|
6067
6072
|
for (const result of toolResults) {
|
|
6068
|
-
const batch = yield*
|
|
6069
|
-
turnResultsBatch({ ...input, toolResults: [result] }),
|
|
6070
|
-
);
|
|
6073
|
+
const batch = yield* turnResultsBatch({ ...input, toolResults: [result] });
|
|
6071
6074
|
|
|
6072
6075
|
yield* appendBatch(
|
|
6073
6076
|
ctx,
|
|
@@ -6100,47 +6103,45 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6100
6103
|
turnId: commit.turnId,
|
|
6101
6104
|
// The journal owns encoded messages. Detach the remaining small metadata
|
|
6102
6105
|
// trees too: Schema validation alone is not an ownership transfer.
|
|
6103
|
-
batch: yield*
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
toolExposure
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
toolNames: [...input.toolExposure.selection.toolNames],
|
|
6121
|
-
}),
|
|
6106
|
+
batch: yield* turnCanonicalBatch({
|
|
6107
|
+
...input,
|
|
6108
|
+
toolParameterRejections: input.toolParameterRejections?.map((rejection) => ({
|
|
6109
|
+
...rejection,
|
|
6110
|
+
parameters: copyJson(rejection.parameters),
|
|
6111
|
+
error: { ...rejection.error, reason: { ...rejection.error.reason } },
|
|
6112
|
+
})),
|
|
6113
|
+
toolExposure:
|
|
6114
|
+
input.toolExposure === undefined
|
|
6115
|
+
? undefined
|
|
6116
|
+
: Snapshot.make({
|
|
6117
|
+
exposedToolNames: [...input.toolExposure.exposedToolNames],
|
|
6118
|
+
...(input.toolExposure.selection === undefined
|
|
6119
|
+
? {}
|
|
6120
|
+
: {
|
|
6121
|
+
selection: Selection.make({
|
|
6122
|
+
toolNames: [...input.toolExposure.selection.toolNames],
|
|
6122
6123
|
}),
|
|
6123
|
-
}),
|
|
6124
|
-
usage:
|
|
6125
|
-
input.usage === undefined
|
|
6126
|
-
? undefined
|
|
6127
|
-
: {
|
|
6128
|
-
...input.usage,
|
|
6129
|
-
modelUsage: input.usage.modelUsage?.map((usage) =>
|
|
6130
|
-
ModelCallUsage.make({
|
|
6131
|
-
...usage,
|
|
6132
|
-
...(usage.response === undefined
|
|
6133
|
-
? {}
|
|
6134
|
-
: {
|
|
6135
|
-
response: ModelResponseIdentity.make({ ...usage.response }),
|
|
6136
|
-
}),
|
|
6137
|
-
inputTokens: InputTokenUsage.make({ ...usage.inputTokens }),
|
|
6138
|
-
outputTokens: OutputTokenUsage.make({ ...usage.outputTokens }),
|
|
6139
6124
|
}),
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6125
|
+
}),
|
|
6126
|
+
usage:
|
|
6127
|
+
input.usage === undefined
|
|
6128
|
+
? undefined
|
|
6129
|
+
: {
|
|
6130
|
+
...input.usage,
|
|
6131
|
+
modelUsage: input.usage.modelUsage?.map((usage) =>
|
|
6132
|
+
ModelCallUsage.make({
|
|
6133
|
+
...usage,
|
|
6134
|
+
...(usage.response === undefined
|
|
6135
|
+
? {}
|
|
6136
|
+
: {
|
|
6137
|
+
response: ModelResponseIdentity.make({ ...usage.response }),
|
|
6138
|
+
}),
|
|
6139
|
+
inputTokens: InputTokenUsage.make({ ...usage.inputTokens }),
|
|
6140
|
+
outputTokens: OutputTokenUsage.make({ ...usage.outputTokens }),
|
|
6141
|
+
}),
|
|
6142
|
+
),
|
|
6143
|
+
},
|
|
6144
|
+
}),
|
|
6144
6145
|
};
|
|
6145
6146
|
|
|
6146
6147
|
const progress = progressWriters.get(ctx);
|
|
@@ -6163,17 +6164,15 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6163
6164
|
let batch: CanonicalBatch;
|
|
6164
6165
|
|
|
6165
6166
|
if (deferred === undefined) {
|
|
6166
|
-
batch = yield*
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
: turnCanonicalBatch(input),
|
|
6172
|
-
);
|
|
6167
|
+
batch = yield* commit._tag === "Response"
|
|
6168
|
+
? turnResponseBatch(input)
|
|
6169
|
+
: response === undefined
|
|
6170
|
+
? turnResultsBatch(input)
|
|
6171
|
+
: turnCanonicalBatch(input);
|
|
6173
6172
|
} else if (toolResults.length === 0 && runCompletion === undefined) {
|
|
6174
6173
|
batch = deferred.batch;
|
|
6175
6174
|
} else {
|
|
6176
|
-
const results = yield*
|
|
6175
|
+
const results = yield* turnResultsBatch(input);
|
|
6177
6176
|
|
|
6178
6177
|
batch = CanonicalBatch.make({
|
|
6179
6178
|
...deferred.batch,
|
|
@@ -6347,214 +6346,208 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6347
6346
|
.get(ctx)
|
|
6348
6347
|
?.stageUsage(runId, terminalUsageCharge(uncommittedModelUsage()));
|
|
6349
6348
|
}),
|
|
6350
|
-
commitCompaction: (commit)
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
const recordId = compactionRecordId(runId, canonicalTurn, commit.kind);
|
|
6354
|
-
|
|
6355
|
-
if (knownIds.has(recordId)) {
|
|
6356
|
-
return yield* CompactionError.make({
|
|
6357
|
-
message: "Compaction is already committed for this Turn and kind",
|
|
6358
|
-
});
|
|
6359
|
-
}
|
|
6349
|
+
commitCompaction: Effect.fnUntraced(function* (commit) {
|
|
6350
|
+
const canonicalTurn = commit.turn;
|
|
6351
|
+
const recordId = compactionRecordId(runId, canonicalTurn, commit.kind);
|
|
6360
6352
|
|
|
6361
|
-
|
|
6362
|
-
|
|
6353
|
+
if (knownIds.has(recordId)) {
|
|
6354
|
+
return yield* CompactionError.make({
|
|
6355
|
+
message: "Compaction is already committed for this Turn and kind",
|
|
6356
|
+
});
|
|
6357
|
+
}
|
|
6363
6358
|
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
initialJournal.history = undefined;
|
|
6367
|
-
}
|
|
6368
|
-
if (commit.kind !== "summarize" || initialJournal?.prefix !== undefined) {
|
|
6369
|
-
// Results must be canonical before pruning or rollover can cover them. Newly committed
|
|
6370
|
-
// compactions remain overlays on this Attempt's append-only source, so omit those
|
|
6371
|
-
// overlays while reconstructing the exact source-to-record mapping.
|
|
6372
|
-
const tail = yield* ctx.tail;
|
|
6373
|
-
|
|
6374
|
-
const source =
|
|
6375
|
-
initialJournal === undefined
|
|
6376
|
-
? canonical
|
|
6377
|
-
: Stream.fromIterable(
|
|
6378
|
-
yield* recordHalt(
|
|
6379
|
-
readInitialJournal(initialJournal.original, initialJournal.suffix),
|
|
6380
|
-
),
|
|
6381
|
-
);
|
|
6359
|
+
let sourceJournal = journal;
|
|
6360
|
+
let sourceBoundaries = boundaries;
|
|
6382
6361
|
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6362
|
+
if (initialJournal !== undefined) {
|
|
6363
|
+
initialJournal.cacheable = false;
|
|
6364
|
+
initialJournal.history = undefined;
|
|
6365
|
+
}
|
|
6366
|
+
if (commit.kind !== "summarize" || initialJournal?.prefix !== undefined) {
|
|
6367
|
+
// Results must be canonical before pruning or rollover can cover them. Newly committed
|
|
6368
|
+
// compactions remain overlays on this Attempt's append-only source, so omit those
|
|
6369
|
+
// overlays while reconstructing the exact source-to-record mapping.
|
|
6370
|
+
const tail = yield* ctx.tail;
|
|
6371
|
+
|
|
6372
|
+
const source =
|
|
6373
|
+
initialJournal === undefined
|
|
6374
|
+
? canonical
|
|
6375
|
+
: Stream.fromIterable(
|
|
6376
|
+
yield* recordHalt(
|
|
6377
|
+
readInitialJournal(initialJournal.original, initialJournal.suffix),
|
|
6397
6378
|
),
|
|
6398
|
-
)
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6379
|
+
);
|
|
6380
|
+
|
|
6381
|
+
sourceBoundaries = [];
|
|
6382
|
+
sourceJournal = yield* recordHalt(
|
|
6383
|
+
projectRunJournalStream(
|
|
6384
|
+
Stream.concat(
|
|
6385
|
+
source,
|
|
6386
|
+
Stream.fromIterable(
|
|
6387
|
+
yield* recordHalt(
|
|
6388
|
+
selectedRange(ctx.threadId, [submissionId], tail.sequence, canonicalThrough),
|
|
6403
6389
|
),
|
|
6404
6390
|
),
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6391
|
+
).pipe(
|
|
6392
|
+
Stream.filter(
|
|
6393
|
+
(envelope) =>
|
|
6394
|
+
envelope.record.payload._tag !== "CompactionCreated" ||
|
|
6395
|
+
envelope.sequence <= canonicalThrough,
|
|
6396
|
+
),
|
|
6408
6397
|
),
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
// complete current-Run boundaries from the fresh canonical source above.
|
|
6414
|
-
const coverable = sourceBoundaries.filter(
|
|
6415
|
-
(boundary) =>
|
|
6416
|
-
commit.kind !== "summarize" ||
|
|
6417
|
-
ownerFirstSequence === undefined ||
|
|
6418
|
-
boundary.sequence < ownerFirstSequence,
|
|
6398
|
+
runId,
|
|
6399
|
+
(boundary) => sourceBoundaries.push(boundary),
|
|
6400
|
+
priorContext,
|
|
6401
|
+
),
|
|
6419
6402
|
);
|
|
6403
|
+
}
|
|
6420
6404
|
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6405
|
+
// Summaries use the initial prior-Run boundaries; pruning and rollover also admit
|
|
6406
|
+
// complete current-Run boundaries from the fresh canonical source above.
|
|
6407
|
+
const coverable = sourceBoundaries.filter(
|
|
6408
|
+
(boundary) =>
|
|
6409
|
+
commit.kind !== "summarize" ||
|
|
6410
|
+
ownerFirstSequence === undefined ||
|
|
6411
|
+
boundary.sequence < ownerFirstSequence,
|
|
6412
|
+
);
|
|
6429
6413
|
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6414
|
+
if (coverable.length === 0) {
|
|
6415
|
+
return yield* CompactionError.make({
|
|
6416
|
+
message:
|
|
6417
|
+
commit.kind === "rollover"
|
|
6418
|
+
? "Durable rollover requires complete canonical records"
|
|
6419
|
+
: "Durable compaction requires eligible canonical records",
|
|
6420
|
+
});
|
|
6421
|
+
}
|
|
6436
6422
|
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6423
|
+
const comparisonView = instructionView(
|
|
6424
|
+
sourceJournal.prompt.content,
|
|
6425
|
+
initialInstructions,
|
|
6426
|
+
false,
|
|
6427
|
+
sourceJournal.historyBefore.content.length,
|
|
6428
|
+
);
|
|
6442
6429
|
|
|
6443
|
-
|
|
6444
|
-
|
|
6430
|
+
// Compare each visible message once. A transformed source can authorize only its
|
|
6431
|
+
// exact canonical prefix; no per-candidate rereads or full encoded Prompt copies.
|
|
6432
|
+
let matchingPrefix = 0;
|
|
6433
|
+
let requiredThrough = 0;
|
|
6434
|
+
const comparisonLimit = Math.min(comparisonView.messages.length, commit.through);
|
|
6445
6435
|
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
(commit.kind === "clear-tool-results"
|
|
6449
|
-
? message.role === "tool"
|
|
6450
|
-
: message.role !== "system")
|
|
6451
|
-
)
|
|
6452
|
-
requiredThrough = index + 1;
|
|
6453
|
-
if (index >= comparisonLimit || index !== matchingPrefix || message === undefined)
|
|
6454
|
-
continue;
|
|
6455
|
-
const canonicalMessage = comparisonView.messages[index];
|
|
6456
|
-
|
|
6457
|
-
if (canonicalMessage === undefined) continue;
|
|
6458
|
-
|
|
6459
|
-
// Preserve Prompt's JSON projection while ignoring persisted object-key order.
|
|
6460
|
-
const encode = (entry: Prompt.Message) =>
|
|
6461
|
-
encodeCompactionMessageJson(entry).pipe(
|
|
6462
|
-
Effect.flatMap(decodeCompactionMessageJson),
|
|
6463
|
-
Effect.map(canonicalJson),
|
|
6464
|
-
Effect.mapError((cause) =>
|
|
6465
|
-
CompactionError.make({
|
|
6466
|
-
message: "Could not encode the canonical compaction prefix",
|
|
6467
|
-
cause,
|
|
6468
|
-
}),
|
|
6469
|
-
),
|
|
6470
|
-
);
|
|
6436
|
+
for (let index = 0; index < commit.through; index += 1) {
|
|
6437
|
+
const message = commit.source.content[index];
|
|
6471
6438
|
|
|
6472
|
-
|
|
6473
|
-
|
|
6439
|
+
if (
|
|
6440
|
+
message !== undefined &&
|
|
6441
|
+
(commit.kind === "clear-tool-results"
|
|
6442
|
+
? message.role === "tool"
|
|
6443
|
+
: message.role !== "system")
|
|
6444
|
+
)
|
|
6445
|
+
requiredThrough = index + 1;
|
|
6446
|
+
if (index >= comparisonLimit || index !== matchingPrefix || message === undefined)
|
|
6447
|
+
continue;
|
|
6448
|
+
const canonicalMessage = comparisonView.messages[index];
|
|
6449
|
+
|
|
6450
|
+
if (canonicalMessage === undefined) continue;
|
|
6451
|
+
|
|
6452
|
+
// Preserve Prompt's JSON projection while ignoring persisted object-key order.
|
|
6453
|
+
const encode = (entry: Prompt.Message) =>
|
|
6454
|
+
encodeCompactionMessageJson(entry).pipe(
|
|
6455
|
+
Effect.flatMap(decodeCompactionMessageJson),
|
|
6456
|
+
Effect.map(canonicalJson),
|
|
6457
|
+
Effect.mapError((cause) =>
|
|
6458
|
+
CompactionError.make({
|
|
6459
|
+
message: "Could not encode the canonical compaction prefix",
|
|
6460
|
+
cause,
|
|
6461
|
+
}),
|
|
6462
|
+
),
|
|
6463
|
+
);
|
|
6474
6464
|
|
|
6475
|
-
|
|
6476
|
-
|
|
6465
|
+
const left = yield* encode(canonicalMessage);
|
|
6466
|
+
const right = yield* encode(message);
|
|
6477
6467
|
|
|
6478
|
-
|
|
6468
|
+
if (left === right) matchingPrefix += 1;
|
|
6469
|
+
}
|
|
6479
6470
|
|
|
6480
|
-
|
|
6481
|
-
const candidate = coverable[index];
|
|
6471
|
+
let lastCovered: JournalBoundary | undefined;
|
|
6482
6472
|
|
|
6483
|
-
|
|
6484
|
-
|
|
6473
|
+
for (let index = 0; index < coverable.length; index += 1) {
|
|
6474
|
+
const candidate = coverable[index];
|
|
6485
6475
|
|
|
6486
|
-
|
|
6476
|
+
if (candidate === undefined) continue;
|
|
6477
|
+
const following = coverable[index + 1];
|
|
6487
6478
|
|
|
6488
|
-
|
|
6479
|
+
if (following?.tag === "ToolCallSettled") continue;
|
|
6489
6480
|
|
|
6490
|
-
|
|
6491
|
-
if (length < requiredThrough || length > matchingPrefix) continue;
|
|
6492
|
-
lastCovered = candidate;
|
|
6493
|
-
}
|
|
6494
|
-
if (lastCovered === undefined) {
|
|
6495
|
-
return yield* CompactionError.make({
|
|
6496
|
-
message:
|
|
6497
|
-
commit.kind === "rollover"
|
|
6498
|
-
? "Rollover coverage cannot be mapped to complete canonical records"
|
|
6499
|
-
: "Compaction coverage cannot be mapped to complete canonical records",
|
|
6500
|
-
});
|
|
6501
|
-
}
|
|
6502
|
-
const coveredSequence = lastCovered.sequence;
|
|
6481
|
+
const length = comparisonView.prefixLength(candidate.promptLength);
|
|
6503
6482
|
|
|
6504
|
-
if (
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
if (commit.kind === "summarize" && (commit.summary ?? "").trim().length === 0) {
|
|
6518
|
-
return yield* CompactionError.make({
|
|
6519
|
-
message: "A summarize compaction commit carried no summary",
|
|
6520
|
-
});
|
|
6521
|
-
}
|
|
6483
|
+
if (length === 0 || length > commit.through) continue;
|
|
6484
|
+
if (length < requiredThrough || length > matchingPrefix) continue;
|
|
6485
|
+
lastCovered = candidate;
|
|
6486
|
+
}
|
|
6487
|
+
if (lastCovered === undefined) {
|
|
6488
|
+
return yield* CompactionError.make({
|
|
6489
|
+
message:
|
|
6490
|
+
commit.kind === "rollover"
|
|
6491
|
+
? "Rollover coverage cannot be mapped to complete canonical records"
|
|
6492
|
+
: "Compaction coverage cannot be mapped to complete canonical records",
|
|
6493
|
+
});
|
|
6494
|
+
}
|
|
6495
|
+
const coveredSequence = lastCovered.sequence;
|
|
6522
6496
|
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6497
|
+
if (
|
|
6498
|
+
commit.kind !== "summarize" &&
|
|
6499
|
+
sourceBoundaries.some(
|
|
6500
|
+
(boundary) =>
|
|
6501
|
+
boundary.incomplete === true &&
|
|
6502
|
+
boundary.terminalPriorRun !== true &&
|
|
6503
|
+
boundary.sequence <= coveredSequence,
|
|
6504
|
+
)
|
|
6505
|
+
) {
|
|
6506
|
+
return yield* CompactionError.make({
|
|
6507
|
+
message: "Compaction cannot cover an incomplete Tool batch",
|
|
6508
|
+
});
|
|
6509
|
+
}
|
|
6510
|
+
if (commit.kind === "summarize" && (commit.summary ?? "").trim().length === 0) {
|
|
6511
|
+
return yield* CompactionError.make({
|
|
6512
|
+
message: "A summarize compaction commit carried no summary",
|
|
6513
|
+
});
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6516
|
+
const payload = yield* Schema.decodeEffect(CompactionCreated)({
|
|
6517
|
+
_tag: "CompactionCreated",
|
|
6518
|
+
runId,
|
|
6519
|
+
turn: canonicalTurn,
|
|
6520
|
+
kind: commit.kind,
|
|
6521
|
+
coversThrough: lastCovered.sequence,
|
|
6522
|
+
...(commit.kind === "summarize" ? { summary: commit.summary } : {}),
|
|
6523
|
+
...(commit.kind === "rollover" && commit.handoff !== undefined
|
|
6524
|
+
? { handoff: commit.handoff }
|
|
6525
|
+
: {}),
|
|
6526
|
+
}).pipe(
|
|
6527
|
+
Effect.mapError((cause) =>
|
|
6528
|
+
CompactionError.make({
|
|
6529
|
+
message: "Compaction decision exceeds canonical persistence bounds",
|
|
6530
|
+
cause,
|
|
6531
|
+
}),
|
|
6532
|
+
),
|
|
6533
|
+
);
|
|
6541
6534
|
|
|
6542
|
-
|
|
6535
|
+
const envelope = yield* recordHalt(makeEnvelope(recordId, payload));
|
|
6543
6536
|
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6537
|
+
yield* recordHalt(hit("compaction:before-canonical-append"));
|
|
6538
|
+
yield* recordHalt(
|
|
6539
|
+
appendBatch(
|
|
6540
|
+
ctx,
|
|
6541
|
+
CanonicalBatch.make({
|
|
6542
|
+
batchId: compactionBatchId(runId, canonicalTurn, commit.kind),
|
|
6543
|
+
producerId: config.producerId,
|
|
6544
|
+
records: [envelope],
|
|
6545
|
+
}),
|
|
6546
|
+
),
|
|
6547
|
+
);
|
|
6548
|
+
knownIds.add(recordId);
|
|
6549
|
+
yield* recordHalt(hit("compaction:after-canonical-append"));
|
|
6550
|
+
}),
|
|
6558
6551
|
};
|
|
6559
6552
|
|
|
6560
6553
|
/** Digest of one declared call's canonical encoded parameters (the original normalized wire). */
|
|
@@ -6803,37 +6796,34 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6803
6796
|
* so the next Turn's response commit makes it model-visible canonically — exactly the
|
|
6804
6797
|
* prompt-coverage rule recovery relies on.
|
|
6805
6798
|
*/
|
|
6806
|
-
const renderJoinedInput = (
|
|
6807
|
-
|
|
6808
|
-
messageAdmission,
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
messageAdmission,
|
|
6814
|
-
).pipe(
|
|
6815
|
-
Effect.mapError(() =>
|
|
6816
|
-
AgentInputError.make({ message: "Invalid worker completion message" }),
|
|
6817
|
-
),
|
|
6818
|
-
);
|
|
6819
|
-
const inputPrompt = agent.definition.inputPrompt;
|
|
6820
|
-
|
|
6821
|
-
if (inputPrompt === undefined) {
|
|
6822
|
-
return yield* renderInputPrompt(undefined, encodedInput, encodedInput);
|
|
6823
|
-
}
|
|
6824
|
-
|
|
6825
|
-
const decodedInput = yield* Schema.decodeEffect(agent.definition.input)(
|
|
6826
|
-
encodedInput,
|
|
6799
|
+
const renderJoinedInput = Effect.fnUntraced(function* (
|
|
6800
|
+
encodedInput: UserInputRecorded["input"],
|
|
6801
|
+
messageAdmission: UserInputRecorded["messageAdmission"],
|
|
6802
|
+
) {
|
|
6803
|
+
if (Schema.is(FrameworkMessage)(messageAdmission))
|
|
6804
|
+
return yield* Schema.encodeEffect(Schema.fromJsonString(FrameworkMessage))(
|
|
6805
|
+
messageAdmission,
|
|
6827
6806
|
).pipe(
|
|
6828
|
-
Effect.mapError((
|
|
6829
|
-
|
|
6830
|
-
message: cause.message,
|
|
6831
|
-
}),
|
|
6807
|
+
Effect.mapError(() =>
|
|
6808
|
+
AgentInputError.make({ message: "Invalid worker completion message" }),
|
|
6832
6809
|
),
|
|
6833
6810
|
);
|
|
6811
|
+
const inputPrompt = agent.definition.inputPrompt;
|
|
6834
6812
|
|
|
6835
|
-
|
|
6836
|
-
|
|
6813
|
+
if (inputPrompt === undefined) {
|
|
6814
|
+
return yield* renderInputPrompt(undefined, encodedInput, encodedInput);
|
|
6815
|
+
}
|
|
6816
|
+
|
|
6817
|
+
const decodedInput = yield* Schema.decodeEffect(agent.definition.input)(encodedInput).pipe(
|
|
6818
|
+
Effect.mapError((cause) =>
|
|
6819
|
+
AgentInputDecodeError.make({
|
|
6820
|
+
message: cause.message,
|
|
6821
|
+
}),
|
|
6822
|
+
),
|
|
6823
|
+
);
|
|
6824
|
+
|
|
6825
|
+
return yield* renderInputPrompt(inputPrompt, decodedInput, encodedInput);
|
|
6826
|
+
});
|
|
6837
6827
|
|
|
6838
6828
|
// Claims are authority, wakes are hints. A cancelled waiter retains every claim
|
|
6839
6829
|
// for the seam drain; it never appends input while an old response can still commit.
|
|
@@ -6892,7 +6882,9 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6892
6882
|
: { messageAdmission: snapshot.submission.messageAdmission }),
|
|
6893
6883
|
};
|
|
6894
6884
|
|
|
6895
|
-
const rendered = yield* Effect.result(
|
|
6885
|
+
const rendered = yield* Effect.result(
|
|
6886
|
+
renderJoinedInput(input.input, input.messageAdmission),
|
|
6887
|
+
);
|
|
6896
6888
|
|
|
6897
6889
|
if (Result.isFailure(rendered)) {
|
|
6898
6890
|
// A rejected prompt and its suffix retain their own Runs in queue order.
|
|
@@ -6932,118 +6924,117 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
6932
6924
|
Agent.DefinitionRequirements<(typeof agent)["definition"]>
|
|
6933
6925
|
> = {
|
|
6934
6926
|
awaitJoin,
|
|
6935
|
-
drain: (policy)
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
const limit = policy === "one" ? 1 : MAX_JOIN_DRAIN;
|
|
6927
|
+
drain: Effect.fnUntraced(function* (policy) {
|
|
6928
|
+
const joinedInputs = yield* recordHalt(
|
|
6929
|
+
Effect.gen(function* () {
|
|
6930
|
+
const limit = policy === "one" ? 1 : MAX_JOIN_DRAIN;
|
|
6940
6931
|
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6932
|
+
const joinedInputs: Array<
|
|
6933
|
+
Pick<UserInputRecorded, "input" | "messageAdmission"> & {
|
|
6934
|
+
readonly rendered?: Prompt.RawInput;
|
|
6935
|
+
}
|
|
6936
|
+
> = [];
|
|
6946
6937
|
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6938
|
+
if (joinBacklog === undefined) {
|
|
6939
|
+
const hostSnapshot = yield* ledger.loadRecoverySnapshot(
|
|
6940
|
+
RecoverySnapshotRequest.make({ submissionId }),
|
|
6941
|
+
);
|
|
6951
6942
|
|
|
6952
|
-
|
|
6943
|
+
joinBacklog = hostSnapshot.joins;
|
|
6944
|
+
}
|
|
6945
|
+
// These inputs were already consumed by an earlier attempt. Restore the
|
|
6946
|
+
// entire uncovered prompt; only fresh claims are subject to the drain bound.
|
|
6947
|
+
for (const join of joinBacklog) {
|
|
6948
|
+
const joinId = join.submissionId;
|
|
6949
|
+
|
|
6950
|
+
if (deliveredJoinInputs.has(joinId)) continue;
|
|
6951
|
+
if (join.state !== "joining" && join.state !== "joined") continue;
|
|
6952
|
+
const existing = joinedInputEnvelopes.get(joinId);
|
|
6953
|
+
|
|
6954
|
+
if (existing === undefined) continue;
|
|
6955
|
+
if (join.state === "joining") {
|
|
6956
|
+
// Canonical input without its joined marker (crash between the append and
|
|
6957
|
+
// `markJoined`): repair the marker from history before reattaching.
|
|
6958
|
+
yield* session.markJoined(joinId, {
|
|
6959
|
+
recordId: existing.record.recordId,
|
|
6960
|
+
sequence: existing.sequence,
|
|
6961
|
+
});
|
|
6953
6962
|
}
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
if (join.state !== "joining" && join.state !== "joined") continue;
|
|
6961
|
-
const existing = joinedInputEnvelopes.get(joinId);
|
|
6962
|
-
|
|
6963
|
-
if (existing === undefined) continue;
|
|
6964
|
-
if (join.state === "joining") {
|
|
6965
|
-
// Canonical input without its joined marker (crash between the append and
|
|
6966
|
-
// `markJoined`): repair the marker from history before reattaching.
|
|
6967
|
-
yield* session.markJoined(joinId, {
|
|
6968
|
-
recordId: existing.record.recordId,
|
|
6969
|
-
sequence: existing.sequence,
|
|
6970
|
-
});
|
|
6971
|
-
}
|
|
6972
|
-
deliveredJoinInputs.add(joinId);
|
|
6973
|
-
if (
|
|
6974
|
-
lastHostResponseSequence !== undefined &&
|
|
6975
|
-
lastHostResponseSequence > existing.sequence
|
|
6976
|
-
) {
|
|
6977
|
-
continue;
|
|
6978
|
-
}
|
|
6979
|
-
const payload = existing.record.payload;
|
|
6980
|
-
|
|
6981
|
-
if (payload._tag !== "UserInputRecorded") continue;
|
|
6982
|
-
joinedInputs.push(payload);
|
|
6963
|
+
deliveredJoinInputs.add(joinId);
|
|
6964
|
+
if (
|
|
6965
|
+
lastHostResponseSequence !== undefined &&
|
|
6966
|
+
lastHostResponseSequence > existing.sequence
|
|
6967
|
+
) {
|
|
6968
|
+
continue;
|
|
6983
6969
|
}
|
|
6984
|
-
const
|
|
6985
|
-
|
|
6986
|
-
pendingJoinClaims.splice(0, claims.length);
|
|
6987
|
-
for (const { claim, input: payload, rendered } of claims) {
|
|
6988
|
-
const recordId = submissionInputRecordId(claim.submissionId);
|
|
6989
|
-
let sequence: CanonicalSequence;
|
|
6990
|
-
const existing = joinedInputEnvelopes.get(claim.submissionId);
|
|
6991
|
-
|
|
6992
|
-
if (existing !== undefined) {
|
|
6993
|
-
// Defensive reattach: the exact record is already canonical, so only the
|
|
6994
|
-
// marker and the delivery remain (DUR-016 — never a duplicate append).
|
|
6995
|
-
sequence = existing.sequence;
|
|
6996
|
-
} else {
|
|
6997
|
-
const envelope = yield* makeEnvelope(
|
|
6998
|
-
recordId,
|
|
6999
|
-
UserInputRecorded.make({
|
|
7000
|
-
submissionId: claim.submissionId,
|
|
7001
|
-
kind: "steering",
|
|
7002
|
-
runId,
|
|
7003
|
-
input: claim.inputPayload,
|
|
7004
|
-
...(payload.messageAdmission === undefined
|
|
7005
|
-
? {}
|
|
7006
|
-
: { messageAdmission: payload.messageAdmission }),
|
|
7007
|
-
}),
|
|
7008
|
-
);
|
|
6970
|
+
const payload = existing.record.payload;
|
|
7009
6971
|
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
6972
|
+
if (payload._tag !== "UserInputRecorded") continue;
|
|
6973
|
+
joinedInputs.push(payload);
|
|
6974
|
+
}
|
|
6975
|
+
const claims = yield* prepareInputs(limit);
|
|
6976
|
+
|
|
6977
|
+
pendingJoinClaims.splice(0, claims.length);
|
|
6978
|
+
for (const { claim, input: payload, rendered } of claims) {
|
|
6979
|
+
const recordId = submissionInputRecordId(claim.submissionId);
|
|
6980
|
+
let sequence: CanonicalSequence;
|
|
6981
|
+
const existing = joinedInputEnvelopes.get(claim.submissionId);
|
|
6982
|
+
|
|
6983
|
+
if (existing !== undefined) {
|
|
6984
|
+
// Defensive reattach: the exact record is already canonical, so only the
|
|
6985
|
+
// marker and the delivery remain (DUR-016 — never a duplicate append).
|
|
6986
|
+
sequence = existing.sequence;
|
|
6987
|
+
} else {
|
|
6988
|
+
const envelope = yield* makeEnvelope(
|
|
6989
|
+
recordId,
|
|
6990
|
+
UserInputRecorded.make({
|
|
6991
|
+
submissionId: claim.submissionId,
|
|
6992
|
+
kind: "steering",
|
|
6993
|
+
runId,
|
|
6994
|
+
input: claim.inputPayload,
|
|
6995
|
+
...(payload.messageAdmission === undefined
|
|
6996
|
+
? {}
|
|
6997
|
+
: { messageAdmission: payload.messageAdmission }),
|
|
6998
|
+
}),
|
|
6999
|
+
);
|
|
7018
7000
|
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7001
|
+
const result = yield* appendBatch(
|
|
7002
|
+
ctx,
|
|
7003
|
+
CanonicalBatch.make({
|
|
7004
|
+
batchId: submissionInputBatchId(claim.submissionId),
|
|
7005
|
+
producerId: config.producerId,
|
|
7006
|
+
records: [envelope],
|
|
7007
|
+
}),
|
|
7008
|
+
);
|
|
7009
|
+
|
|
7010
|
+
sequence = result.firstSequence;
|
|
7011
|
+
knownIds.add(recordId);
|
|
7012
|
+
yield* hit("join:after-canonical-append");
|
|
7029
7013
|
}
|
|
7014
|
+
yield* session.markJoined(claim.submissionId, { recordId, sequence });
|
|
7015
|
+
deliveredJoinInputs.add(claim.submissionId);
|
|
7016
|
+
joinedInputs.push({
|
|
7017
|
+
...payload,
|
|
7018
|
+
rendered,
|
|
7019
|
+
});
|
|
7020
|
+
}
|
|
7030
7021
|
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7022
|
+
return joinedInputs;
|
|
7023
|
+
}),
|
|
7024
|
+
);
|
|
7034
7025
|
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7026
|
+
return yield* Effect.forEach(joinedInputs, (joinedInput) =>
|
|
7027
|
+
(joinedInput.rendered === undefined
|
|
7028
|
+
? renderJoinedInput(joinedInput.input, joinedInput.messageAdmission)
|
|
7029
|
+
: Effect.succeed(joinedInput.rendered)
|
|
7030
|
+
).pipe(
|
|
7031
|
+
Effect.map((input): RunInputCommand => ({
|
|
7032
|
+
kind: "steering",
|
|
7033
|
+
input,
|
|
7034
|
+
})),
|
|
7035
|
+
),
|
|
7036
|
+
);
|
|
7037
|
+
}),
|
|
7047
7038
|
};
|
|
7048
7039
|
|
|
7049
7040
|
/**
|
|
@@ -7726,50 +7717,49 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
7726
7717
|
},
|
|
7727
7718
|
}),
|
|
7728
7719
|
...(preparedContext === undefined ? {} : { context: preparedContext }),
|
|
7729
|
-
beforeTurn: ()
|
|
7730
|
-
|
|
7720
|
+
beforeTurn: Effect.fnUntraced(function* () {
|
|
7721
|
+
if (
|
|
7722
|
+
yieldAfter !== undefined &&
|
|
7723
|
+
(yield* Clock.currentTimeMillis) >= DateTime.toEpochMillis(yieldAfter)
|
|
7724
|
+
) {
|
|
7725
|
+
yield* Deferred.succeed(yieldSignal, undefined);
|
|
7726
|
+
|
|
7727
|
+
// The successful signal wins the outer race and closes the execution Scope;
|
|
7728
|
+
// no synthetic engine RunFailed event or terminal Settlement is produced.
|
|
7729
|
+
return yield* Effect.never;
|
|
7730
|
+
}
|
|
7731
|
+
if (submissionScheduling.yieldTo !== undefined && (yield* Ref.get(turnCounter)) > 0) {
|
|
7732
|
+
const candidate = yield* recordHalt(
|
|
7733
|
+
eligibleThreadHead(submission.threadId, submission.queueSequence),
|
|
7734
|
+
);
|
|
7735
|
+
|
|
7731
7736
|
if (
|
|
7732
|
-
|
|
7733
|
-
(
|
|
7737
|
+
Option.isSome(candidate) &&
|
|
7738
|
+
(candidate.value.state === "ready" || candidate.value.state === "input-applied")
|
|
7734
7739
|
) {
|
|
7735
|
-
yield*
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
if (submissionScheduling.yieldTo !== undefined && (yield* Ref.get(turnCounter)) > 0) {
|
|
7742
|
-
const candidate = yield* recordHalt(
|
|
7743
|
-
eligibleThreadHead(submission.threadId, submission.queueSequence),
|
|
7740
|
+
const next = yield* recordHalt(
|
|
7741
|
+
ledger.lookup(
|
|
7742
|
+
SubmissionLookupById.make({
|
|
7743
|
+
submissionId: candidate.value.submissionId,
|
|
7744
|
+
}),
|
|
7745
|
+
),
|
|
7744
7746
|
);
|
|
7745
7747
|
|
|
7746
7748
|
if (
|
|
7747
|
-
Option.isSome(
|
|
7748
|
-
|
|
7749
|
+
Option.isSome(next) &&
|
|
7750
|
+
next.value.agentId === submission.agentId &&
|
|
7751
|
+
(next.value.state === "ready" || next.value.state === "input-applied") &&
|
|
7752
|
+
(yield* recordHalt(
|
|
7753
|
+
submissionScheduling.yieldTo({ active: submission, next: next.value }),
|
|
7754
|
+
))
|
|
7749
7755
|
) {
|
|
7750
|
-
|
|
7751
|
-
ledger.lookup(
|
|
7752
|
-
SubmissionLookupById.make({
|
|
7753
|
-
submissionId: candidate.value.submissionId,
|
|
7754
|
-
}),
|
|
7755
|
-
),
|
|
7756
|
-
);
|
|
7756
|
+
yield* Deferred.succeed(yieldSignal, next.value.submissionId);
|
|
7757
7757
|
|
|
7758
|
-
|
|
7759
|
-
Option.isSome(next) &&
|
|
7760
|
-
next.value.agentId === submission.agentId &&
|
|
7761
|
-
(next.value.state === "ready" || next.value.state === "input-applied") &&
|
|
7762
|
-
(yield* recordHalt(
|
|
7763
|
-
submissionScheduling.yieldTo({ active: submission, next: next.value }),
|
|
7764
|
-
))
|
|
7765
|
-
) {
|
|
7766
|
-
yield* Deferred.succeed(yieldSignal, next.value.submissionId);
|
|
7767
|
-
|
|
7768
|
-
return yield* Effect.never;
|
|
7769
|
-
}
|
|
7758
|
+
return yield* Effect.never;
|
|
7770
7759
|
}
|
|
7771
7760
|
}
|
|
7772
|
-
}
|
|
7761
|
+
}
|
|
7762
|
+
}),
|
|
7773
7763
|
...(runContextPreparation.transientContext === undefined
|
|
7774
7764
|
? {}
|
|
7775
7765
|
: { transientContext: runContextPreparation.transientContext }),
|
|
@@ -8112,7 +8102,8 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8112
8102
|
};
|
|
8113
8103
|
|
|
8114
8104
|
return completed;
|
|
8115
|
-
}
|
|
8105
|
+
},
|
|
8106
|
+
);
|
|
8116
8107
|
|
|
8117
8108
|
/**
|
|
8118
8109
|
* One ownership period over the claimed lane head. The step order mirrors the pure recovery
|
|
@@ -8121,43 +8112,44 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8121
8112
|
* (Unknown Outcomes, or a durable approval suspension) — no settlement occurs and the
|
|
8122
8113
|
* obligation stays owed.
|
|
8123
8114
|
*/
|
|
8124
|
-
const runAttempt =
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
Tools extends Record<string, Tool.Any>,
|
|
8129
|
-
Provider,
|
|
8130
|
-
ModelProvides,
|
|
8131
|
-
ModelRequires,
|
|
8132
|
-
InstructionError = InstructionErrorOf<Instructions, InputSchema["Type"]>,
|
|
8133
|
-
InstructionRequirements = InstructionRequirementsOf<Instructions, InputSchema["Type"]>,
|
|
8134
|
-
RunDispositionValue extends
|
|
8135
|
-
| RunDispositionDeclaration<OutputSchema["Type"], Schema.Top>
|
|
8136
|
-
| undefined = undefined,
|
|
8137
|
-
InputPromptValue extends InputPromptSource<InputSchema["Type"], unknown, unknown> | undefined =
|
|
8138
|
-
undefined,
|
|
8139
|
-
UpdatesSchema extends Schema.Top | undefined = undefined,
|
|
8140
|
-
>(
|
|
8141
|
-
registeredAgent: RuntimeBinding<
|
|
8142
|
-
InputSchema,
|
|
8143
|
-
OutputSchema,
|
|
8115
|
+
const runAttempt = Effect.fnUntraced(
|
|
8116
|
+
function* <
|
|
8117
|
+
InputSchema extends Schema.Top,
|
|
8118
|
+
OutputSchema extends Schema.Top,
|
|
8144
8119
|
Instructions,
|
|
8145
|
-
Tools,
|
|
8120
|
+
Tools extends Record<string, Tool.Any>,
|
|
8146
8121
|
Provider,
|
|
8147
8122
|
ModelProvides,
|
|
8148
8123
|
ModelRequires,
|
|
8149
|
-
InstructionError,
|
|
8150
|
-
InstructionRequirements,
|
|
8151
|
-
RunDispositionValue
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8124
|
+
InstructionError = InstructionErrorOf<Instructions, InputSchema["Type"]>,
|
|
8125
|
+
InstructionRequirements = InstructionRequirementsOf<Instructions, InputSchema["Type"]>,
|
|
8126
|
+
RunDispositionValue extends
|
|
8127
|
+
| RunDispositionDeclaration<OutputSchema["Type"], Schema.Top>
|
|
8128
|
+
| undefined = undefined,
|
|
8129
|
+
InputPromptValue extends
|
|
8130
|
+
| InputPromptSource<InputSchema["Type"], unknown, unknown>
|
|
8131
|
+
| undefined = undefined,
|
|
8132
|
+
UpdatesSchema extends Schema.Top | undefined = undefined,
|
|
8133
|
+
>(
|
|
8134
|
+
registeredAgent: RuntimeBinding<
|
|
8135
|
+
InputSchema,
|
|
8136
|
+
OutputSchema,
|
|
8137
|
+
Instructions,
|
|
8138
|
+
Tools,
|
|
8139
|
+
Provider,
|
|
8140
|
+
ModelProvides,
|
|
8141
|
+
ModelRequires,
|
|
8142
|
+
InstructionError,
|
|
8143
|
+
InstructionRequirements,
|
|
8144
|
+
RunDispositionValue,
|
|
8145
|
+
InputPromptValue,
|
|
8146
|
+
UpdatesSchema
|
|
8147
|
+
>,
|
|
8148
|
+
session: RunStorageSession,
|
|
8149
|
+
resumeAfterRetention: () => void,
|
|
8150
|
+
onHandoff: (nextSubmissionId: SubmissionId) => void,
|
|
8151
|
+
yieldAfter?: DateTime.Utc,
|
|
8152
|
+
) {
|
|
8161
8153
|
// Recheck ownership outside the disposable cache's failure recovery.
|
|
8162
8154
|
yield* session.checkActive;
|
|
8163
8155
|
|
|
@@ -8273,9 +8265,8 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8273
8265
|
return metadata;
|
|
8274
8266
|
};
|
|
8275
8267
|
|
|
8276
|
-
let records: ReadonlyArray<CanonicalRecordEnvelope> =
|
|
8277
|
-
initialView.
|
|
8278
|
-
);
|
|
8268
|
+
let records: ReadonlyArray<CanonicalRecordEnvelope> =
|
|
8269
|
+
initialView.records.filter(collectControl);
|
|
8279
8270
|
|
|
8280
8271
|
// The append-only prefix remains valid for this Attempt. Retain only this Run's control
|
|
8281
8272
|
// evidence and validate each newly visible suffix against its own captured tail.
|
|
@@ -8382,6 +8373,8 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8382
8373
|
submission,
|
|
8383
8374
|
Duration.toMillis(agent.definition.policy.maxDuration),
|
|
8384
8375
|
yield* refreshControl(),
|
|
8376
|
+
// Applying the input cannot change the Run start captured by this Attempt's owner.
|
|
8377
|
+
initialView.operational,
|
|
8385
8378
|
).pipe(Effect.provideService(CurrentRunWriter, ctx));
|
|
8386
8379
|
|
|
8387
8380
|
const savedRunTiming = start.timing;
|
|
@@ -8625,7 +8618,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8625
8618
|
let canonical: Stream.Stream<
|
|
8626
8619
|
JournalRecordEnvelope,
|
|
8627
8620
|
ThreadStoreError | ThreadNotMaterialized | RunJournalError
|
|
8628
|
-
> = view.
|
|
8621
|
+
> = Stream.fromIterable(view.records);
|
|
8629
8622
|
|
|
8630
8623
|
let initialJournal: InitialJournalSource | undefined;
|
|
8631
8624
|
|
|
@@ -8885,7 +8878,9 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8885
8878
|
|
|
8886
8879
|
return Option.some(settlement);
|
|
8887
8880
|
}
|
|
8888
|
-
}
|
|
8881
|
+
},
|
|
8882
|
+
(effect) => effect.pipe(Effect.scoped),
|
|
8883
|
+
);
|
|
8889
8884
|
|
|
8890
8885
|
/** A missing current binding leaves both roots and children owed, with their claims released. */
|
|
8891
8886
|
type CapturedWorkerBinding = Effect.Success<ReturnType<typeof makeLegacyWorkerBinding>>;
|
|
@@ -9094,7 +9089,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
9094
9089
|
}
|
|
9095
9090
|
}).pipe((body) => withProcessing(threadId, body));
|
|
9096
9091
|
|
|
9097
|
-
const processThreadImpl = <
|
|
9092
|
+
const processThreadImpl = Effect.fnUntraced(function* <
|
|
9098
9093
|
InputSchema extends Schema.Top,
|
|
9099
9094
|
OutputSchema extends Schema.Top,
|
|
9100
9095
|
Instructions,
|
|
@@ -9126,26 +9121,25 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
9126
9121
|
UpdatesSchema
|
|
9127
9122
|
>,
|
|
9128
9123
|
threadId: ThreadId,
|
|
9129
|
-
)
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
});
|
|
9124
|
+
) {
|
|
9125
|
+
// The legacy single-binding worker is a singleton resolver (plan §1.7): identity-exact —
|
|
9126
|
+
// a claimed head with a different Agent never runs against this binding (the latent P4
|
|
9127
|
+
// gap) — and digest-transparent, because this call site registers no digest authority.
|
|
9128
|
+
const binding = yield* makeLegacyWorkerBinding(agent);
|
|
9129
|
+
|
|
9130
|
+
return yield* drainThread(
|
|
9131
|
+
(submission) =>
|
|
9132
|
+
submission.agentId === binding.agentId
|
|
9133
|
+
? Effect.succeed(binding)
|
|
9134
|
+
: Effect.fail(
|
|
9135
|
+
BindingUnavailable.make({
|
|
9136
|
+
agentId: submission.agentId,
|
|
9137
|
+
message: `This worker is bound to Agent ${binding.agentId}; the claimed head belongs to Agent ${submission.agentId} (SUB-023)`,
|
|
9138
|
+
}),
|
|
9139
|
+
),
|
|
9140
|
+
threadId,
|
|
9141
|
+
);
|
|
9142
|
+
});
|
|
9149
9143
|
|
|
9150
9144
|
const processThreadResolvedImpl = (
|
|
9151
9145
|
threadId: ThreadId,
|
|
@@ -10057,9 +10051,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
10057
10051
|
const hostId = snapshot.hostSubmissionId;
|
|
10058
10052
|
const hostView = yield* recoveryView(submission.threadId, history.throughSequence, [hostId]);
|
|
10059
10053
|
|
|
10060
|
-
const hostRecords =
|
|
10061
|
-
hostView.canonical.pipe(Stream.filter(controlRecords([hostId]))),
|
|
10062
|
-
);
|
|
10054
|
+
const hostRecords = hostView.records.filter(controlRecords([hostId]));
|
|
10063
10055
|
|
|
10064
10056
|
const merged = new Map(history.records.map((entry) => [entry.sequence, entry]));
|
|
10065
10057
|
|
|
@@ -11248,14 +11240,8 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
11248
11240
|
}
|
|
11249
11241
|
if (snapshot.value.state !== "settled") return Option.none();
|
|
11250
11242
|
|
|
11251
|
-
// Finalization replay reads the canonical outcome without
|
|
11252
|
-
|
|
11253
|
-
SettlementFinalization.make({
|
|
11254
|
-
submissionId: receipt.submissionId,
|
|
11255
|
-
settlementId: submissionSettlementId(receipt.submissionId),
|
|
11256
|
-
}),
|
|
11257
|
-
);
|
|
11258
|
-
|
|
11243
|
+
// Finalization replay reads the canonical outcome for adapters without finalized
|
|
11244
|
+
// metadata. Native projections already retain the first settledAt and exact record.
|
|
11259
11245
|
const canonical = yield* getRecord({
|
|
11260
11246
|
threadId: receipt.threadId,
|
|
11261
11247
|
recordId: submissionSettlementRecordId(receipt.submissionId),
|
|
@@ -11278,6 +11264,40 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
11278
11264
|
}
|
|
11279
11265
|
|
|
11280
11266
|
const record = yield* settlementPayloadFromRecord(canonical.value.record, receipt.submissionId);
|
|
11267
|
+
const finalized = snapshot.value;
|
|
11268
|
+
|
|
11269
|
+
const retainedFinalization =
|
|
11270
|
+
finalized.settledAt !== undefined &&
|
|
11271
|
+
finalized.settledRecordId !== undefined &&
|
|
11272
|
+
finalized.settledOutcome !== undefined;
|
|
11273
|
+
|
|
11274
|
+
if (
|
|
11275
|
+
retainedFinalization &&
|
|
11276
|
+
(finalized.settledRecordId !== canonical.value.record.recordId ||
|
|
11277
|
+
finalized.settledOutcome !== record.outcome ||
|
|
11278
|
+
canonical.value.batchId !== submissionSettlementBatchId(receipt.submissionId))
|
|
11279
|
+
) {
|
|
11280
|
+
return yield* LedgerError.make({
|
|
11281
|
+
operation: "awaitSettlement",
|
|
11282
|
+
message: "Settled projection disagrees with its canonical Settlement",
|
|
11283
|
+
});
|
|
11284
|
+
}
|
|
11285
|
+
|
|
11286
|
+
const settlement = retainedFinalization
|
|
11287
|
+
? Settlement.make({
|
|
11288
|
+
submissionId: receipt.submissionId,
|
|
11289
|
+
settlementId: record.settlementId,
|
|
11290
|
+
receiptId: record.receiptId,
|
|
11291
|
+
outcome: record.outcome,
|
|
11292
|
+
...(record.outcome === "failed" ? { failure: record.result } : {}),
|
|
11293
|
+
settledAt: finalized.settledAt,
|
|
11294
|
+
})
|
|
11295
|
+
: yield* ledger.finalizeSettlement(
|
|
11296
|
+
SettlementFinalization.make({
|
|
11297
|
+
submissionId: receipt.submissionId,
|
|
11298
|
+
settlementId: submissionSettlementId(receipt.submissionId),
|
|
11299
|
+
}),
|
|
11300
|
+
);
|
|
11281
11301
|
|
|
11282
11302
|
if (
|
|
11283
11303
|
record.receiptId !== receipt.receiptId ||
|