@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
|
@@ -119,8 +119,8 @@ export const makeEventSource = Effect.fnUntraced(function* <
|
|
|
119
119
|
Effect.provideContext(services),
|
|
120
120
|
);
|
|
121
121
|
|
|
122
|
-
const parameters: EventSource["parameters"] = (
|
|
123
|
-
|
|
122
|
+
const parameters: EventSource["parameters"] = Effect.fnUntraced(
|
|
123
|
+
function* (value) {
|
|
124
124
|
yield* Schema.decodeUnknownEffect(PersistedJson)(value).pipe(Effect.mapError(invalid));
|
|
125
125
|
|
|
126
126
|
const decoded = yield* Schema.decodeUnknownEffect(options.parameters)(value).pipe(
|
|
@@ -131,10 +131,12 @@ export const makeEventSource = Effect.fnUntraced(function* <
|
|
|
131
131
|
parameters: yield* encode(options.parameters, decoded),
|
|
132
132
|
matchingKey: options.parameterKey(decoded),
|
|
133
133
|
};
|
|
134
|
-
}
|
|
134
|
+
},
|
|
135
|
+
(effect) => effect.pipe(Effect.scoped, Effect.provideContext(services)),
|
|
136
|
+
);
|
|
135
137
|
|
|
136
|
-
const matches: EventSource["matches"] = (
|
|
137
|
-
|
|
138
|
+
const matches: EventSource["matches"] = Effect.fnUntraced(
|
|
139
|
+
function* (event, subscription) {
|
|
138
140
|
const e = yield* Schema.decodeEffect(options.event)(event.payload).pipe(
|
|
139
141
|
Effect.mapError(invalid),
|
|
140
142
|
);
|
|
@@ -144,7 +146,9 @@ export const makeEventSource = Effect.fnUntraced(function* <
|
|
|
144
146
|
).pipe(Effect.mapError(invalid));
|
|
145
147
|
|
|
146
148
|
return options.matches(e, p);
|
|
147
|
-
}
|
|
149
|
+
},
|
|
150
|
+
(effect) => effect.pipe(Effect.scoped, Effect.provideContext(services)),
|
|
151
|
+
);
|
|
148
152
|
|
|
149
153
|
const reconcile = options.reconcile;
|
|
150
154
|
|
|
@@ -157,8 +161,8 @@ export const makeEventSource = Effect.fnUntraced(function* <
|
|
|
157
161
|
...(reconcile === undefined
|
|
158
162
|
? {}
|
|
159
163
|
: {
|
|
160
|
-
reconcile: (
|
|
161
|
-
|
|
164
|
+
reconcile: Effect.fnUntraced(
|
|
165
|
+
function* (subscription: SubscriptionRecord) {
|
|
162
166
|
const p = yield* Schema.decodeEffect(options.parameters)(
|
|
163
167
|
subscription.configuration.parameters,
|
|
164
168
|
).pipe(Effect.mapError(invalid));
|
|
@@ -166,7 +170,9 @@ export const makeEventSource = Effect.fnUntraced(function* <
|
|
|
166
170
|
const event = yield* reconcile(p);
|
|
167
171
|
|
|
168
172
|
return event === null ? null : yield* normalized(event);
|
|
169
|
-
}
|
|
173
|
+
},
|
|
174
|
+
(effect) => effect.pipe(Effect.scoped, Effect.provideContext(services)),
|
|
175
|
+
),
|
|
170
176
|
}),
|
|
171
177
|
};
|
|
172
178
|
});
|
|
@@ -45,7 +45,9 @@ export const decodeExportRecordJson = (
|
|
|
45
45
|
// Both codecs validate RecordJson before this getter; decode the supported view once.
|
|
46
46
|
const decodeView = SchemaGetter.transformEffect((value: RecordJson) =>
|
|
47
47
|
decodeRecord(value).pipe(
|
|
48
|
-
Effect.map((record) =>
|
|
48
|
+
Effect.map((record) =>
|
|
49
|
+
ExportedRecord.make({ ...record, wire: value }, { disableChecks: true }),
|
|
50
|
+
),
|
|
49
51
|
Effect.mapError((error) => error.issue),
|
|
50
52
|
),
|
|
51
53
|
);
|
|
@@ -104,8 +106,8 @@ export const ReadEnvelope = Schema.Struct({
|
|
|
104
106
|
record: ReadRecord,
|
|
105
107
|
}).pipe(
|
|
106
108
|
Schema.decodeTo(Schema.toType(CanonicalRecordEnvelope), {
|
|
107
|
-
decode: SchemaGetter.transform(
|
|
108
|
-
|
|
109
|
+
decode: SchemaGetter.transform((fields) =>
|
|
110
|
+
CanonicalRecordEnvelope.make(fields, { disableChecks: true }),
|
|
109
111
|
),
|
|
110
112
|
encode: SchemaGetter.transform((envelope) => envelope),
|
|
111
113
|
}),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Context,
|
|
1
|
+
import { Context, DateTime, Effect, Option, Result, Schema, Semaphore, Stream } from "effect";
|
|
2
2
|
import { Prompt } from "effect/ai";
|
|
3
3
|
|
|
4
4
|
import { AgentPersistenceCapacityError } from "../core/AgentError.ts";
|
|
5
5
|
import type { RunId, SubmissionId, ThreadId } from "../core/Identifiers.ts";
|
|
6
6
|
import { ToolCallId } from "../core/Identifiers.ts";
|
|
7
7
|
import { utf8ByteLength } from "../core/internal/utf8.ts";
|
|
8
|
-
import { summarizeModelUsage } from "../core/Usage.ts";
|
|
9
8
|
import { reference, resolveEvidence } from "./internal/evidence.ts";
|
|
9
|
+
import { continuationUsage } from "./internal/usage-totals.ts";
|
|
10
10
|
export { reference, resolveEvidence } from "./internal/evidence.ts";
|
|
11
11
|
import {
|
|
12
12
|
captureRecord,
|
|
@@ -119,6 +119,43 @@ const isExecutionProgressRecord = (
|
|
|
119
119
|
record.payload._tag === "RunContinuation";
|
|
120
120
|
|
|
121
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
|
+
};
|
|
122
159
|
|
|
123
160
|
const validateBatchHeader = Schema.decodeSync(
|
|
124
161
|
Schema.Struct({
|
|
@@ -136,39 +173,76 @@ const ContinuationBytes = Schema.Struct({
|
|
|
136
173
|
terminalBytes: RunContinuation.fields.terminalBytes,
|
|
137
174
|
});
|
|
138
175
|
|
|
176
|
+
const decodeExecutionFrontier = Schema.decodeUnknownEffect(
|
|
177
|
+
Schema.Struct({
|
|
178
|
+
canonicalRecords: ExecutionCheckpoint.fields.canonicalRecords,
|
|
179
|
+
throughSequence: ExecutionCheckpoint.fields.throughSequence,
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
|
|
139
183
|
/** One private snapshot for every retry; callers cannot change facts while awaiting the gate. */
|
|
140
184
|
const captureFacts = (batch: CommitBatch) =>
|
|
141
185
|
Effect.try({
|
|
142
|
-
try: () =>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
186
|
+
try: () =>
|
|
187
|
+
Result.gen(function* () {
|
|
188
|
+
const header = validateBatchHeader(batch);
|
|
189
|
+
|
|
190
|
+
validateBatchCount(batch.records);
|
|
191
|
+
const encodings = yield* Result.all(batch.records.map(captureRecord));
|
|
192
|
+
const records = encodings.map((record) => record.canonical);
|
|
193
|
+
|
|
194
|
+
return Object.freeze(
|
|
195
|
+
CanonicalBatch.make(
|
|
196
|
+
{ ...header, records: [records[0]!, ...records.slice(1)] },
|
|
197
|
+
{ disableChecks: true },
|
|
198
|
+
),
|
|
199
|
+
);
|
|
200
|
+
}),
|
|
155
201
|
catch: (cause) => failure("Cannot capture canonical progress facts", cause),
|
|
156
|
-
})
|
|
202
|
+
}).pipe(
|
|
203
|
+
Effect.flatMap(Effect.fromResult),
|
|
204
|
+
Effect.mapError((cause) =>
|
|
205
|
+
Schema.is(ThreadStoreError)(cause)
|
|
206
|
+
? cause
|
|
207
|
+
: failure("Cannot capture canonical progress facts", cause),
|
|
208
|
+
),
|
|
209
|
+
);
|
|
157
210
|
|
|
158
211
|
/** Exact UTF-8 wire accounting reuses the append's privately captured Schema encoding. */
|
|
159
|
-
export const canonicalRecordBytes = (record: RecordEnvelope): number =>
|
|
160
|
-
recordEncoding(record)
|
|
212
|
+
export const canonicalRecordBytes = (record: RecordEnvelope): number => {
|
|
213
|
+
const encoded = recordEncoding(record);
|
|
214
|
+
|
|
215
|
+
if (Result.isFailure(encoded)) {
|
|
216
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- Public synchronous byte-accounting validation must reject malformed records before returning a number.
|
|
217
|
+
throw encoded.failure.cause ?? new RangeError(encoded.failure.message);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return encoded.success.bytes;
|
|
221
|
+
};
|
|
161
222
|
|
|
162
223
|
export type { ProgressAppendRecord } from "./internal/record-encoding.ts";
|
|
163
224
|
|
|
164
225
|
/** Capture before acquiring the mutation owner; summaries never cross a wire boundary. */
|
|
165
226
|
export const prepareProgressAppend = (
|
|
166
227
|
records: ReadonlyArray<RecordEnvelope>,
|
|
167
|
-
): ReadonlyArray<ProgressAppendRecord> =>
|
|
168
|
-
|
|
228
|
+
): ReadonlyArray<ProgressAppendRecord> => {
|
|
229
|
+
const encodings = Result.all(records.map(captureRecord));
|
|
169
230
|
|
|
170
|
-
|
|
171
|
-
|
|
231
|
+
if (Result.isFailure(encodings)) {
|
|
232
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- Public synchronous progress construction must reject malformed records before acquiring a mutation owner.
|
|
233
|
+
throw encodings.failure.cause ?? new RangeError(encodings.failure.message);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return Object.freeze(encodings.success.map((record) => record.progress));
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const factUsageCharge = (facts: ReadonlyArray<RecordEnvelope>) =>
|
|
240
|
+
Effect.fromResult(Result.all(facts.map(recordEncoding))).pipe(
|
|
241
|
+
Effect.map((encodings) =>
|
|
242
|
+
encodings.reduce((bytes, record) => bytes + record.progress.terminalUsageBytes, 0),
|
|
243
|
+
),
|
|
244
|
+
Effect.mapError((cause) => failure("Cannot account canonical progress facts", cause)),
|
|
245
|
+
);
|
|
172
246
|
|
|
173
247
|
/** These values belong to the active Run, not its permanent conversation history. */
|
|
174
248
|
export const isOperationalRecord = ({ payload }: RecordEnvelope): boolean =>
|
|
@@ -663,10 +737,27 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
663
737
|
if (payload.turn !== accounting.committedTurns + 1)
|
|
664
738
|
return yield* failure("Canonical Turn progress must advance once");
|
|
665
739
|
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
740
|
+
const promptInput = payload.messages;
|
|
741
|
+
const retainedPrompt = responsePrompts.get(payload);
|
|
742
|
+
|
|
743
|
+
const messages =
|
|
744
|
+
retainedPrompt ??
|
|
745
|
+
(yield* decodeResponsePrompt(promptInput).pipe(
|
|
746
|
+
Effect.mapError((cause) => failure("Invalid model evidence", cause)),
|
|
747
|
+
));
|
|
669
748
|
|
|
749
|
+
if (retainedPrompt === undefined) {
|
|
750
|
+
const property = Object.getOwnPropertyDescriptor(payload, "messages");
|
|
751
|
+
|
|
752
|
+
if (
|
|
753
|
+
Object.isFrozen(payload) &&
|
|
754
|
+
property !== undefined &&
|
|
755
|
+
"value" in property &&
|
|
756
|
+
property.value === promptInput &&
|
|
757
|
+
isFrozenJsonData(promptInput)
|
|
758
|
+
)
|
|
759
|
+
responsePrompts.set(payload, messages);
|
|
760
|
+
}
|
|
670
761
|
responsePrompt = messages;
|
|
671
762
|
|
|
672
763
|
const calls = messages.content.flatMap((message) =>
|
|
@@ -678,18 +769,18 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
678
769
|
const summary =
|
|
679
770
|
payload.modelUsage === undefined
|
|
680
771
|
? undefined
|
|
681
|
-
: yield*
|
|
772
|
+
: yield* continuationUsage(payload.modelUsage).pipe(
|
|
682
773
|
Effect.mapError((cause) => failure("Invalid usage evidence", cause)),
|
|
683
774
|
);
|
|
684
775
|
|
|
685
776
|
accounting.committedTurns = payload.turn;
|
|
686
777
|
accounting.toolCalls += calls.length;
|
|
687
778
|
accounting.modelCalls += summary?.modelCalls ?? 1;
|
|
688
|
-
accounting.inputTokens += summary?.inputTokens
|
|
689
|
-
accounting.outputTokens += summary?.outputTokens
|
|
779
|
+
accounting.inputTokens += summary?.inputTokens ?? payload.inputTokens ?? 0;
|
|
780
|
+
accounting.outputTokens += summary?.outputTokens ?? payload.outputTokens ?? 0;
|
|
690
781
|
accounting.costMicrousd += summary?.costMicrousd ?? payload.costMicrousd ?? 0;
|
|
691
|
-
accounting.lastInputTokens = summary?.inputTokens
|
|
692
|
-
accounting.lastOutputTokens = summary?.outputTokens
|
|
782
|
+
accounting.lastInputTokens = summary?.inputTokens ?? payload.inputTokens ?? 0;
|
|
783
|
+
accounting.lastOutputTokens = summary?.outputTokens ?? payload.outputTokens ?? 0;
|
|
693
784
|
accounting.unobservedModelCalls += payload.unobservedModelCalls ?? 0;
|
|
694
785
|
latestResponse = yield* reference(fact);
|
|
695
786
|
response = payload;
|
|
@@ -754,14 +845,14 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
754
845
|
if (payload.restart !== (accounting.modelRestarts ?? 0) + 1)
|
|
755
846
|
return yield* failure("Model restart progress must advance once");
|
|
756
847
|
|
|
757
|
-
const summary = yield*
|
|
848
|
+
const summary = yield* continuationUsage(payload.modelUsage).pipe(
|
|
758
849
|
Effect.mapError((cause) => failure("Invalid cancelled model usage", cause)),
|
|
759
850
|
);
|
|
760
851
|
|
|
761
852
|
accounting.modelRestarts = payload.restart;
|
|
762
853
|
accounting.modelCalls += summary.modelCalls;
|
|
763
|
-
accounting.inputTokens += summary.inputTokens
|
|
764
|
-
accounting.outputTokens += summary.outputTokens
|
|
854
|
+
accounting.inputTokens += summary.inputTokens;
|
|
855
|
+
accounting.outputTokens += summary.outputTokens;
|
|
765
856
|
accounting.costMicrousd += summary.costMicrousd;
|
|
766
857
|
accounting.unobservedModelCalls += payload.unobservedModelCalls;
|
|
767
858
|
break;
|
|
@@ -802,6 +893,7 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
802
893
|
) {
|
|
803
894
|
const messages =
|
|
804
895
|
responsePrompt ??
|
|
896
|
+
responsePrompts.get(response) ??
|
|
805
897
|
(yield* decodeResponsePrompt(response.messages).pipe(
|
|
806
898
|
Effect.mapError((cause) => failure("Invalid batch evidence", cause)),
|
|
807
899
|
));
|
|
@@ -848,7 +940,7 @@ const advanceFacts = Effect.fnUntraced(function* (
|
|
|
848
940
|
(previous?.continuation.turn === turn ? previous.continuation.turnBytes : initialBytes) +
|
|
849
941
|
factBytes;
|
|
850
942
|
|
|
851
|
-
const usageCharge = factUsageCharge(facts);
|
|
943
|
+
const usageCharge = yield* factUsageCharge(facts);
|
|
852
944
|
const terminalUsageBytes = (previous?.continuation.terminalUsageBytes ?? 0) + usageCharge;
|
|
853
945
|
|
|
854
946
|
const closing = facts.filter(isTerminalBudgetFact);
|
|
@@ -951,7 +1043,6 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
951
1043
|
deploymentId: DeploymentId,
|
|
952
1044
|
) {
|
|
953
1045
|
const reader = yield* ThreadReader;
|
|
954
|
-
const crypto = yield* Crypto.Crypto;
|
|
955
1046
|
const gate = yield* Semaphore.make(1);
|
|
956
1047
|
const cached = new Map<RunId, ProgressState>();
|
|
957
1048
|
|
|
@@ -967,16 +1058,10 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
967
1058
|
|
|
968
1059
|
const stagedUsage = new Map<RunId, number>();
|
|
969
1060
|
|
|
970
|
-
const provide = <A, E>(effect: Effect.Effect<A, E, ThreadReader
|
|
971
|
-
|
|
972
|
-
Effect.provideService(ThreadReader, reader),
|
|
973
|
-
Effect.provideService(Crypto.Crypto, crypto),
|
|
974
|
-
);
|
|
975
|
-
|
|
976
|
-
const loadState = Effect.fnUntraced(function* (runId: RunId, after: CanonicalSequence) {
|
|
977
|
-
const retained = cached.get(runId);
|
|
1061
|
+
const provide = <A, E>(effect: Effect.Effect<A, E, ThreadReader>) =>
|
|
1062
|
+
Effect.provideService(effect, ThreadReader, reader);
|
|
978
1063
|
|
|
979
|
-
|
|
1064
|
+
const loadUncachedState = Effect.fnUntraced(function* (runId: RunId, after: CanonicalSequence) {
|
|
980
1065
|
const loaded = yield* provide(readContinuation(threadId, runId, after));
|
|
981
1066
|
|
|
982
1067
|
if (Option.isNone(loaded)) return undefined;
|
|
@@ -1095,11 +1180,21 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1095
1180
|
};
|
|
1096
1181
|
});
|
|
1097
1182
|
|
|
1098
|
-
const
|
|
1183
|
+
const loadState = (runId: RunId, after: CanonicalSequence) =>
|
|
1184
|
+
Effect.suspend(() => {
|
|
1185
|
+
const retained = cached.get(runId);
|
|
1186
|
+
|
|
1187
|
+
return retained === undefined ? loadUncachedState(runId, after) : Effect.succeed(retained);
|
|
1188
|
+
});
|
|
1189
|
+
|
|
1190
|
+
const checkFutureShapes = (
|
|
1191
|
+
state: ProgressState,
|
|
1192
|
+
cursorBytes?: number,
|
|
1193
|
+
): Effect.Effect<void, ThreadStoreError> => {
|
|
1099
1194
|
const progress = state.continuation;
|
|
1100
1195
|
|
|
1101
1196
|
if (progress.position === "settled") return Effect.void;
|
|
1102
|
-
const size = canonicalRecordBytes(state.record);
|
|
1197
|
+
const size = cursorBytes ?? canonicalRecordBytes(state.record);
|
|
1103
1198
|
const textBytes = (value: string) => utf8ByteLength(JSON.stringify(value));
|
|
1104
1199
|
const refBytes = (value: EvidenceReference) => utf8ByteLength(JSON.stringify(value));
|
|
1105
1200
|
|
|
@@ -1213,14 +1308,20 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1213
1308
|
return Effect.void;
|
|
1214
1309
|
};
|
|
1215
1310
|
|
|
1216
|
-
const prepare = Effect.fnUntraced(function* (
|
|
1311
|
+
const prepare = Effect.fnUntraced(function* (
|
|
1312
|
+
batch: CanonicalBatch,
|
|
1313
|
+
after: CanonicalSequence,
|
|
1314
|
+
mode: "commit" | "preflight" = "commit",
|
|
1315
|
+
) {
|
|
1217
1316
|
if (batch.records.some((record) => record.payload._tag === "RunContinuation"))
|
|
1218
1317
|
return yield* failure("A caller cannot supply interpreter progress to the progress writer");
|
|
1219
1318
|
|
|
1220
|
-
const ownedRecords = yield* Effect.
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1319
|
+
const ownedRecords = yield* Effect.fromResult(
|
|
1320
|
+
Result.all(batch.records.map(captureRecord)),
|
|
1321
|
+
).pipe(
|
|
1322
|
+
Effect.map((encodings) => encodings.map((record) => record.canonical)),
|
|
1323
|
+
Effect.mapError((cause) => failure("Cannot capture canonical progress facts", cause)),
|
|
1324
|
+
);
|
|
1224
1325
|
|
|
1225
1326
|
const groups = new Map<RunId, Array<RecordEnvelope>>();
|
|
1226
1327
|
|
|
@@ -1234,6 +1335,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1234
1335
|
}
|
|
1235
1336
|
const executions: Array<ExecutionUpdate> = [];
|
|
1236
1337
|
const accepted = new Map<RunId, ProgressState>();
|
|
1338
|
+
let executionCount = 0;
|
|
1237
1339
|
|
|
1238
1340
|
for (const [runId, facts] of groups) {
|
|
1239
1341
|
const previous = yield* loadState(runId, after);
|
|
@@ -1337,12 +1439,17 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1337
1439
|
|
|
1338
1440
|
if (payload._tag !== "SubmissionSettled" || payload.runId !== runId) continue;
|
|
1339
1441
|
|
|
1340
|
-
const retained =
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1442
|
+
const retained = yield* Effect.fromResult(
|
|
1443
|
+
captureRecord(
|
|
1444
|
+
RecordEnvelope.make({
|
|
1445
|
+
...fact,
|
|
1446
|
+
payload: { ...payload, historyRecordCount: canonicalRecords },
|
|
1447
|
+
}),
|
|
1448
|
+
),
|
|
1449
|
+
).pipe(
|
|
1450
|
+
Effect.map((record) => record.canonical),
|
|
1451
|
+
Effect.mapError((cause) => failure("Cannot capture canonical progress facts", cause)),
|
|
1452
|
+
);
|
|
1346
1453
|
|
|
1347
1454
|
facts[index] = retained;
|
|
1348
1455
|
ownedRecords[ownedRecords.indexOf(fact)] = retained;
|
|
@@ -1353,9 +1460,9 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1353
1460
|
? previous.continuation.originalInput
|
|
1354
1461
|
: original === undefined
|
|
1355
1462
|
? yield* failure("Run progress has no original input")
|
|
1356
|
-
: yield*
|
|
1463
|
+
: yield* reference(original);
|
|
1357
1464
|
|
|
1358
|
-
const next = yield*
|
|
1465
|
+
const next = yield* advanceFacts(previous, facts, submissionId, initialBytes);
|
|
1359
1466
|
|
|
1360
1467
|
const {
|
|
1361
1468
|
accounting,
|
|
@@ -1391,7 +1498,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1391
1498
|
...(savedContext === undefined ? {} : { savedContext }),
|
|
1392
1499
|
...(latestResponse === undefined ? {} : { latestResponse }),
|
|
1393
1500
|
...(terminal === undefined ? {} : { terminal }),
|
|
1394
|
-
lastFact: yield*
|
|
1501
|
+
lastFact: yield* reference(last),
|
|
1395
1502
|
position,
|
|
1396
1503
|
accounting,
|
|
1397
1504
|
}).pipe(
|
|
@@ -1451,23 +1558,63 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1451
1558
|
);
|
|
1452
1559
|
|
|
1453
1560
|
// Every other field was checked above; byte accounting changes only these counters.
|
|
1454
|
-
continuation =
|
|
1561
|
+
continuation = RunContinuation.make(
|
|
1455
1562
|
{ ...continuation, ...checkedBytes },
|
|
1456
1563
|
{ disableChecks: true },
|
|
1457
1564
|
);
|
|
1458
1565
|
|
|
1459
|
-
const
|
|
1460
|
-
|
|
1461
|
-
|
|
1566
|
+
const proposedRecord = RecordEnvelope.make(
|
|
1567
|
+
{ ...header, payload: continuation },
|
|
1568
|
+
{ disableChecks: true },
|
|
1569
|
+
);
|
|
1570
|
+
|
|
1571
|
+
const cursorBytes = turnBytes - turnBase;
|
|
1462
1572
|
|
|
1463
|
-
if (
|
|
1464
|
-
return yield* failure("Captured execution has no Run continuation");
|
|
1465
|
-
if (canonicalRecordBytes(record) !== turnBytes - turnBase)
|
|
1466
|
-
return yield* failure("Continuation byte accounting differs from its Schema encoding");
|
|
1467
|
-
if (canonicalRecordBytes(record) > MAX_RUN_CONTINUATION_BYTES)
|
|
1573
|
+
if (cursorBytes > MAX_RUN_CONTINUATION_BYTES)
|
|
1468
1574
|
return yield* capacityFailure(
|
|
1469
1575
|
"Encoded continuation exceeds 8192 bytes including its envelope",
|
|
1470
1576
|
);
|
|
1577
|
+
executionCount++;
|
|
1578
|
+
if (
|
|
1579
|
+
mode === "preflight" &&
|
|
1580
|
+
previous?.checkpoint !== undefined &&
|
|
1581
|
+
facts.every(({ payload }) => payload._tag === "ModelResponseRecorded")
|
|
1582
|
+
) {
|
|
1583
|
+
// The payload and header are validated, and operational facts are unchanged.
|
|
1584
|
+
// Dispatch needs their capacity proof; only a commit needs checkpoint wire.
|
|
1585
|
+
yield* decodeExecutionFrontier({
|
|
1586
|
+
canonicalRecords,
|
|
1587
|
+
throughSequence: after + ownedRecords.filter((fact) => !isOperationalRecord(fact)).length,
|
|
1588
|
+
}).pipe(Effect.mapError((cause) => failure("Active execution exceeds its bounds", cause)));
|
|
1589
|
+
|
|
1590
|
+
const state: ProgressState = {
|
|
1591
|
+
continuation,
|
|
1592
|
+
record: proposedRecord,
|
|
1593
|
+
...(response === undefined ? {} : { response }),
|
|
1594
|
+
results,
|
|
1595
|
+
childResults,
|
|
1596
|
+
...(completionBytes === undefined ? {} : { completionBytes }),
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
yield* checkCapacity(
|
|
1600
|
+
state,
|
|
1601
|
+
new Set(batch.records.map(({ recordId }) => recordId)),
|
|
1602
|
+
undefined,
|
|
1603
|
+
usageCharge,
|
|
1604
|
+
);
|
|
1605
|
+
yield* checkFutureShapes(state, cursorBytes);
|
|
1606
|
+
continue;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
const record = yield* Effect.fromResult(captureRecord(proposedRecord)).pipe(
|
|
1610
|
+
Effect.map((record) => record.canonical),
|
|
1611
|
+
Effect.mapError((cause) => failure("Cannot capture canonical progress facts", cause)),
|
|
1612
|
+
);
|
|
1613
|
+
|
|
1614
|
+
if (!isExecutionProgressRecord(record))
|
|
1615
|
+
return yield* failure("Captured execution has no Run continuation");
|
|
1616
|
+
if (canonicalRecordBytes(record) !== cursorBytes)
|
|
1617
|
+
return yield* failure("Continuation byte accounting differs from its Schema encoding");
|
|
1471
1618
|
|
|
1472
1619
|
const operational = new Map(
|
|
1473
1620
|
(previous?.checkpoint?.operational ?? []).map((fact) => [fact.recordId, fact]),
|
|
@@ -1478,7 +1625,15 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1478
1625
|
for (const fact of changed) {
|
|
1479
1626
|
const prior = operational.get(fact.recordId);
|
|
1480
1627
|
|
|
1481
|
-
if (
|
|
1628
|
+
if (
|
|
1629
|
+
prior !== undefined &&
|
|
1630
|
+
(yield* Effect.fromResult(recordEncoding(prior)).pipe(
|
|
1631
|
+
Effect.mapError((cause) => failure("Cannot encode active Run fact", cause)),
|
|
1632
|
+
)).json !==
|
|
1633
|
+
(yield* Effect.fromResult(recordEncoding(fact)).pipe(
|
|
1634
|
+
Effect.mapError((cause) => failure("Cannot encode active Run fact", cause)),
|
|
1635
|
+
)).json
|
|
1636
|
+
)
|
|
1482
1637
|
return yield* failure("An active Run fact cannot change after becoming durable");
|
|
1483
1638
|
operational.set(fact.recordId, fact);
|
|
1484
1639
|
}
|
|
@@ -1535,10 +1690,10 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1535
1690
|
accepted.set(runId, state);
|
|
1536
1691
|
}
|
|
1537
1692
|
|
|
1538
|
-
if (ownedRecords.length +
|
|
1693
|
+
if (ownedRecords.length + executionCount > 256)
|
|
1539
1694
|
return yield* failure("Progress and facts exceed the atomic batch bound");
|
|
1540
1695
|
|
|
1541
|
-
const prepared =
|
|
1696
|
+
const prepared = CommitBatch.make(
|
|
1542
1697
|
{
|
|
1543
1698
|
...batch,
|
|
1544
1699
|
records: ownedRecords.filter((fact) => !isOperationalRecord(fact)),
|
|
@@ -1566,14 +1721,11 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1566
1721
|
};
|
|
1567
1722
|
});
|
|
1568
1723
|
|
|
1569
|
-
const tail = Effect.
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
return (yield* writer.tail).sequence;
|
|
1576
|
-
});
|
|
1724
|
+
const tail = Effect.flatMap(CurrentRunWriter, (writer) =>
|
|
1725
|
+
writer.threadId !== threadId
|
|
1726
|
+
? Effect.fail(failure("Progress writer belongs to another Thread"))
|
|
1727
|
+
: Effect.map(writer.tail, (position) => position.sequence),
|
|
1728
|
+
);
|
|
1577
1729
|
|
|
1578
1730
|
const commitCaptured = Effect.fnUntraced(
|
|
1579
1731
|
function* (batch: CanonicalBatch) {
|
|
@@ -1699,7 +1851,7 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1699
1851
|
|
|
1700
1852
|
const owned = yield* captureFacts(batch);
|
|
1701
1853
|
|
|
1702
|
-
yield* prepare(owned, after);
|
|
1854
|
+
yield* prepare(owned, after, "preflight");
|
|
1703
1855
|
|
|
1704
1856
|
const response = owned.records.find(
|
|
1705
1857
|
(record) => record.payload._tag === "ModelResponseRecorded",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Brand,
|
|
1
|
+
import { Brand, Effect, Predicate, Schema, Stream, type DateTime } from "effect";
|
|
2
2
|
import { Prompt } from "effect/ai";
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -22,13 +22,14 @@ import {
|
|
|
22
22
|
contextWindowMessage,
|
|
23
23
|
} from "../engine/Compaction.ts";
|
|
24
24
|
import type { RunTurnToolResult } from "../engine/RunOptions.ts";
|
|
25
|
-
import { digestJson
|
|
25
|
+
import { digestJson } from "./Digest.ts";
|
|
26
26
|
import {
|
|
27
27
|
makeJournalMetadata,
|
|
28
28
|
toolCallSettledRecordId,
|
|
29
29
|
type JournalMetadata,
|
|
30
30
|
type JournalRecordEnvelope,
|
|
31
31
|
} from "./internal/journal-metadata.ts";
|
|
32
|
+
import { continuationUsage } from "./internal/usage-totals.ts";
|
|
32
33
|
import {
|
|
33
34
|
type BatchId,
|
|
34
35
|
type RecordId,
|
|
@@ -1704,7 +1705,7 @@ const requireCanonicalTurn = (turn: number): Effect.Effect<void, RunJournalError
|
|
|
1704
1705
|
|
|
1705
1706
|
const modelResponseRecord = Effect.fnUntraced(function* (
|
|
1706
1707
|
input: TurnCommitInput,
|
|
1707
|
-
): Effect.fn.Return<RecordEnvelope, RunJournalError
|
|
1708
|
+
): Effect.fn.Return<RecordEnvelope, RunJournalError> {
|
|
1708
1709
|
const promptMessages = input.responseMessages;
|
|
1709
1710
|
|
|
1710
1711
|
if (promptMessages.length === 0) {
|
|
@@ -1753,14 +1754,14 @@ const modelResponseRecord = Effect.fnUntraced(function* (
|
|
|
1753
1754
|
return yield* journalError("Turn model usage must contain at least one completed call");
|
|
1754
1755
|
}
|
|
1755
1756
|
|
|
1756
|
-
const summary = yield*
|
|
1757
|
+
const summary = yield* continuationUsage(modelUsage).pipe(
|
|
1757
1758
|
Effect.mapError((cause) => journalError("Turn model usage exceeds accounting bounds", cause)),
|
|
1758
1759
|
);
|
|
1759
1760
|
|
|
1760
1761
|
if (
|
|
1761
1762
|
input.usage === undefined ||
|
|
1762
|
-
input.usage.inputTokens !== summary.inputTokens
|
|
1763
|
-
input.usage.outputTokens !== summary.outputTokens
|
|
1763
|
+
input.usage.inputTokens !== summary.inputTokens ||
|
|
1764
|
+
input.usage.outputTokens !== summary.outputTokens ||
|
|
1764
1765
|
(input.usage.costMicrousd ?? 0) !== summary.costMicrousd
|
|
1765
1766
|
) {
|
|
1766
1767
|
return yield* journalError("Turn detailed and aggregate model usage disagree");
|
|
@@ -1882,7 +1883,7 @@ const runCompletionRecord = Effect.fnUntraced(function* (input: TurnCommitInput)
|
|
|
1882
1883
|
*/
|
|
1883
1884
|
export const turnCanonicalBatch = Effect.fnUntraced(function* (
|
|
1884
1885
|
input: TurnCommitInput,
|
|
1885
|
-
): Effect.fn.Return<CanonicalBatch, RunJournalError
|
|
1886
|
+
): Effect.fn.Return<CanonicalBatch, RunJournalError> {
|
|
1886
1887
|
yield* requireCanonicalTurn(input.turn);
|
|
1887
1888
|
const modelResponse = yield* modelResponseRecord(input);
|
|
1888
1889
|
const toolRecords = yield* toolSettledRecords(input);
|
|
@@ -1907,7 +1908,7 @@ export const turnCanonicalBatch = Effect.fnUntraced(function* (
|
|
|
1907
1908
|
*/
|
|
1908
1909
|
export const turnResponseBatch = Effect.fnUntraced(function* (
|
|
1909
1910
|
input: TurnCommitInput,
|
|
1910
|
-
): Effect.fn.Return<CanonicalBatch, RunJournalError
|
|
1911
|
+
): Effect.fn.Return<CanonicalBatch, RunJournalError> {
|
|
1911
1912
|
yield* requireCanonicalTurn(input.turn);
|
|
1912
1913
|
const modelResponse = yield* modelResponseRecord(input);
|
|
1913
1914
|
|
|
@@ -1926,7 +1927,7 @@ export const turnResponseBatch = Effect.fnUntraced(function* (
|
|
|
1926
1927
|
*/
|
|
1927
1928
|
export const turnResultsBatch = Effect.fnUntraced(function* (
|
|
1928
1929
|
input: TurnCommitInput,
|
|
1929
|
-
): Effect.fn.Return<CanonicalBatch, RunJournalError
|
|
1930
|
+
): Effect.fn.Return<CanonicalBatch, RunJournalError> {
|
|
1930
1931
|
yield* requireCanonicalTurn(input.turn);
|
|
1931
1932
|
const toolRecords = yield* toolSettledRecords(input);
|
|
1932
1933
|
const first = toolRecords[0];
|