@yielded/agent 0.1.0-beta.181 → 0.1.0-beta.183
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-NvXFPDIM.d.mts → Admin-BgCHCGSl.d.mts} +8 -8
- package/dist/{AgentRuntime-Dx5u_FJD.d.mts → AgentRuntime-DhRchFzv.d.mts} +7 -4
- package/dist/{AgentRuntime-BAExRlgu.mjs → AgentRuntime-ILtyHuQG.mjs} +61 -45
- package/dist/AgentRuntime-ILtyHuQG.mjs.map +1 -0
- package/dist/{Digest-DjUgS5PG.d.mts → Digest-1iVcDLVm.d.mts} +2 -2
- package/dist/{Digest-ft4ku9pj.mjs → Digest-CzLJcsWv.mjs} +2 -2
- package/dist/{Digest-ft4ku9pj.mjs.map → Digest-CzLJcsWv.mjs.map} +1 -1
- package/dist/{DurableAgentRuntime-HH2muFrT.mjs → DurableAgentRuntime-Cj263rW9.mjs} +27 -57
- package/dist/DurableAgentRuntime-Cj263rW9.mjs.map +1 -0
- package/dist/{EventSource-DNyaWmyQ.d.mts → EventSource-CaA6RAtC.d.mts} +3 -3
- package/dist/InMemory.d.mts +1 -1
- package/dist/{MessageDelivery-CLzWJImC.d.mts → MessageDelivery-rlLpakO8.d.mts} +43 -43
- package/dist/{PreparedInputAdmission-BQ9UCLFS.d.mts → PreparedInputAdmission-DjbWz2lW.d.mts} +4 -4
- package/dist/{RecordFormat-BNiLpe43.d.mts → RecordFormat-CjMl0uu8.d.mts} +2 -2
- package/dist/{Records-BTnGRdcf.d.mts → Records-BP67Yz6n.d.mts} +20 -8
- package/dist/{Records-CZRedCE7.mjs → Records-bbGVHprv.mjs} +14 -10
- package/dist/Records-bbGVHprv.mjs.map +1 -0
- package/dist/{RunContinuation-CL0wBsQE.d.mts → RunContinuation-CIJRN_vC.d.mts} +5 -4
- package/dist/{RunContinuation-BF95Ncv2.mjs → RunContinuation-DJ6kkbQG.mjs} +22 -58
- package/dist/RunContinuation-DJ6kkbQG.mjs.map +1 -0
- package/dist/{RunEvent-C5jVQZ6K.d.mts → RunEvent-Bh1p4zAO.d.mts} +2 -2
- package/dist/{RunJournal-oJLo-pjS.mjs → RunJournal-DQr2dUgg.mjs} +4 -7
- package/dist/RunJournal-DQr2dUgg.mjs.map +1 -0
- package/dist/{RunOptions-BANtohGk.d.mts → RunOptions-aBHR-Eqm.d.mts} +6 -3
- package/dist/{RunStorage-DlfvMfHM.mjs → RunStorage-DblN-cmM.mjs} +2 -2
- package/dist/{RunStorage-DlfvMfHM.mjs.map → RunStorage-DblN-cmM.mjs.map} +1 -1
- package/dist/{Schedule-CDgTz0vj.d.mts → Schedule-CVLtl5rP.d.mts} +2 -2
- package/dist/{Scheduling-BebkRVc2.mjs → Scheduling-B6l0lWdr.mjs} +3 -3
- package/dist/{Scheduling-BebkRVc2.mjs.map → Scheduling-B6l0lWdr.mjs.map} +1 -1
- package/dist/{Subagent-D68fe7mr.mjs → Subagent-Bm842K7J.mjs} +43 -17
- package/dist/Subagent-Bm842K7J.mjs.map +1 -0
- package/dist/{Subagent-5ulnV6An.d.mts → Subagent-CWWmA1UQ.d.mts} +17 -5
- package/dist/{Subscription-D2yn6Eo3.d.mts → Subscription-BRsNy0TA.d.mts} +4 -4
- package/dist/{SubscriptionInput-Cog4x7Rd.d.mts → SubscriptionInput-ClCaW_kX.d.mts} +3 -3
- package/dist/{ThreadHistory-KPPBJLJb.d.mts → ThreadHistory-ajQhqZDY.d.mts} +2 -2
- package/dist/{ThreadImport-BoTfjjrz.mjs → ThreadImport-CkPAxXU5.mjs} +7 -7
- package/dist/{ThreadImport-BoTfjjrz.mjs.map → ThreadImport-CkPAxXU5.mjs.map} +1 -1
- package/dist/{ThreadImport-em89zmM-.d.mts → ThreadImport-DtRNoHIr.d.mts} +5 -5
- package/dist/{ThreadStore-D2rqtt7k.mjs → ThreadStore-C_ofHc7h.mjs} +4 -4
- package/dist/{ThreadStore-D2rqtt7k.mjs.map → ThreadStore-C_ofHc7h.mjs.map} +1 -1
- package/dist/{ThreadTransfer-BFolkpEp.mjs → ThreadTransfer-C_TRuo_9.mjs} +4 -4
- package/dist/{ThreadTransfer-BFolkpEp.mjs.map → ThreadTransfer-C_TRuo_9.mjs.map} +1 -1
- package/dist/{WorkerAdmission-DrxDrLII.mjs → WorkerAdmission-9Ka3edXj.mjs} +5 -5
- package/dist/{WorkerAdmission-DrxDrLII.mjs.map → WorkerAdmission-9Ka3edXj.mjs.map} +1 -1
- package/dist/{agent-registration-BovXT8jc.mjs → agent-registration-7kp1dHT0.mjs} +4 -4
- package/dist/{agent-registration-BovXT8jc.mjs.map → agent-registration-7kp1dHT0.mjs.map} +1 -1
- package/dist/capabilities/Commands.d.mts +1 -1
- package/dist/capabilities/Redaction.d.mts +1 -1
- package/dist/capabilities/RunHooks.d.mts +1 -1
- package/dist/capabilities/Subagent.d.mts +1 -1
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/capabilities/SubagentReservations.d.mts +4 -1
- package/dist/capabilities/SubagentReservations.mjs +4 -1
- package/dist/capabilities/SubagentReservations.mjs.map +1 -1
- package/dist/core/RunEvent.d.mts +1 -1
- package/dist/core/RunEvent.mjs +1 -1
- package/dist/core/RunEvent.mjs.map +1 -1
- package/dist/durable/ActivityStore.d.mts +1 -1
- package/dist/durable/ActivityStore.mjs +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/Admin.mjs +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 +3 -3
- package/dist/durable/CommittedActivity.mjs +3 -3
- package/dist/durable/Digest.d.mts +1 -1
- 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 +1 -1
- package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
- package/dist/durable/LifecyclePublication.d.mts +1 -1
- package/dist/durable/LifecyclePublication.mjs +2 -2
- package/dist/durable/MessageDelivery.d.mts +1 -1
- package/dist/durable/MessageDelivery.mjs +2 -2
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +42 -42
- package/dist/durable/MessageDeliveryStoreConformance.mjs +2 -2
- package/dist/durable/PersistentHistory.d.mts +2 -2
- package/dist/durable/PersistentHistory.mjs +4 -4
- package/dist/durable/PreparedInputAdmission.d.mts +1 -1
- package/dist/durable/RecordFormat.d.mts +1 -1
- package/dist/durable/RecordFormat.mjs +1 -1
- package/dist/durable/Records.d.mts +1 -1
- package/dist/durable/Records.mjs +1 -1
- package/dist/durable/Recovery.d.mts +1 -1
- package/dist/durable/Recovery.mjs +1 -1
- package/dist/durable/RunContinuation.d.mts +3 -3
- package/dist/durable/RunContinuation.mjs +3 -3
- 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/Schedule.d.mts +1 -1
- package/dist/durable/Schedule.mjs +1 -1
- package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
- package/dist/durable/ScheduleStoreConformance.mjs +1 -1
- package/dist/durable/ScheduleTransition.d.mts +1 -1
- package/dist/durable/ScheduleTransition.mjs +1 -1
- package/dist/durable/Scheduling.d.mts +3 -3
- package/dist/durable/Scheduling.mjs +1 -1
- package/dist/durable/SettlementPublisher.d.mts +1 -1
- package/dist/durable/SettlementPublisher.mjs +3 -3
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedger.mjs +2 -2
- package/dist/durable/SubmissionLedgerConformance.d.mts +2 -2
- package/dist/durable/SubmissionLedgerConformance.mjs +5 -5
- package/dist/durable/SubmissionStatus.d.mts +1 -1
- package/dist/durable/Subscription.d.mts +1 -1
- package/dist/durable/Subscription.mjs +1 -1
- package/dist/durable/SubscriptionInput.d.mts +1 -1
- package/dist/durable/SubscriptionInput.mjs +2 -2
- package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
- package/dist/durable/SubscriptionStoreConformance.mjs +1 -1
- package/dist/durable/SubscriptionTools.d.mts +4 -4
- package/dist/durable/SubscriptionTransition.d.mts +1 -1
- package/dist/durable/SubscriptionTransition.mjs +1 -1
- package/dist/durable/Subscriptions.d.mts +6 -6
- package/dist/durable/Subscriptions.mjs +2 -2
- package/dist/durable/ThreadArchiveRange.d.mts +1 -1
- package/dist/durable/ThreadArchiveRange.mjs +1 -1
- package/dist/durable/ThreadContextHistory.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.mjs +2 -2
- package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
- package/dist/durable/ThreadContextHistoryProjection.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/ThreadProjection.d.mts +1 -1
- package/dist/durable/ThreadProjection.mjs +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 +2 -2
- package/dist/durable/ThreadStore.mjs +2 -2
- package/dist/durable/ThreadStoreConformance.d.mts +2 -2
- package/dist/durable/ThreadStoreConformance.mjs +4 -4
- package/dist/durable/ThreadTransfer.d.mts +2 -2
- package/dist/durable/ThreadTransfer.mjs +1 -1
- package/dist/durable/ThreadWork.d.mts +1 -1
- package/dist/durable/ThreadWork.mjs +5 -5
- package/dist/durable/ToolReconciler.mjs +1 -1
- package/dist/durable/WorkerAdmission.d.mts +2 -2
- 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/RunOptions.d.mts +1 -1
- package/dist/engine/RunOptions.mjs.map +1 -1
- package/dist/engine/ThreadHistory.d.mts +1 -1
- package/dist/index.d.mts +17 -17
- package/dist/index.mjs +12 -12
- package/dist/{run-context-reader-kpO9xhP2.d.mts → run-context-reader-DEU4REfD.d.mts} +3 -3
- package/package.json +1 -1
- package/src/capabilities/Subagent.ts +83 -28
- package/src/capabilities/SubagentReservations.ts +4 -1
- package/src/capabilities/internal/subagent-contract.ts +23 -3
- package/src/core/RunEvent.ts +1 -1
- package/src/durable/DurableAgentRuntime.ts +64 -14
- package/src/durable/Records.ts +21 -15
- package/src/durable/RunContinuation.ts +64 -125
- package/src/durable/RunJournal.ts +4 -12
- package/src/durable/internal/history-prompt.ts +10 -4
- package/src/durable/internal/initial-context.ts +1 -1
- package/src/durable/internal/prompt-history-cache.ts +8 -63
- package/src/engine/RunOptions.ts +4 -1
- package/src/engine/internal/agent-runtime.ts +422 -387
- package/dist/AgentRuntime-BAExRlgu.mjs.map +0 -1
- package/dist/DurableAgentRuntime-HH2muFrT.mjs.map +0 -1
- package/dist/Records-CZRedCE7.mjs.map +0 -1
- package/dist/RunContinuation-BF95Ncv2.mjs.map +0 -1
- package/dist/RunJournal-oJLo-pjS.mjs.map +0 -1
- package/dist/Subagent-D68fe7mr.mjs.map +0 -1
- package/dist/json-BlJVQZxN.mjs +0 -15
- package/dist/json-BlJVQZxN.mjs.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Context, DateTime, Effect, Option, Result, Schema, Semaphore, Stream } from "effect";
|
|
2
|
-
import { Prompt } from "effect/ai";
|
|
3
2
|
|
|
4
3
|
import { AgentPersistenceCapacityError } from "../core/AgentError.ts";
|
|
5
4
|
import type { RunId, SubmissionId, ThreadId } from "../core/Identifiers.ts";
|
|
@@ -118,45 +117,6 @@ const isExecutionProgressRecord = (
|
|
|
118
117
|
): record is RecordEnvelope & { readonly payload: RunContinuation } =>
|
|
119
118
|
record.payload._tag === "RunContinuation";
|
|
120
119
|
|
|
121
|
-
const decodeResponsePrompt = Schema.decodeUnknownEffect(Prompt.Prompt);
|
|
122
|
-
// The decoded Prompt stays private. Progress and capacity are recomputed on every invocation.
|
|
123
|
-
const responsePrompts = new WeakMap<ModelResponseRecorded, Prompt.Prompt>();
|
|
124
|
-
|
|
125
|
-
/** Cache eligibility only: freezing does not make accessors or custom iterators immutable. */
|
|
126
|
-
const isFrozenJsonData = (input: Schema.Json): boolean => {
|
|
127
|
-
const pending: Array<unknown> = [input];
|
|
128
|
-
const seen = new WeakSet<object>();
|
|
129
|
-
|
|
130
|
-
while (pending.length > 0) {
|
|
131
|
-
const value = pending.pop();
|
|
132
|
-
|
|
133
|
-
if (value === null) continue;
|
|
134
|
-
if (typeof value !== "object") {
|
|
135
|
-
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean")
|
|
136
|
-
return false;
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
if (seen.has(value)) continue;
|
|
140
|
-
seen.add(value);
|
|
141
|
-
const prototype = Object.getPrototypeOf(value);
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
!Object.isFrozen(value) ||
|
|
145
|
-
(prototype !== null && prototype !== Object.prototype && prototype !== Array.prototype)
|
|
146
|
-
)
|
|
147
|
-
return false;
|
|
148
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
149
|
-
if (typeof key !== "string") return false;
|
|
150
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
151
|
-
|
|
152
|
-
if (descriptor === undefined || !("value" in descriptor)) return false;
|
|
153
|
-
pending.push(descriptor.value);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return true;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
120
|
const validateBatchShape = Schema.decodeUnknownSync(
|
|
161
121
|
Schema.Struct({
|
|
162
122
|
batchId: CanonicalBatch.fields.batchId,
|
|
@@ -165,11 +125,6 @@ const validateBatchShape = Schema.decodeUnknownSync(
|
|
|
165
125
|
}),
|
|
166
126
|
);
|
|
167
127
|
|
|
168
|
-
const ContinuationBytes = Schema.Struct({
|
|
169
|
-
turnBytes: RunContinuation.fields.turnBytes,
|
|
170
|
-
terminalBytes: RunContinuation.fields.terminalBytes,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
128
|
const decodeExecutionFrontier = Schema.decodeUnknownEffect(
|
|
174
129
|
Schema.Struct({
|
|
175
130
|
canonicalRecords: ExecutionCheckpoint.fields.canonicalRecords,
|
|
@@ -714,7 +669,6 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
714
669
|
let terminal = previous?.continuation.terminal;
|
|
715
670
|
let position = previous?.continuation.position ?? "starting";
|
|
716
671
|
let response = previous?.response;
|
|
717
|
-
let responsePrompt: Prompt.Prompt | undefined;
|
|
718
672
|
let results = new Map(previous?.results);
|
|
719
673
|
let childResults = new Map(previous?.childResults);
|
|
720
674
|
let completionBytes = previous?.completionBytes;
|
|
@@ -756,31 +710,10 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
756
710
|
if (payload.turn !== accounting.committedTurns + 1)
|
|
757
711
|
return yield* failure("Canonical Turn progress must advance once");
|
|
758
712
|
|
|
759
|
-
const
|
|
760
|
-
const retainedPrompt = responsePrompts.get(payload);
|
|
761
|
-
|
|
762
|
-
const messages =
|
|
763
|
-
retainedPrompt ??
|
|
764
|
-
(yield* decodeResponsePrompt(promptInput).pipe(
|
|
765
|
-
Effect.mapError((cause) => failure("Invalid model evidence", cause)),
|
|
766
|
-
));
|
|
767
|
-
|
|
768
|
-
if (retainedPrompt === undefined) {
|
|
769
|
-
const property = Object.getOwnPropertyDescriptor(payload, "messages");
|
|
770
|
-
|
|
771
|
-
if (
|
|
772
|
-
Object.isFrozen(payload) &&
|
|
773
|
-
property !== undefined &&
|
|
774
|
-
"value" in property &&
|
|
775
|
-
property.value === promptInput &&
|
|
776
|
-
isFrozenJsonData(promptInput)
|
|
777
|
-
)
|
|
778
|
-
responsePrompts.set(payload, messages);
|
|
779
|
-
}
|
|
780
|
-
responsePrompt = messages;
|
|
713
|
+
const messages = payload.messages;
|
|
781
714
|
|
|
782
715
|
const calls = messages.content.flatMap((message) =>
|
|
783
|
-
message.role === "assistant"
|
|
716
|
+
message.role === "assistant" && typeof message.content !== "string"
|
|
784
717
|
? message.content.filter((part) => part.type === "tool-call")
|
|
785
718
|
: [],
|
|
786
719
|
);
|
|
@@ -910,15 +843,8 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
910
843
|
response.turn > accounting.accountedToolTurn &&
|
|
911
844
|
response.toolOperations.every((operation) => results.has(operation.toolCallId))
|
|
912
845
|
) {
|
|
913
|
-
const messages
|
|
914
|
-
|
|
915
|
-
responsePrompts.get(response) ??
|
|
916
|
-
(yield* decodeResponsePrompt(response.messages).pipe(
|
|
917
|
-
Effect.mapError((cause) => failure("Invalid batch evidence", cause)),
|
|
918
|
-
));
|
|
919
|
-
|
|
920
|
-
const parts = messages.content.flatMap((message) =>
|
|
921
|
-
message.role === "assistant" ? message.content : [],
|
|
846
|
+
const parts = response.messages.content.flatMap((message) =>
|
|
847
|
+
message.role === "assistant" && typeof message.content !== "string" ? message.content : [],
|
|
922
848
|
);
|
|
923
849
|
|
|
924
850
|
for (const call of parts) {
|
|
@@ -931,7 +857,8 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
931
857
|
if (
|
|
932
858
|
result === undefined ||
|
|
933
859
|
!("isFailure" in result) ||
|
|
934
|
-
|
|
860
|
+
// Only canonical application settlements carry budget-rejection authority.
|
|
861
|
+
(!call.providerExecuted && "budgetRejected" in result && result.budgetRejected === true)
|
|
935
862
|
)
|
|
936
863
|
continue;
|
|
937
864
|
accounting.consecutiveToolFailures = result.isFailure
|
|
@@ -1497,29 +1424,30 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1497
1424
|
terminalUsageBytes,
|
|
1498
1425
|
} = next;
|
|
1499
1426
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1427
|
+
// Facts and prior state are already checked. Validate the complete candidate at
|
|
1428
|
+
// record capture, after byte accounting; preflight has its own boundary below.
|
|
1429
|
+
let continuation = RunContinuation.make(
|
|
1430
|
+
{
|
|
1431
|
+
version: 1,
|
|
1432
|
+
runId,
|
|
1433
|
+
submissionId,
|
|
1434
|
+
revision: (previous?.continuation.revision ?? 0) + 1,
|
|
1435
|
+
recordCount: (previous?.continuation.recordCount ?? originalCount) + facts.length,
|
|
1436
|
+
recordBytes: (previous?.continuation.recordBytes ?? initialBytes) + factBytes,
|
|
1437
|
+
turn,
|
|
1438
|
+
turnBytes: turnBase,
|
|
1439
|
+
terminalUsageBytes,
|
|
1440
|
+
terminalBytes: next.terminalBytes,
|
|
1441
|
+
terminalRecords: next.terminalRecords,
|
|
1442
|
+
originalInput,
|
|
1443
|
+
...(savedContext === undefined ? {} : { savedContext }),
|
|
1444
|
+
...(latestResponse === undefined ? {} : { latestResponse }),
|
|
1445
|
+
...(terminal === undefined ? {} : { terminal }),
|
|
1446
|
+
lastFact: EvidenceReference.make({ recordId: last.recordId }),
|
|
1447
|
+
position,
|
|
1448
|
+
accounting,
|
|
1449
|
+
},
|
|
1450
|
+
{ disableChecks: true },
|
|
1523
1451
|
);
|
|
1524
1452
|
|
|
1525
1453
|
const header = {
|
|
@@ -1530,7 +1458,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1530
1458
|
deploymentId: last.deploymentId,
|
|
1531
1459
|
};
|
|
1532
1460
|
|
|
1533
|
-
//
|
|
1461
|
+
// Continuation fields are JSON; only the envelope DateTime needs encoding.
|
|
1534
1462
|
// Key order does not change byte width. Measure without capturing a provisional record,
|
|
1535
1463
|
// then compare against the final Schema encoding before accepting its accounting.
|
|
1536
1464
|
const provisional = {
|
|
@@ -1563,18 +1491,9 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1563
1491
|
terminalBytes = nextTerminalBytes;
|
|
1564
1492
|
}
|
|
1565
1493
|
|
|
1566
|
-
|
|
1567
|
-
turnBytes,
|
|
1568
|
-
terminalBytes,
|
|
1569
|
-
}).pipe(
|
|
1570
|
-
Effect.mapError(() =>
|
|
1571
|
-
capacityFailure("Turn exceeds its incremental canonical byte budget"),
|
|
1572
|
-
),
|
|
1573
|
-
);
|
|
1574
|
-
|
|
1575
|
-
// Every other field was checked above; byte accounting changes only these counters.
|
|
1494
|
+
// Byte accounting changes only these counters; the full candidate is checked below.
|
|
1576
1495
|
continuation = RunContinuation.make(
|
|
1577
|
-
{ ...continuation,
|
|
1496
|
+
{ ...continuation, turnBytes, terminalBytes },
|
|
1578
1497
|
{ disableChecks: true },
|
|
1579
1498
|
);
|
|
1580
1499
|
|
|
@@ -1595,8 +1514,13 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1595
1514
|
previous?.checkpoint !== undefined &&
|
|
1596
1515
|
facts.every(({ payload }) => payload._tag === "ModelResponseRecorded")
|
|
1597
1516
|
) {
|
|
1598
|
-
//
|
|
1599
|
-
//
|
|
1517
|
+
// Preflight does not capture a record. Check its complete payload before
|
|
1518
|
+
// dispatch; a commit receives the same proof from record capture below.
|
|
1519
|
+
continuation = yield* RunContinuation.makeEffect({ ...continuation }).pipe(
|
|
1520
|
+
Effect.mapError(() =>
|
|
1521
|
+
capacityFailure("Canonical continuation exceeds its protocol bounds"),
|
|
1522
|
+
),
|
|
1523
|
+
);
|
|
1600
1524
|
yield* decodeExecutionFrontier({
|
|
1601
1525
|
canonicalRecords,
|
|
1602
1526
|
throughSequence: after + ownedRecords.filter((fact) => !isOperationalRecord(fact)).length,
|
|
@@ -1623,7 +1547,11 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1623
1547
|
|
|
1624
1548
|
const record = yield* Effect.fromResult(captureRecord(proposedRecord)).pipe(
|
|
1625
1549
|
Effect.map((record) => record.canonical),
|
|
1626
|
-
Effect.mapError((cause) =>
|
|
1550
|
+
Effect.mapError((cause) =>
|
|
1551
|
+
Schema.isSchemaError(cause.cause)
|
|
1552
|
+
? capacityFailure("Canonical continuation exceeds its protocol bounds")
|
|
1553
|
+
: failure("Cannot capture canonical progress facts", cause),
|
|
1554
|
+
),
|
|
1627
1555
|
);
|
|
1628
1556
|
|
|
1629
1557
|
if (!isExecutionProgressRecord(record))
|
|
@@ -1679,7 +1607,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1679
1607
|
);
|
|
1680
1608
|
|
|
1681
1609
|
const state = {
|
|
1682
|
-
continuation,
|
|
1610
|
+
continuation: record.payload,
|
|
1683
1611
|
record,
|
|
1684
1612
|
checkpoint,
|
|
1685
1613
|
...(response === undefined ? {} : { response }),
|
|
@@ -1803,13 +1731,14 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1803
1731
|
if (first === undefined)
|
|
1804
1732
|
return yield* failure("Settlement must publish a retained terminal fact");
|
|
1805
1733
|
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1734
|
+
// prepare retains captured records within the validated batch bound.
|
|
1735
|
+
// The explicit first element proves this retained batch is still non-empty.
|
|
1736
|
+
const terminalBatch = CanonicalBatch.make(
|
|
1737
|
+
{
|
|
1738
|
+
...prepared.batch,
|
|
1739
|
+
records: [first, ...prepared.batch.records.slice(1)],
|
|
1740
|
+
},
|
|
1741
|
+
{ disableChecks: true },
|
|
1813
1742
|
);
|
|
1814
1743
|
|
|
1815
1744
|
const result = yield* publisher.publishSettlement(terminalBatch, prepared.executions).pipe(
|
|
@@ -1840,6 +1769,15 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1840
1769
|
const publish = (batch: CanonicalBatch) =>
|
|
1841
1770
|
captureFacts(batch).pipe(Effect.flatMap(publishCaptured));
|
|
1842
1771
|
|
|
1772
|
+
const preflight = (batch: CanonicalBatch) =>
|
|
1773
|
+
gate.withPermits(1)(
|
|
1774
|
+
Effect.gen(function* () {
|
|
1775
|
+
const owned = yield* captureFacts(batch);
|
|
1776
|
+
|
|
1777
|
+
yield* prepare(owned, yield* tail, "preflight");
|
|
1778
|
+
}),
|
|
1779
|
+
);
|
|
1780
|
+
|
|
1843
1781
|
const reserve = (runId: RunId, probe: CanonicalBatch, bytes: number) =>
|
|
1844
1782
|
gate.withPermits(1)(
|
|
1845
1783
|
Effect.gen(function* () {
|
|
@@ -1952,6 +1890,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1952
1890
|
return {
|
|
1953
1891
|
commit,
|
|
1954
1892
|
publish,
|
|
1893
|
+
preflight,
|
|
1955
1894
|
reserve,
|
|
1956
1895
|
defer,
|
|
1957
1896
|
check,
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
ToolCallId,
|
|
9
9
|
type SubmissionId,
|
|
10
10
|
} from "../core/Identifiers.ts";
|
|
11
|
-
import { copyJson } from "../core/internal/json.ts";
|
|
12
11
|
import { type ExhaustedLimit } from "../core/RunEvent.ts";
|
|
13
12
|
import { RunPolicyUsage } from "../core/RunPolicyUsage.ts";
|
|
14
13
|
import { type Selection, type Snapshot } from "../core/ToolExposure.ts";
|
|
@@ -37,7 +36,7 @@ import {
|
|
|
37
36
|
CanonicalBatch,
|
|
38
37
|
ModelResponseRecorded,
|
|
39
38
|
MAX_PERSISTED_JSON_BYTES,
|
|
40
|
-
PersistedJson,
|
|
39
|
+
type PersistedJson,
|
|
41
40
|
RecordEnvelope,
|
|
42
41
|
RunCompleted,
|
|
43
42
|
ToolCallSettled,
|
|
@@ -1697,7 +1696,6 @@ export interface TurnCommitInput {
|
|
|
1697
1696
|
| undefined;
|
|
1698
1697
|
}
|
|
1699
1698
|
|
|
1700
|
-
const decodePersistedJson = Schema.decodeUnknownEffect(PersistedJson);
|
|
1701
1699
|
const decodeModelResponse = Schema.decodeUnknownEffect(ModelResponseRecorded);
|
|
1702
1700
|
const decodeToolSettled = Schema.decodeUnknownEffect(ToolCallSettled);
|
|
1703
1701
|
const encodePrompt = Schema.encodeEffect(Prompt.Prompt);
|
|
@@ -1739,14 +1737,8 @@ const modelResponseRecord = Effect.fnUntraced(function* (
|
|
|
1739
1737
|
Effect.mapErrorEager((cause) => journalError("Turn Prompt messages failed to encode", cause)),
|
|
1740
1738
|
);
|
|
1741
1739
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
Effect.mapErrorEager((cause) =>
|
|
1745
|
-
journalError("Turn Prompt messages exceed canonical persistence bounds", cause),
|
|
1746
|
-
),
|
|
1747
|
-
);
|
|
1748
|
-
|
|
1749
|
-
// Validate the detached messages and usage together; no mutable caller data is trusted.
|
|
1740
|
+
// Validate messages and usage together. The progress writer captures the complete record
|
|
1741
|
+
// before acquiring its mutation gate; a separate JSON copy here adds no ownership proof.
|
|
1750
1742
|
const modelUsage = input.usage?.modelUsage;
|
|
1751
1743
|
|
|
1752
1744
|
const payload = yield* decodeModelResponse({
|
|
@@ -1761,7 +1753,7 @@ const modelResponseRecord = Effect.fnUntraced(function* (
|
|
|
1761
1753
|
runId: input.runId,
|
|
1762
1754
|
turnId: input.turnId,
|
|
1763
1755
|
turn: input.turn,
|
|
1764
|
-
messages,
|
|
1756
|
+
messages: encodedMessages,
|
|
1765
1757
|
...(runScopedPrefixLength === undefined ? {} : { runScopedPrefixLength }),
|
|
1766
1758
|
...(modelUsage === undefined ? {} : { modelUsage }),
|
|
1767
1759
|
...(input.unobservedModelCalls === undefined || input.unobservedModelCalls === 0
|
|
@@ -23,7 +23,8 @@ function restorePart(part: Prompt.PartEncoded): Prompt.Part {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
// The encoded-message Schema has validated this value; constructors restore brands/defaults.
|
|
27
|
+
export const restoreHistoryMessage = (message: Prompt.MessageEncoded): Prompt.Message => {
|
|
27
28
|
switch (message.role) {
|
|
28
29
|
case "system":
|
|
29
30
|
return Prompt.makeMessage("system", message);
|
|
@@ -52,14 +53,19 @@ const restoreMessage = (message: Prompt.MessageEncoded): Prompt.Message => {
|
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
|
-
*
|
|
56
|
+
* Share the upstream encoded-message boundary between canonical history and checkpoint reads.
|
|
56
57
|
* The canonical codec remains authoritative at append, import, recovery and explicit verification.
|
|
57
58
|
*/
|
|
58
|
-
export const
|
|
59
|
+
export const HistoryMessage = Schema.toEncoded(Prompt.Message);
|
|
60
|
+
|
|
61
|
+
export const HistoryPrompt = Schema.Struct({
|
|
62
|
+
content: Schema.Array(HistoryMessage),
|
|
63
|
+
}).pipe(
|
|
59
64
|
Schema.decodeTo(
|
|
60
65
|
Schema.toType(Prompt.Prompt),
|
|
61
66
|
SchemaTransformation.transformEffect({
|
|
62
|
-
decode: (input) =>
|
|
67
|
+
decode: (input) =>
|
|
68
|
+
Effect.succeed(Prompt.fromMessages(input.content.map(restoreHistoryMessage))),
|
|
63
69
|
encode: SchemaParser.encodeEffect(Prompt.Prompt),
|
|
64
70
|
}),
|
|
65
71
|
),
|
|
@@ -145,7 +145,7 @@ export const initialContext = Effect.fnUntraced(function* (original: InitialCont
|
|
|
145
145
|
)
|
|
146
146
|
return yield* invalid("Late Tool result differs from its original declaration identity");
|
|
147
147
|
|
|
148
|
-
const prompt = yield* Schema.
|
|
148
|
+
const prompt = yield* Schema.decodeEffect(Prompt.Prompt)(response.messages).pipe(
|
|
149
149
|
Effect.mapError(() => invalid("Late Tool declaration messages are malformed")),
|
|
150
150
|
);
|
|
151
151
|
|
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
ThreadStore,
|
|
24
24
|
ThreadTailRequest,
|
|
25
25
|
} from "../ThreadStore.ts";
|
|
26
|
+
import { HistoryMessage, restoreHistoryMessage } from "./history-prompt.ts";
|
|
26
27
|
import type { InitialContextInput } from "./initial-context.ts";
|
|
27
|
-
import type
|
|
28
|
+
import { makeJournalMetadata, type JournalRecordEnvelope } from "./journal-metadata.ts";
|
|
28
29
|
import { promptJsonFootprint } from "./prompt-footprint.ts";
|
|
29
30
|
import { captureRecord } from "./record-encoding.ts";
|
|
30
31
|
import { digestRunHistory } from "./run-context.ts";
|
|
@@ -47,9 +48,7 @@ const decodeCommittedPromptRecord = Schema.decodeUnknownSync(PromptRecord);
|
|
|
47
48
|
const decodeEncodedPrompt = Schema.decodeUnknownEffect(
|
|
48
49
|
Schema.suspend(() =>
|
|
49
50
|
Schema.Struct({
|
|
50
|
-
content: Schema.Array(Schema.
|
|
51
|
-
Schema.isMaxLength(MAX_ENTRIES),
|
|
52
|
-
),
|
|
51
|
+
content: Schema.Array(HistoryMessage).check(Schema.isMaxLength(MAX_ENTRIES)),
|
|
53
52
|
}),
|
|
54
53
|
),
|
|
55
54
|
);
|
|
@@ -64,64 +63,6 @@ const decodePrompt = Schema.decodeUnknownEffect(
|
|
|
64
63
|
),
|
|
65
64
|
);
|
|
66
65
|
|
|
67
|
-
// Inputs have crossed Effect's encoded-message Schema boundary. Native constructors
|
|
68
|
-
// supply only the brands and defaults; Effect still owns every message and part type.
|
|
69
|
-
function hydratePart(part: Prompt.UserMessagePartEncoded): Prompt.UserMessagePart;
|
|
70
|
-
function hydratePart(part: Prompt.ToolMessagePartEncoded): Prompt.ToolMessagePart;
|
|
71
|
-
function hydratePart(part: Prompt.AssistantMessagePartEncoded): Prompt.AssistantMessagePart;
|
|
72
|
-
function hydratePart(part: Prompt.PartEncoded): Prompt.Part {
|
|
73
|
-
switch (part.type) {
|
|
74
|
-
case "text":
|
|
75
|
-
return Prompt.textPart(part);
|
|
76
|
-
case "reasoning":
|
|
77
|
-
return Prompt.reasoningPart(part);
|
|
78
|
-
case "file":
|
|
79
|
-
return Prompt.filePart(part);
|
|
80
|
-
case "tool-call":
|
|
81
|
-
// Unlike options, providerExecuted is required by Effect's constructors;
|
|
82
|
-
// only its Schema decoder supplies the false default.
|
|
83
|
-
return Prompt.toolCallPart({ ...part, providerExecuted: part.providerExecuted ?? false });
|
|
84
|
-
case "tool-result":
|
|
85
|
-
return Prompt.toolResultPart({ ...part, providerExecuted: part.providerExecuted ?? false });
|
|
86
|
-
case "tool-approval-request":
|
|
87
|
-
return Prompt.toolApprovalRequestPart(part);
|
|
88
|
-
case "tool-approval-response":
|
|
89
|
-
return Prompt.toolApprovalResponsePart(part);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return part satisfies never;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const hydrateMessage = (message: Prompt.MessageEncoded): Prompt.Message => {
|
|
96
|
-
switch (message.role) {
|
|
97
|
-
case "system":
|
|
98
|
-
return Prompt.systemMessage(message);
|
|
99
|
-
case "user":
|
|
100
|
-
return Prompt.userMessage({
|
|
101
|
-
...message,
|
|
102
|
-
content:
|
|
103
|
-
typeof message.content === "string"
|
|
104
|
-
? [Prompt.textPart({ text: message.content })]
|
|
105
|
-
: message.content.map((p) => hydratePart(p)),
|
|
106
|
-
});
|
|
107
|
-
case "assistant":
|
|
108
|
-
return Prompt.assistantMessage({
|
|
109
|
-
...message,
|
|
110
|
-
content:
|
|
111
|
-
typeof message.content === "string"
|
|
112
|
-
? [Prompt.textPart({ text: message.content })]
|
|
113
|
-
: message.content.map((p) => hydratePart(p)),
|
|
114
|
-
});
|
|
115
|
-
case "tool":
|
|
116
|
-
return Prompt.toolMessage({
|
|
117
|
-
...message,
|
|
118
|
-
content: message.content.map((p) => hydratePart(p)),
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return message satisfies never;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
66
|
export interface PromptHistory {
|
|
126
67
|
readonly prompt: Prompt.Prompt;
|
|
127
68
|
encoded: string | undefined;
|
|
@@ -171,7 +112,7 @@ export const decodeCheckpointPrefix = Effect.fnUntraced(function* (
|
|
|
171
112
|
if (bytes === undefined) return undefined;
|
|
172
113
|
|
|
173
114
|
const decoded = yield* decodeEncodedPrompt(value).pipe(
|
|
174
|
-
Effect.map((prompt) => ({ content: prompt.content.map(
|
|
115
|
+
Effect.map((prompt) => ({ content: prompt.content.map(restoreHistoryMessage) })),
|
|
175
116
|
// Keep the canonical codec as fallback for representations the encoded Schema rejects.
|
|
176
117
|
Effect.catch(() => decodePrompt(value)),
|
|
177
118
|
);
|
|
@@ -399,6 +340,7 @@ const readSuffix = Effect.fnUntraced(function* (
|
|
|
399
340
|
) {
|
|
400
341
|
const store = yield* ThreadStore;
|
|
401
342
|
const records: Array<JournalRecordEnvelope> = [];
|
|
343
|
+
const metadata = makeJournalMetadata(undefined);
|
|
402
344
|
let after = from;
|
|
403
345
|
let remaining = allowance;
|
|
404
346
|
let active: RunId | undefined;
|
|
@@ -461,6 +403,7 @@ const readSuffix = Effect.fnUntraced(function* (
|
|
|
461
403
|
if (footprint === undefined) return undefined;
|
|
462
404
|
remaining -= 32 * footprint;
|
|
463
405
|
records.push(entry);
|
|
406
|
+
metadata.add(entry);
|
|
464
407
|
after = entry.sequence;
|
|
465
408
|
}
|
|
466
409
|
if (page.length === 0) break;
|
|
@@ -474,6 +417,8 @@ const readSuffix = Effect.fnUntraced(function* (
|
|
|
474
417
|
(boundary) => {
|
|
475
418
|
if (boundary.incomplete) incomplete = true;
|
|
476
419
|
},
|
|
420
|
+
undefined,
|
|
421
|
+
metadata.finish(),
|
|
477
422
|
);
|
|
478
423
|
|
|
479
424
|
if (incomplete || delta.prompt.content.length > MAX_ENTRIES) return undefined;
|
package/src/engine/RunOptions.ts
CHANGED
|
@@ -688,10 +688,13 @@ export interface RunDurabilityHook<Error = never, Requirements = never> {
|
|
|
688
688
|
* `committed` accepts the supplied facts canonically. `deferred` is valid only for a Response
|
|
689
689
|
* with `defer: true`: validation and ownership succeeded, but no canonical acceptance occurred.
|
|
690
690
|
* The interpreter retains its response and inputs until the Settled commit is accepted.
|
|
691
|
+
* `capacity-refused` is valid only for a fresh Response rejected before any storage append or
|
|
692
|
+
* Tool work. The interpreter settles every application call as not dispatched, atomically with
|
|
693
|
+
* that response. A failed append or an already accepted response must never return this value.
|
|
691
694
|
*/
|
|
692
695
|
readonly commitTurn: (
|
|
693
696
|
commit: RunTurnCommit,
|
|
694
|
-
) => Effect.Effect<"committed" | "deferred", Error, Requirements>;
|
|
697
|
+
) => Effect.Effect<"committed" | "deferred" | "capacity-refused", Error, Requirements>;
|
|
695
698
|
/** Check the writer fence after approval/authorization and before handler permits; no write. */
|
|
696
699
|
readonly checkToolDispatch: Effect.Effect<void, Error, Requirements>;
|
|
697
700
|
readonly step: RunStepHook<Error, Requirements>;
|