@yielded/agent-storage-cloudflare 0.1.0-beta.174 → 0.1.0-beta.175
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/DoMemoryStore.mjs +1 -1
- package/dist/DoMessageDeliveryStore.mjs +1 -1
- package/dist/DoStorageFailpoint.d.mts +3 -1
- package/dist/DoStorageFailpoint.mjs +7 -2
- package/dist/DoStorageFailpoint.mjs.map +1 -1
- package/dist/{DoStorageVersion-NKnQU3eR.d.mts → DoStorageVersion-Mc7CXMdN.d.mts} +2 -2
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoSubmissionLedger.mjs +116 -65
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/{DoThreadStore-DyzOZDXK.mjs → DoThreadStore-CgIZQUNR.mjs} +24 -19
- package/dist/DoThreadStore-CgIZQUNR.mjs.map +1 -0
- package/dist/DoThreadStore.mjs +1 -1
- package/dist/PortProtocol.d.mts +7063 -7063
- package/dist/PortRouting.mjs +6 -1
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-ZMAzzENZ.mjs → do-journal-7P3DUBz0.mjs} +131 -43
- package/dist/do-journal-7P3DUBz0.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{migrations-C3N9GN6A.mjs → migrations-CAO_akhD.mjs} +45 -22
- package/dist/migrations-CAO_akhD.mjs.map +1 -0
- package/dist/{owned-state-DcFh0YNo.mjs → owned-state-B4QhezMp.mjs} +2 -1
- package/dist/{owned-state-DcFh0YNo.mjs.map → owned-state-B4QhezMp.mjs.map} +1 -1
- package/package.json +1 -1
- package/src/DoStorageFailpoint.ts +4 -0
- package/src/DoSubmissionLedger.ts +262 -149
- package/src/DoThreadStore.ts +18 -44
- package/src/PortRouting.ts +10 -2
- package/src/internal/do-journal.ts +286 -66
- package/src/internal/migrations.ts +52 -10
- package/src/internal/owned-state.ts +9 -1
- package/src/internal/prompt-checkpoint.ts +6 -3
- package/src/internal/storage-span.ts +14 -10
- package/dist/DoThreadStore-DyzOZDXK.mjs.map +0 -1
- package/dist/do-journal-ZMAzzENZ.mjs.map +0 -1
- package/dist/migrations-C3N9GN6A.mjs.map +0 -1
package/dist/DoMemoryStore.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { r as ownedState } from "./owned-state-
|
|
2
|
+
import { r as ownedState } from "./owned-state-B4QhezMp.mjs";
|
|
3
3
|
import { SqlMemoryLimits, SqlStorageOwner, memoryStoreLayerWithFailpoints } from "@yielded/agent/sql-memory-store";
|
|
4
4
|
import { Effect, Layer, Schema } from "effect";
|
|
5
5
|
import * as SqlClientService from "effect/sql/SqlClient";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
|
-
import { i as initializeDoJournal } from "./do-journal-
|
|
4
|
+
import { i as initializeDoJournal } from "./do-journal-7P3DUBz0.mjs";
|
|
5
5
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
6
6
|
import { SqlLifecycleSource } from "@yielded/agent-storage-sql/sql-lifecycle-publication";
|
|
7
7
|
import { makeSqlMessageDeliveryStore } from "@yielded/agent-storage-sql/sql-message-delivery-store";
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { c as DoStorageFailpointError, l as DoStorageFailpointLocation } from "./DoStorageError-CxjMnzUA.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
declare namespace DoStorageFailpoint_d_exports {
|
|
4
|
-
export { DoStorageFailpoint, DoStorageFailpointHandler };
|
|
4
|
+
export { DoStorageFailpoint, DoStorageFailpointHandler, isDefaultDoStorageFailpoint };
|
|
5
5
|
}
|
|
6
6
|
export type DoStorageFailpointHandler = (location: DoStorageFailpointLocation) => Effect.Effect<void, DoStorageFailpointError>;
|
|
7
|
+
/** @internal Select a plain native body only for the library's no-op handler. */
|
|
8
|
+
export declare const isDefaultDoStorageFailpoint: (handler: DoStorageFailpointHandler) => boolean;
|
|
7
9
|
declare const DoStorageFailpoint_base: Context.ServiceClass<DoStorageFailpoint, "@effect-agent/storage-cloudflare/DoStorageFailpoint", {
|
|
8
10
|
readonly hit: DoStorageFailpointHandler;
|
|
9
11
|
}>;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
//#region src/DoStorageFailpoint.ts
|
|
4
|
-
var DoStorageFailpoint_exports = /* @__PURE__ */ __exportAll({
|
|
4
|
+
var DoStorageFailpoint_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
DoStorageFailpoint: () => DoStorageFailpoint,
|
|
6
|
+
isDefaultDoStorageFailpoint: () => isDefaultDoStorageFailpoint
|
|
7
|
+
});
|
|
5
8
|
const noFailpoint = () => Effect.void;
|
|
9
|
+
/** @internal Select a plain native body only for the library's no-op handler. */
|
|
10
|
+
const isDefaultDoStorageFailpoint = (handler) => handler === noFailpoint;
|
|
6
11
|
/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */
|
|
7
12
|
var DoStorageFailpoint = class extends Context.Service()("@effect-agent/storage-cloudflare/DoStorageFailpoint") {
|
|
8
13
|
/** Production default: no fault injection. */
|
|
9
14
|
static layer = Layer.succeed(this)({ hit: noFailpoint });
|
|
10
15
|
};
|
|
11
16
|
//#endregion
|
|
12
|
-
export { DoStorageFailpoint, DoStorageFailpoint_exports as t };
|
|
17
|
+
export { DoStorageFailpoint, isDefaultDoStorageFailpoint, DoStorageFailpoint_exports as t };
|
|
13
18
|
|
|
14
19
|
//# sourceMappingURL=DoStorageFailpoint.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoStorageFailpoint.mjs","names":[],"sources":["../src/DoStorageFailpoint.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\n\nimport type { DoStorageFailpointError, DoStorageFailpointLocation } from \"./DoStorageError.ts\";\n\nexport type DoStorageFailpointHandler = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoStorageFailpointHandler = () => Effect.void;\n\n/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */\nexport class DoStorageFailpoint extends Context.Service<\n DoStorageFailpoint,\n {\n readonly hit: DoStorageFailpointHandler;\n }\n>()(\"@effect-agent/storage-cloudflare/DoStorageFailpoint\") {\n /** Production default: no fault injection. */\n static readonly layer = Layer.succeed(this)({ hit: noFailpoint });\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"DoStorageFailpoint.mjs","names":[],"sources":["../src/DoStorageFailpoint.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\n\nimport type { DoStorageFailpointError, DoStorageFailpointLocation } from \"./DoStorageError.ts\";\n\nexport type DoStorageFailpointHandler = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoStorageFailpointHandler = () => Effect.void;\n\n/** @internal Select a plain native body only for the library's no-op handler. */\nexport const isDefaultDoStorageFailpoint = (handler: DoStorageFailpointHandler): boolean =>\n handler === noFailpoint;\n\n/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */\nexport class DoStorageFailpoint extends Context.Service<\n DoStorageFailpoint,\n {\n readonly hit: DoStorageFailpointHandler;\n }\n>()(\"@effect-agent/storage-cloudflare/DoStorageFailpoint\") {\n /** Production default: no fault injection. */\n static readonly layer = Layer.succeed(this)({ hit: noFailpoint });\n}\n"],"mappings":";;;;;;;AAQA,MAAM,oBAA+C,OAAO;;AAG5D,MAAa,+BAA+B,YAC1C,YAAY;;AAGd,IAAa,qBAAb,cAAwC,QAAQ,QAK9C,CAAC,CAAC,qDAAqD,CAAC,CAAC;;CAEzD,OAAgB,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC;AAClE"}
|
|
@@ -2,10 +2,10 @@ import "./DoStorageError-CxjMnzUA.mjs";
|
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import "effect/sql/SqlClient";
|
|
4
4
|
//#region src/internal/migrations.d.ts
|
|
5
|
-
declare const CurrentDoStorageVersion =
|
|
5
|
+
declare const CurrentDoStorageVersion = 28;
|
|
6
6
|
declare namespace DoStorageVersion_d_exports {
|
|
7
7
|
export { CurrentDoStorageVersion };
|
|
8
8
|
}
|
|
9
9
|
//#endregion
|
|
10
10
|
export { CurrentDoStorageVersion as n, DoStorageVersion_d_exports as t };
|
|
11
|
-
//# sourceMappingURL=DoStorageVersion-
|
|
11
|
+
//# sourceMappingURL=DoStorageVersion-Mc7CXMdN.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as CurrentDoStorageVersion } from "./DoStorageVersion-
|
|
1
|
+
import { n as CurrentDoStorageVersion } from "./DoStorageVersion-Mc7CXMdN.mjs";
|
|
2
2
|
export { CurrentDoStorageVersion };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { t as CurrentDoStorageVersion } from "./migrations-
|
|
2
|
+
import { t as CurrentDoStorageVersion } from "./migrations-CAO_akhD.mjs";
|
|
3
3
|
//#region src/DoStorageVersion.ts
|
|
4
|
-
var DoStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentDoStorageVersion: () =>
|
|
4
|
+
var DoStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentDoStorageVersion: () => 28 });
|
|
5
5
|
//#endregion
|
|
6
6
|
export { CurrentDoStorageVersion, DoStorageVersion_exports as t };
|
|
7
7
|
|
|
@@ -2,18 +2,18 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { DoLedgerError, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
|
|
5
|
-
import { n as ownedRows } from "./owned-state-
|
|
6
|
-
import { i as initializeDoJournal, r as decodeRows } from "./do-journal-
|
|
7
|
-
import { l as prepareCanonicalAppend, o as storageConfigLayer, s as storageFailpointLayer } from "./DoThreadStore-
|
|
5
|
+
import { n as ownedRows } from "./owned-state-B4QhezMp.mjs";
|
|
6
|
+
import { i as initializeDoJournal, r as decodeRows } from "./do-journal-7P3DUBz0.mjs";
|
|
7
|
+
import { l as prepareCanonicalAppend, o as storageConfigLayer, s as storageFailpointLayer } from "./DoThreadStore-CgIZQUNR.mjs";
|
|
8
8
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
9
9
|
import { Cause, Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
10
10
|
import * as SqlClientService from "effect/sql/SqlClient";
|
|
11
|
+
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
11
12
|
import { definitionJson, makeCanonicalStorage, recordBatchId, runKey } from "@yielded/agent-storage-sql/sql-canonical-storage";
|
|
12
13
|
import { SqlStorageProgress } from "@yielded/agent-storage-sql/sql-storage-progress";
|
|
13
14
|
import { canonicalRecordJson } from "@yielded/agent-storage-sql/sql-thread-archive-range";
|
|
14
15
|
import { ApprovalDecision, CanonicalSequence, DefinitionDigests, Digest, PersistedJson, RecordEnvelope, RecordId, SettlementOutcome, WorkerAdmission } from "@yielded/agent/records";
|
|
15
16
|
import { AppendConflict, ThreadNotMaterialized, ThreadStoreDiagnostic, ThreadStoreError, makeTransferFactCheck } from "@yielded/agent/thread-store";
|
|
16
|
-
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
17
17
|
import { StorageOwner } from "@yielded/agent/run-storage";
|
|
18
18
|
import { decodeAbortFact, decodeAdmissionFact, decodeApprovalFact, decodeResolutionFact } from "@yielded/agent-storage-sql/sql-admission-facts";
|
|
19
19
|
import { InputMessage } from "@yielded/agent/messaging";
|
|
@@ -191,7 +191,7 @@ const decodeClaim = Schema.decodeUnknownEffect(Claim);
|
|
|
191
191
|
const decodeSettlement = Schema.decodeUnknownEffect(Settlement);
|
|
192
192
|
const decodeAbortIntent = Schema.decodeUnknownEffect(AbortIntent);
|
|
193
193
|
const decodeInputAppliedMarker = Schema.decodeUnknownEffect(InputAppliedMarker);
|
|
194
|
-
const decodeSubmissionSnapshotType = (input) =>
|
|
194
|
+
const decodeSubmissionSnapshotType = (input) => SubmissionSnapshot.makeEffect(input).pipe(Effect.mapError((issue) => new Schema.SchemaError(issue)));
|
|
195
195
|
const decodeSubmissionId = Schema.decodeUnknownEffect(SubmissionSnapshot.fields.submissionId);
|
|
196
196
|
const decodeQueueSequence = Schema.decodeUnknownEffect(QueueSequence);
|
|
197
197
|
const decodeUtcInstant = Schema.decodeUnknownEffect(Schema.DateTimeUtcFromString);
|
|
@@ -205,6 +205,26 @@ const decodeChildReservationSnapshotUnknown = Schema.decodeUnknownEffect(ChildBu
|
|
|
205
205
|
const decodeChildAttachmentSnapshot = Schema.decodeUnknownEffect(ChildAttachmentSnapshot);
|
|
206
206
|
const equivalentPersistedJson = Schema.toEquivalence(PersistedJson);
|
|
207
207
|
const equivalentUnknownResolution = Schema.toEquivalence(UnknownResolution);
|
|
208
|
+
const decodeAdmissionRequestType = Schema.decodeEffect(Schema.toType(AdmissionRequest));
|
|
209
|
+
const decodeSubmissionLookupType = Schema.decodeEffect(Schema.toType(SubmissionLookup));
|
|
210
|
+
const decodeClaimRequestType = Schema.decodeEffect(Schema.toType(ClaimRequest));
|
|
211
|
+
const decodeMarkInputAppliedRequestType = Schema.decodeEffect(Schema.toType(MarkInputAppliedRequest));
|
|
212
|
+
const decodeSettlementFinalizationType = Schema.decodeEffect(Schema.toType(SettlementFinalization));
|
|
213
|
+
const decodeClaimJoiningRequestType = Schema.decodeEffect(Schema.toType(ClaimJoiningRequest));
|
|
214
|
+
const decodeAbortIntentRequestType = Schema.decodeEffect(Schema.toType(AbortIntentRequest));
|
|
215
|
+
const decodeRecoverySnapshotRequestType = Schema.decodeEffect(Schema.toType(RecoverySnapshotRequest));
|
|
216
|
+
const SubmissionRows = Schema.Array(SubmissionRow);
|
|
217
|
+
const ChildReservationRows = Schema.Array(ChildReservationRow);
|
|
218
|
+
const MaxQueueSequenceRows = Schema.Array(MaxQueueSequenceRow);
|
|
219
|
+
const SubmissionWorkItems = Schema.Array(SubmissionWorkItem);
|
|
220
|
+
const decodeSubmissionWorkItems = Schema.decodeEffect(SubmissionWorkItems);
|
|
221
|
+
const equivalentWorkerOrigin = Schema.toEquivalence(Schema.optional(WorkerAdmission.fields.origin));
|
|
222
|
+
const decodeFirstWorkerAdmissions = Schema.decodeUnknownEffect(Schema.Array(Schema.Struct({ worker_admission_json: Schema.NullOr(BoundedStoredText) })));
|
|
223
|
+
const CanonicalSettlementRows = Schema.Array(Schema.Struct({
|
|
224
|
+
batch_id: Schema.fromJsonString(BoundedIdentifier),
|
|
225
|
+
record_id: Schema.fromJsonString(BoundedIdentifier),
|
|
226
|
+
record_json: BoundedStoredText
|
|
227
|
+
}));
|
|
208
228
|
const isDoStorageError = Schema.is(DoStorageError);
|
|
209
229
|
/** Wrap an adapter-internal failure into the port's LedgerError without erasing its tag. */
|
|
210
230
|
const internalFailure = (operation) => (error) => LedgerError.make({
|
|
@@ -319,7 +339,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
319
339
|
millis,
|
|
320
340
|
iso: new Date(millis).toISOString()
|
|
321
341
|
}));
|
|
322
|
-
const decodeSubmissionRows = (operation, rowKey, rows) => decodeRows(
|
|
342
|
+
const decodeSubmissionRows = (operation, rowKey, rows) => decodeRows(SubmissionRows, "effect_agent_submissions", rowKey, rows).pipe(Effect.mapError(internalFailure(operation)));
|
|
323
343
|
const readSubmission = Effect.fnUntraced(function* (operation, submissionId) {
|
|
324
344
|
const found = yield* cached(rows.submissions.by("submission_id", submissionId), operation);
|
|
325
345
|
return Option.fromUndefinedOr(found[0]);
|
|
@@ -373,11 +393,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
373
393
|
const found = yield* sql`SELECT ${recordBatchId(sql)} AS batch_id, record_id, ${canonicalRecordJson(sql)} AS record_json
|
|
374
394
|
FROM effect_agent_canonical_records WHERE thread_id = ${submission.thread_id}
|
|
375
395
|
AND record_id = ${JSON.stringify(recordId)}`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
376
|
-
const decoded = yield* decodeRows(
|
|
377
|
-
batch_id: Schema.fromJsonString(BoundedIdentifier),
|
|
378
|
-
record_id: Schema.fromJsonString(BoundedIdentifier),
|
|
379
|
-
record_json: BoundedStoredText
|
|
380
|
-
})), "effect_agent_canonical_records", recordId, found).pipe(Effect.mapError(internalFailure(operation)));
|
|
396
|
+
const decoded = yield* decodeRows(CanonicalSettlementRows, "effect_agent_canonical_records", recordId, found).pipe(Effect.mapError(internalFailure(operation)));
|
|
381
397
|
if (decoded.length === 0) return void 0;
|
|
382
398
|
const row = decoded[0];
|
|
383
399
|
if (decoded.length !== 1 || row.batch_id !== submissionSettlementBatchId(expected.submissionId) || row.record_id !== recordId) return yield* corruptionFailure(operation, "effect_agent_canonical_records", recordId, "Canonical settlement identity is inconsistent.");
|
|
@@ -410,7 +426,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
410
426
|
const childRow = yield* readSubmission(operation, childSubmissionId);
|
|
411
427
|
return Option.isSome(childRow) && (yield* readCanonicalSettlement(operation, childRow.value)) !== void 0;
|
|
412
428
|
});
|
|
413
|
-
const decodeChildReservationRows = (operation, rowKey, rows) => decodeRows(
|
|
429
|
+
const decodeChildReservationRows = (operation, rowKey, rows) => decodeRows(ChildReservationRows, "effect_agent_child_reservations", rowKey, rows).pipe(Effect.mapError(internalFailure(operation)));
|
|
414
430
|
const readChildReservation = Effect.fnUntraced(function* (operation, reservationId) {
|
|
415
431
|
const rows = yield* sql`
|
|
416
432
|
SELECT ${sql.literal(CHILD_RESERVATION_COLUMNS)}
|
|
@@ -483,9 +499,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
483
499
|
});
|
|
484
500
|
});
|
|
485
501
|
const capabilities = Effect.succeed(LedgerCapabilities.make({ durability: "durable-cloudflare" }));
|
|
486
|
-
const admit = Effect.fnUntraced(function* (request) {
|
|
502
|
+
const admit = Effect.fnUntraced(function* (request, options) {
|
|
487
503
|
const operation = "ledger admit";
|
|
488
|
-
const validated = yield*
|
|
504
|
+
const validated = yield* decodeAdmissionRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
489
505
|
const inputJson = yield* encodePersistedJsonText(validated.inputPayload).pipe(Effect.mapError(internalFailure(operation)));
|
|
490
506
|
yield* journal.checkValueBound(operation, inputJson).pipe(Effect.mapError(internalFailure(operation)));
|
|
491
507
|
const workerAdmissionJson = validated.workerAdmission === void 0 ? null : yield* Schema.encodeEffect(Schema.fromJsonString(WorkerAdmission))(validated.workerAdmission).pipe(Effect.mapError(internalFailure(operation)));
|
|
@@ -550,10 +566,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
550
566
|
SELECT worker_admission_json FROM effect_agent_submissions
|
|
551
567
|
WHERE thread_id=${validated.threadId} ORDER BY queue_sequence LIMIT 1
|
|
552
568
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
553
|
-
const first = yield*
|
|
569
|
+
const first = yield* decodeFirstWorkerAdmissions(firstRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
554
570
|
if (first[0] !== void 0) {
|
|
555
571
|
const previous = first[0].worker_admission_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(WorkerAdmission))(first[0].worker_admission_json).pipe(Effect.mapError(internalFailure(operation)));
|
|
556
|
-
if (!
|
|
572
|
+
if (!equivalentWorkerOrigin(previous?.origin, validated.workerAdmission?.origin)) return yield* AdmissionPolicyError.make({
|
|
557
573
|
reason: "refused",
|
|
558
574
|
code: "worker-origin-conflict"
|
|
559
575
|
});
|
|
@@ -573,9 +589,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
573
589
|
FROM effect_agent_submissions
|
|
574
590
|
WHERE thread_id = ${validated.threadId}
|
|
575
591
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
576
|
-
const decodedMax = yield* decodeRows(
|
|
592
|
+
const decodedMax = yield* decodeRows(MaxQueueSequenceRows, "effect_agent_submissions", validated.threadId, maxRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
577
593
|
const queueSequence = yield* decodeQueueSequence((decodedMax[0]?.max_queue_sequence ?? 0) + 1).pipe(Effect.mapError(internalFailure(operation)));
|
|
578
594
|
const now = yield* currentInstant;
|
|
595
|
+
const ready = options?.readyIfInitialized === true && validated.workerAdmission === void 0 && (yield* journal.getThread(validated.threadId).pipe(Effect.mapError(internalFailure(operation)))).some((thread) => thread.tail_sequence > 0);
|
|
579
596
|
yield* sql`
|
|
580
597
|
INSERT INTO effect_agent_submissions (
|
|
581
598
|
submission_id,
|
|
@@ -591,6 +608,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
591
608
|
receipt_id,
|
|
592
609
|
state,
|
|
593
610
|
created_at,
|
|
611
|
+
ready_at,
|
|
594
612
|
parent_submission_id,
|
|
595
613
|
parent_tool_call_id,
|
|
596
614
|
admission_group,
|
|
@@ -609,8 +627,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
609
627
|
${inputJson},
|
|
610
628
|
${validated.inputDigest},
|
|
611
629
|
${mintedReceiptId},
|
|
612
|
-
|
|
630
|
+
${ready ? "ready" : "admitted"},
|
|
613
631
|
${now.iso},
|
|
632
|
+
${ready ? now.iso : null},
|
|
614
633
|
${validated.parentLinkage?.parentSubmissionId ?? null},
|
|
615
634
|
${validated.parentLinkage?.parentToolCallId ?? null},
|
|
616
635
|
${validated.admissionGroup ?? null},
|
|
@@ -622,6 +641,11 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
622
641
|
if (queueSequence === 1) {
|
|
623
642
|
if ((yield* journal.getThread(validated.threadId).pipe(Effect.mapError(internalFailure(operation)))).length === 0) yield* journal.work.initialize(validated.threadId).pipe(Effect.mapError(internalFailure(operation)));
|
|
624
643
|
}
|
|
644
|
+
submissionViews.seedMatching(JSON.stringify([
|
|
645
|
+
"joining-suffix",
|
|
646
|
+
validated.threadId,
|
|
647
|
+
queueSequence
|
|
648
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > queueSequence, [], 0);
|
|
625
649
|
rows.aborts.seed("submission_id", mintedSubmissionId, []);
|
|
626
650
|
rows.submissions.seed("joined_host_submission_id", mintedSubmissionId, []);
|
|
627
651
|
rows.approvals.seed("submission_id", mintedSubmissionId, []);
|
|
@@ -629,13 +653,18 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
629
653
|
rows.childReservations.seed("parent_submission_id", mintedSubmissionId, []);
|
|
630
654
|
rows.childSettlements.seed("parent_submission_id", mintedSubmissionId, []);
|
|
631
655
|
yield* recordProgress("submission", operation);
|
|
632
|
-
|
|
656
|
+
const admitted = yield* decodeAdmissionResult({
|
|
633
657
|
submissionId: mintedSubmissionId,
|
|
634
658
|
receiptId: mintedReceiptId,
|
|
635
659
|
queueSequence,
|
|
636
|
-
state: "admitted",
|
|
660
|
+
state: ready ? "ready" : "admitted",
|
|
637
661
|
replayed: false
|
|
638
662
|
}).pipe(Effect.mapError(internalFailure(operation)));
|
|
663
|
+
if (ready && lifecycle !== void 0) yield* retainLifecycle(yield* requireSubmission(operation, mintedSubmissionId), {
|
|
664
|
+
_tag: "SubmissionReady",
|
|
665
|
+
submissionId: admitted.submissionId
|
|
666
|
+
});
|
|
667
|
+
return admitted;
|
|
639
668
|
}));
|
|
640
669
|
yield* hitFailpoint("ledger:admit:after", operation);
|
|
641
670
|
return result;
|
|
@@ -685,7 +714,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
685
714
|
}, state.read);
|
|
686
715
|
const lookup = Effect.fnUntraced(function* (request) {
|
|
687
716
|
const operation = "ledger lookup";
|
|
688
|
-
const validated = yield*
|
|
717
|
+
const validated = yield* decodeSubmissionLookupType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
689
718
|
if (validated._tag === "SubmissionLookupById") {
|
|
690
719
|
const row = yield* readSubmission(operation, validated.submissionId);
|
|
691
720
|
if (Option.isNone(row)) return Option.none();
|
|
@@ -708,12 +737,23 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
708
737
|
});
|
|
709
738
|
const selectHead = Effect.fn("DoSubmissionLedger.selectHead")(function* (request) {
|
|
710
739
|
const operation = "ledger select head";
|
|
711
|
-
const validated = yield*
|
|
740
|
+
const validated = yield* decodeClaimRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
712
741
|
const attemptId = `attempt-${yield* mintUuid(operation)}`;
|
|
713
742
|
yield* hitFailpoint("ledger:claim:before", operation);
|
|
714
743
|
const claimed = yield* owner.withMutation(Effect.gen(function* () {
|
|
715
744
|
if (owner.hasOwner(validated.threadId)) return Option.none();
|
|
716
|
-
const
|
|
745
|
+
const active = yield* activeNonterminal;
|
|
746
|
+
const heads = [];
|
|
747
|
+
const limit = validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1;
|
|
748
|
+
if (active.length <= 128) {
|
|
749
|
+
const candidates = active.filter((row) => row.thread_id === validated.threadId).sort((left, right) => left.queue_sequence - right.queue_sequence);
|
|
750
|
+
for (const candidate of candidates) {
|
|
751
|
+
if (candidate.state === "unknown" && Option.isNone(yield* readAbortIntent(operation, candidate.submission_id))) continue;
|
|
752
|
+
heads.push(yield* requireSubmission(operation, candidate.submission_id));
|
|
753
|
+
if (heads.length === limit) break;
|
|
754
|
+
}
|
|
755
|
+
} else {
|
|
756
|
+
const headRows = yield* sql`
|
|
717
757
|
SELECT ${submissionColumns}
|
|
718
758
|
FROM effect_agent_submissions
|
|
719
759
|
WHERE thread_id = ${validated.threadId}
|
|
@@ -727,7 +767,8 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
727
767
|
ORDER BY queue_sequence ASC
|
|
728
768
|
LIMIT ${validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1}
|
|
729
769
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
730
|
-
|
|
770
|
+
heads.push(...yield* decodeSubmissionRows(operation, validated.threadId, headRows));
|
|
771
|
+
}
|
|
731
772
|
if (heads.length === 0) return Option.none();
|
|
732
773
|
let head = heads[0];
|
|
733
774
|
if (validated.handoff !== void 0) {
|
|
@@ -754,7 +795,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
754
795
|
});
|
|
755
796
|
const markInputApplied = Effect.fnUntraced(function* (request) {
|
|
756
797
|
const operation = "ledger mark input applied";
|
|
757
|
-
const validated = yield*
|
|
798
|
+
const validated = yield* decodeMarkInputAppliedRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
758
799
|
yield* hitFailpoint("ledger:mark-input-applied:before", operation);
|
|
759
800
|
yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
760
801
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
@@ -899,7 +940,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
899
940
|
});
|
|
900
941
|
const finalizeSettlement = Effect.fn("DoSubmissionLedger.finalizeSettlement")(function* (request) {
|
|
901
942
|
const operation = "ledger finalize settlement";
|
|
902
|
-
const validated = yield*
|
|
943
|
+
const validated = yield* decodeSettlementFinalizationType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
903
944
|
yield* hitFailpoint("ledger:finalize-settlement:before", operation);
|
|
904
945
|
const replay = yield* state.read(Effect.gen(function* () {
|
|
905
946
|
const submission = yield* readSubmission(operation, validated.submissionId);
|
|
@@ -1059,9 +1100,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1059
1100
|
});
|
|
1060
1101
|
const claimJoining = Effect.fnUntraced(function* (request) {
|
|
1061
1102
|
const operation = "ledger claim joining";
|
|
1062
|
-
const validated = yield*
|
|
1103
|
+
const validated = yield* decodeClaimJoiningRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1063
1104
|
yield* hitFailpoint("ledger:claim-joining:before", operation);
|
|
1064
|
-
const claims = yield*
|
|
1105
|
+
const claims = yield* owner.withMutation(Effect.gen(function* () {
|
|
1065
1106
|
const host = yield* requireSubmission(operation, validated.hostSubmissionId);
|
|
1066
1107
|
if (host.thread_id !== validated.threadId) return yield* LedgerError.make({
|
|
1067
1108
|
operation,
|
|
@@ -1069,36 +1110,42 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1069
1110
|
});
|
|
1070
1111
|
yield* requireOwner(operation, host);
|
|
1071
1112
|
if ((yield* cached(rows.workerStops.by("thread_id", validated.threadId), operation)).length > 0) return [];
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
const
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1113
|
+
const later = yield* submissionViews.matching(JSON.stringify([
|
|
1114
|
+
"joining-suffix",
|
|
1115
|
+
validated.threadId,
|
|
1116
|
+
host.queue_sequence
|
|
1117
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > host.queue_sequence, sql`
|
|
1118
|
+
SELECT ${submissionColumns}
|
|
1119
|
+
FROM effect_agent_submissions
|
|
1120
|
+
WHERE thread_id = ${validated.threadId}
|
|
1121
|
+
AND queue_sequence > ${host.queue_sequence}
|
|
1122
|
+
ORDER BY queue_sequence ASC
|
|
1123
|
+
`, 0).pipe(Effect.mapError((error) => error._tag === "SqlError" ? sqlFailure(operation)(error) : internalFailure(operation)(error)));
|
|
1124
|
+
if (later.length === 0) return [];
|
|
1125
|
+
return yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
1126
|
+
const claimed = [];
|
|
1127
|
+
for (const row of later) {
|
|
1128
|
+
if (claimed.length >= validated.maxCount) break;
|
|
1129
|
+
if ((row.state === "joining" || row.state === "joined") && row.joined_host_submission_id === validated.hostSubmissionId) continue;
|
|
1130
|
+
if (row.state === "settled" && row.settled_outcome === "aborted") continue;
|
|
1131
|
+
if (row.state !== "ready") break;
|
|
1132
|
+
const canonical = yield* readCanonicalSettlement(operation, row);
|
|
1133
|
+
if (canonical?.settlement.outcome === "aborted") continue;
|
|
1134
|
+
if (canonical !== void 0) break;
|
|
1135
|
+
yield* sql`
|
|
1090
1136
|
UPDATE effect_agent_submissions
|
|
1091
1137
|
SET state = 'joining', joined_host_submission_id = ${validated.hostSubmissionId}
|
|
1092
1138
|
WHERE submission_id = ${row.submission_id}
|
|
1093
1139
|
RETURNING *, ${definitionJson(sql)} AS agent_digests_json`.pipe(rows.submissions.write, Effect.mapError(internalFailure(operation)));
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1140
|
+
const inputPayload = yield* parseStoredJsonText(row.input_json).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_submissions", row.submission_id, error.message)));
|
|
1141
|
+
claimed.push(yield* decodeJoiningClaim({
|
|
1142
|
+
submissionId: row.submission_id,
|
|
1143
|
+
queueSequence: row.queue_sequence,
|
|
1144
|
+
inputPayload
|
|
1145
|
+
}).pipe(Effect.mapError(internalFailure(operation))));
|
|
1146
|
+
}
|
|
1147
|
+
return claimed;
|
|
1148
|
+
}));
|
|
1102
1149
|
}));
|
|
1103
1150
|
yield* hitFailpoint("ledger:claim-joining:after", operation);
|
|
1104
1151
|
return claims;
|
|
@@ -1668,20 +1715,21 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1668
1715
|
ORDER BY thread_id ASC, queue_sequence ASC
|
|
1669
1716
|
LIMIT ${SCAN_PAGE_SIZE}
|
|
1670
1717
|
`).pipe(Effect.mapError(sqlFailure(operation)));
|
|
1671
|
-
const decoded = yield* decodeRows(
|
|
1718
|
+
const decoded = yield* decodeRows(SubmissionWorkItems, "effect_agent_submissions", "nonterminal_scan", rows, "SubmissionWorkItem").pipe(Effect.mapError(internalFailure(operation)));
|
|
1672
1719
|
const last = decoded[decoded.length - 1];
|
|
1673
1720
|
return [decoded, last === void 0 || decoded.length < SCAN_PAGE_SIZE ? Option.none() : Option.some({
|
|
1674
1721
|
threadId: last.threadId,
|
|
1675
1722
|
queueSequence: last.queueSequence
|
|
1676
1723
|
})];
|
|
1677
1724
|
});
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1725
|
+
const activeNonterminal = cached(workRows.matching("nonterminal", (row) => row.state !== "settled", sql`SELECT submission_id, thread_id, queue_sequence, principal, idempotency_key,
|
|
1726
|
+
deployment_id, receipt_id, state
|
|
1727
|
+
FROM effect_agent_submissions WHERE state <> 'settled' LIMIT 129`, 128), "ledger scan nonterminal");
|
|
1728
|
+
const boundedNonterminal = state.read(Effect.gen(function* () {
|
|
1729
|
+
const active = yield* activeNonterminal;
|
|
1730
|
+
if (active.length > 128) return void 0;
|
|
1683
1731
|
const sorted = [...active].sort((left, right) => left.thread_id < right.thread_id ? -1 : left.thread_id > right.thread_id ? 1 : left.queue_sequence - right.queue_sequence);
|
|
1684
|
-
|
|
1732
|
+
return yield* decodeSubmissionWorkItems(sorted.map((row) => ({
|
|
1685
1733
|
submissionId: row.submission_id,
|
|
1686
1734
|
threadId: row.thread_id,
|
|
1687
1735
|
queueSequence: row.queue_sequence,
|
|
@@ -1691,11 +1739,13 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1691
1739
|
receiptId: row.receipt_id,
|
|
1692
1740
|
state: row.state
|
|
1693
1741
|
}))).pipe(Effect.mapError(internalFailure("ledger scan nonterminal")));
|
|
1694
|
-
|
|
1695
|
-
|
|
1742
|
+
}));
|
|
1743
|
+
const pagedNonterminal = Stream.paginate(void 0, scanPage);
|
|
1744
|
+
const scanNonterminal = Stream.unwrap(Effect.map(boundedNonterminal, (work) => work === void 0 ? pagedNonterminal : Stream.fromIterable(work)));
|
|
1745
|
+
const listNonterminal = Effect.filterOrElse(boundedNonterminal, (work) => work !== void 0, () => Stream.runCollect(pagedNonterminal));
|
|
1696
1746
|
const readAbortIntentForSubmission = Effect.fnUntraced(function* (request) {
|
|
1697
1747
|
const operation = "ledger read abort intent";
|
|
1698
|
-
const validated = yield*
|
|
1748
|
+
const validated = yield* decodeAbortIntentRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1699
1749
|
return yield* state.read(Effect.gen(function* () {
|
|
1700
1750
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
1701
1751
|
const intent = yield* readAbortIntent(operation, validated.submissionId);
|
|
@@ -1704,7 +1754,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1704
1754
|
});
|
|
1705
1755
|
const loadRecoverySnapshot = Effect.fnUntraced(function* (request) {
|
|
1706
1756
|
const operation = "ledger load recovery snapshot";
|
|
1707
|
-
const validated = yield*
|
|
1757
|
+
const validated = yield* decodeRecoverySnapshotRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1708
1758
|
return yield* state.read(Effect.gen(function* () {
|
|
1709
1759
|
const submissionRow = yield* requireSubmission(operation, validated.submissionId);
|
|
1710
1760
|
const submission = yield* decodeSubmissionSnapshot(operation, submissionRow);
|
|
@@ -1811,6 +1861,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1811
1861
|
beginChildBudgetRelease,
|
|
1812
1862
|
releaseChildBudget,
|
|
1813
1863
|
scanNonterminal,
|
|
1864
|
+
listNonterminal,
|
|
1814
1865
|
loadRecoverySnapshot,
|
|
1815
1866
|
readAbortIntent: readAbortIntentForSubmission
|
|
1816
1867
|
})).pipe(Context.add(StorageOwner, owner), Context.add(SettlementPublisher, { publish }));
|