@yielded/agent-storage-cloudflare 0.1.0-beta.174 → 0.1.0-beta.176
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.d.mts +1 -1
- package/dist/DoSubmissionLedger.mjs +194 -98
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/{DoThreadStore-Bd4fTns3.d.mts → DoThreadStore-BzYJjm4O.d.mts} +18 -8
- package/dist/{DoThreadStore-DyzOZDXK.mjs → DoThreadStore-DG0h5J6u.mjs} +25 -19
- package/dist/DoThreadStore-DG0h5J6u.mjs.map +1 -0
- package/dist/DoThreadStore.d.mts +2 -2
- package/dist/DoThreadStore.mjs +3 -2
- package/dist/PortProtocol.d.mts +7201 -7201
- package/dist/PortRouting.mjs +21 -11
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-ZMAzzENZ.mjs → do-journal-ySC3eXNv.mjs} +144 -45
- package/dist/do-journal-ySC3eXNv.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- 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-BgGOA2Ak.mjs} +4 -3
- package/dist/owned-state-BgGOA2Ak.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoStorageFailpoint.ts +4 -0
- package/src/DoSubmissionLedger.ts +430 -228
- package/src/DoThreadStore.ts +25 -44
- package/src/PortRouting.ts +57 -31
- package/src/internal/do-journal.ts +318 -70
- package/src/internal/migrations.ts +52 -10
- package/src/internal/owned-state.ts +12 -5
- 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/owned-state-DcFh0YNo.mjs.map +0 -1
|
@@ -2,24 +2,24 @@ 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-BgGOA2Ak.mjs";
|
|
6
|
+
import { i as initializeDoJournal, r as decodeRows } from "./do-journal-ySC3eXNv.mjs";
|
|
7
|
+
import { l as prepareCanonicalAppend, o as storageConfigLayer, s as storageFailpointLayer } from "./DoThreadStore-DG0h5J6u.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";
|
|
20
20
|
import { runIdForSubmission } from "@yielded/agent/run-journal";
|
|
21
21
|
import { SettlementPublicationResult, SettlementPublisher, validateCanonicalSettlement, validateJoinedSettlement, validatePublication } from "@yielded/agent/settlement-publisher";
|
|
22
|
-
import { AbortCommand, AbortIntent, AbortIntentRequest, AdmissionAdmitted, AdmissionConflict, AdmissionFence, AdmissionGroup, AdmissionNotAdmitted, AdmissionPolicyError, AdmissionRequest, AdmissionResult, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, Claim, ClaimJoiningRequest, ClaimRequest, FundingOwner, FundingOwnerRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipLost, ParentLinkage, QueueSequence, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReservedChildBudget, RevertJoiningRequest, Settlement, SettlementConflict, SettlementFinalization, SubmissionAdmissionFence, SubmissionLedger, SubmissionLookup, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SubmissionWorkItem, SuspendRequest, SuspensionReason, SuspensionSnapshot, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, UnknownResolutionKind, WorkerLedgerState, WorkerStopCommand, approvalDecisionsCover, settlementFailureFromRecord, submissionAbortRecordId, submissionSettlementBatchId, submissionSettlementRecordId, unknownResolutionKind, unknownResolutionMatchesResult, workerTerminalFromRecord } from "@yielded/agent/submission-ledger";
|
|
22
|
+
import { AbortCommand, AbortIntent, AbortIntentRequest, AdmissionAdmitted, AdmissionConflict, AdmissionFence, AdmissionGroup, AdmissionNotAdmitted, AdmissionPolicyError, AdmissionRequest, AdmissionResult, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, Claim, ClaimJoiningRequest, ClaimRequest, FundingOwner, FundingOwnerRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipLost, ParentLinkage, QueueSequence, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReservedChildBudget, RevertJoiningRequest, Settlement, SettlementConflict, SettlementFinalization, SubmissionAdmissionFence, SubmissionLedger, SubmissionLookup, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SubmissionWorkItem, SuspendRequest, SuspensionReason, SuspensionSnapshot, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, UnknownResolutionKind, WorkerLedgerState, WorkerStopCommand, approvalDecisionsCover, settlementFailureFromRecord, submissionAbortRecordId, submissionInputBatchId, submissionInputRecordId, submissionSettlementBatchId, submissionSettlementRecordId, unknownResolutionKind, unknownResolutionMatchesResult, workerTerminalFromRecord } from "@yielded/agent/submission-ledger";
|
|
23
23
|
import { AssignmentTerminal } from "@yielded/agent/worker";
|
|
24
24
|
//#region src/DoSubmissionLedger.ts
|
|
25
25
|
var DoSubmissionLedger_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -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)));
|
|
@@ -508,8 +524,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
508
524
|
yield* hitFailpoint("ledger:admit:before", operation);
|
|
509
525
|
const result = yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
510
526
|
const keyRowKey = `${validated.threadId}/${validated.principal}/${validated.idempotencyKey}`;
|
|
511
|
-
const
|
|
512
|
-
const existing = yield* decodeSubmissionRows(operation, keyRowKey, existingRows);
|
|
527
|
+
const existing = yield* byKey(validated, operation);
|
|
513
528
|
if (existing.length > 1) return yield* corruptionFailure(operation, "effect_agent_submissions", keyRowKey, "An admission idempotency key returned more than one row.");
|
|
514
529
|
if (existing.length === 1) {
|
|
515
530
|
const sameLinkage = validated.parentLinkage === void 0 ? existing[0].parent_submission_id === null && existing[0].parent_tool_call_id === null : existing[0].parent_submission_id === validated.parentLinkage.parentSubmissionId && existing[0].parent_tool_call_id === validated.parentLinkage.parentToolCallId;
|
|
@@ -550,10 +565,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
550
565
|
SELECT worker_admission_json FROM effect_agent_submissions
|
|
551
566
|
WHERE thread_id=${validated.threadId} ORDER BY queue_sequence LIMIT 1
|
|
552
567
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
553
|
-
const first = yield*
|
|
568
|
+
const first = yield* decodeFirstWorkerAdmissions(firstRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
554
569
|
if (first[0] !== void 0) {
|
|
555
570
|
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 (!
|
|
571
|
+
if (!equivalentWorkerOrigin(previous?.origin, validated.workerAdmission?.origin)) return yield* AdmissionPolicyError.make({
|
|
557
572
|
reason: "refused",
|
|
558
573
|
code: "worker-origin-conflict"
|
|
559
574
|
});
|
|
@@ -573,9 +588,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
573
588
|
FROM effect_agent_submissions
|
|
574
589
|
WHERE thread_id = ${validated.threadId}
|
|
575
590
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
576
|
-
const decodedMax = yield* decodeRows(
|
|
591
|
+
const decodedMax = yield* decodeRows(MaxQueueSequenceRows, "effect_agent_submissions", validated.threadId, maxRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
577
592
|
const queueSequence = yield* decodeQueueSequence((decodedMax[0]?.max_queue_sequence ?? 0) + 1).pipe(Effect.mapError(internalFailure(operation)));
|
|
578
593
|
const now = yield* currentInstant;
|
|
594
|
+
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
595
|
yield* sql`
|
|
580
596
|
INSERT INTO effect_agent_submissions (
|
|
581
597
|
submission_id,
|
|
@@ -591,6 +607,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
591
607
|
receipt_id,
|
|
592
608
|
state,
|
|
593
609
|
created_at,
|
|
610
|
+
ready_at,
|
|
594
611
|
parent_submission_id,
|
|
595
612
|
parent_tool_call_id,
|
|
596
613
|
admission_group,
|
|
@@ -609,8 +626,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
609
626
|
${inputJson},
|
|
610
627
|
${validated.inputDigest},
|
|
611
628
|
${mintedReceiptId},
|
|
612
|
-
|
|
629
|
+
${ready ? "ready" : "admitted"},
|
|
613
630
|
${now.iso},
|
|
631
|
+
${ready ? now.iso : null},
|
|
614
632
|
${validated.parentLinkage?.parentSubmissionId ?? null},
|
|
615
633
|
${validated.parentLinkage?.parentToolCallId ?? null},
|
|
616
634
|
${validated.admissionGroup ?? null},
|
|
@@ -622,6 +640,11 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
622
640
|
if (queueSequence === 1) {
|
|
623
641
|
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
642
|
}
|
|
643
|
+
submissionViews.seedMatching(JSON.stringify([
|
|
644
|
+
"joining-suffix",
|
|
645
|
+
validated.threadId,
|
|
646
|
+
queueSequence
|
|
647
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > queueSequence, [], 0);
|
|
625
648
|
rows.aborts.seed("submission_id", mintedSubmissionId, []);
|
|
626
649
|
rows.submissions.seed("joined_host_submission_id", mintedSubmissionId, []);
|
|
627
650
|
rows.approvals.seed("submission_id", mintedSubmissionId, []);
|
|
@@ -629,13 +652,18 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
629
652
|
rows.childReservations.seed("parent_submission_id", mintedSubmissionId, []);
|
|
630
653
|
rows.childSettlements.seed("parent_submission_id", mintedSubmissionId, []);
|
|
631
654
|
yield* recordProgress("submission", operation);
|
|
632
|
-
|
|
655
|
+
const admitted = yield* decodeAdmissionResult({
|
|
633
656
|
submissionId: mintedSubmissionId,
|
|
634
657
|
receiptId: mintedReceiptId,
|
|
635
658
|
queueSequence,
|
|
636
|
-
state: "admitted",
|
|
659
|
+
state: ready ? "ready" : "admitted",
|
|
637
660
|
replayed: false
|
|
638
661
|
}).pipe(Effect.mapError(internalFailure(operation)));
|
|
662
|
+
if (ready && lifecycle !== void 0) yield* retainLifecycle(yield* requireSubmission(operation, mintedSubmissionId), {
|
|
663
|
+
_tag: "SubmissionReady",
|
|
664
|
+
submissionId: admitted.submissionId
|
|
665
|
+
});
|
|
666
|
+
return admitted;
|
|
639
667
|
}));
|
|
640
668
|
yield* hitFailpoint("ledger:admit:after", operation);
|
|
641
669
|
return result;
|
|
@@ -685,14 +713,13 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
685
713
|
}, state.read);
|
|
686
714
|
const lookup = Effect.fnUntraced(function* (request) {
|
|
687
715
|
const operation = "ledger lookup";
|
|
688
|
-
const validated = yield*
|
|
716
|
+
const validated = yield* decodeSubmissionLookupType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
689
717
|
if (validated._tag === "SubmissionLookupById") {
|
|
690
718
|
const row = yield* readSubmission(operation, validated.submissionId);
|
|
691
719
|
if (Option.isNone(row)) return Option.none();
|
|
692
720
|
return Option.some(yield* decodeSubmissionSnapshot(operation, row.value));
|
|
693
721
|
}
|
|
694
|
-
const
|
|
695
|
-
const decoded = yield* decodeSubmissionRows(operation, `${validated.threadId}/${validated.principal}/${validated.idempotencyKey}`, foundRows);
|
|
722
|
+
const decoded = yield* byKey(validated, operation);
|
|
696
723
|
if (decoded.length > 1) return yield* corruptionFailure(operation, "effect_agent_submissions", `${validated.threadId}/${validated.principal}/${validated.idempotencyKey}`, "An admission idempotency key returned more than one row.");
|
|
697
724
|
if (decoded.length === 0) return Option.none();
|
|
698
725
|
return Option.some(yield* decodeSubmissionSnapshot(operation, decoded[0]));
|
|
@@ -700,20 +727,30 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
700
727
|
const resolveAdmission = Effect.fnUntraced(function* (request) {
|
|
701
728
|
const operation = "ledger resolve admission";
|
|
702
729
|
const validated = yield* Schema.decodeEffect(Schema.toType(SubmissionLookupByKey))(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
703
|
-
const
|
|
704
|
-
const decoded = yield* decodeSubmissionRows(operation, `${validated.threadId}/${validated.principal}/${validated.idempotencyKey}`, foundRows);
|
|
730
|
+
const decoded = yield* byKey(validated, operation);
|
|
705
731
|
if (decoded.length > 1) return yield* corruptionFailure(operation, "effect_agent_submissions", `${validated.threadId}/${validated.principal}/${validated.idempotencyKey}`, "An admission idempotency key returned more than one row.");
|
|
706
732
|
if (decoded.length === 0) return AdmissionNotAdmitted.make();
|
|
707
733
|
return AdmissionAdmitted.make({ submission: yield* decodeSubmissionSnapshot(operation, decoded[0]) });
|
|
708
734
|
});
|
|
709
735
|
const selectHead = Effect.fn("DoSubmissionLedger.selectHead")(function* (request) {
|
|
710
736
|
const operation = "ledger select head";
|
|
711
|
-
const validated = yield*
|
|
737
|
+
const validated = yield* decodeClaimRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
712
738
|
const attemptId = `attempt-${yield* mintUuid(operation)}`;
|
|
713
739
|
yield* hitFailpoint("ledger:claim:before", operation);
|
|
714
740
|
const claimed = yield* owner.withMutation(Effect.gen(function* () {
|
|
715
741
|
if (owner.hasOwner(validated.threadId)) return Option.none();
|
|
716
|
-
const
|
|
742
|
+
const active = yield* activeNonterminal;
|
|
743
|
+
const heads = [];
|
|
744
|
+
const limit = validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1;
|
|
745
|
+
if (active.length <= 128) {
|
|
746
|
+
const candidates = active.filter((row) => row.thread_id === validated.threadId).sort((left, right) => left.queue_sequence - right.queue_sequence);
|
|
747
|
+
for (const candidate of candidates) {
|
|
748
|
+
if (candidate.state === "unknown" && Option.isNone(yield* readAbortIntent(operation, candidate.submission_id))) continue;
|
|
749
|
+
heads.push(yield* requireSubmission(operation, candidate.submission_id));
|
|
750
|
+
if (heads.length === limit) break;
|
|
751
|
+
}
|
|
752
|
+
} else {
|
|
753
|
+
const headRows = yield* sql`
|
|
717
754
|
SELECT ${submissionColumns}
|
|
718
755
|
FROM effect_agent_submissions
|
|
719
756
|
WHERE thread_id = ${validated.threadId}
|
|
@@ -727,7 +764,8 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
727
764
|
ORDER BY queue_sequence ASC
|
|
728
765
|
LIMIT ${validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1}
|
|
729
766
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
730
|
-
|
|
767
|
+
heads.push(...yield* decodeSubmissionRows(operation, validated.threadId, headRows));
|
|
768
|
+
}
|
|
731
769
|
if (heads.length === 0) return Option.none();
|
|
732
770
|
let head = heads[0];
|
|
733
771
|
if (validated.handoff !== void 0) {
|
|
@@ -752,31 +790,76 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
752
790
|
yield* hitFailpoint("ledger:claim:after", operation);
|
|
753
791
|
return claimed;
|
|
754
792
|
});
|
|
793
|
+
const markInputAppliedInTransaction = Effect.fnUntraced(function* (validated) {
|
|
794
|
+
const operation = "ledger mark input applied";
|
|
795
|
+
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
796
|
+
yield* requireOwner(operation, submission);
|
|
797
|
+
if (submission.input_applied_record_id !== null) {
|
|
798
|
+
if (submission.input_applied_record_id === validated.recordId && submission.input_applied_sequence === validated.sequence) return;
|
|
799
|
+
return yield* corruptionFailure(operation, "effect_agent_submissions", validated.submissionId, "A different canonical input marker is already recorded for this Submission.");
|
|
800
|
+
}
|
|
801
|
+
yield* sql`
|
|
802
|
+
UPDATE effect_agent_submissions
|
|
803
|
+
SET
|
|
804
|
+
input_applied_record_id = ${validated.recordId},
|
|
805
|
+
input_applied_sequence = ${validated.sequence},
|
|
806
|
+
state = CASE
|
|
807
|
+
WHEN state IN ('admitted', 'ready') THEN 'input-applied'
|
|
808
|
+
ELSE state
|
|
809
|
+
END
|
|
810
|
+
WHERE submission_id = ${validated.submissionId}
|
|
811
|
+
RETURNING *, ${definitionJson(sql)} AS agent_digests_json`.pipe(rows.submissions.write, Effect.mapError(internalFailure(operation)));
|
|
812
|
+
});
|
|
755
813
|
const markInputApplied = Effect.fnUntraced(function* (request) {
|
|
756
814
|
const operation = "ledger mark input applied";
|
|
757
|
-
const validated = yield*
|
|
815
|
+
const validated = yield* decodeMarkInputAppliedRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
758
816
|
yield* hitFailpoint("ledger:mark-input-applied:before", operation);
|
|
759
|
-
yield* inWriteTransaction(operation,
|
|
760
|
-
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
761
|
-
yield* requireOwner(operation, submission);
|
|
762
|
-
if (submission.input_applied_record_id !== null) {
|
|
763
|
-
if (submission.input_applied_record_id === validated.recordId && submission.input_applied_sequence === validated.sequence) return;
|
|
764
|
-
return yield* corruptionFailure(operation, "effect_agent_submissions", validated.submissionId, "A different canonical input marker is already recorded for this Submission.");
|
|
765
|
-
}
|
|
766
|
-
yield* sql`
|
|
767
|
-
UPDATE effect_agent_submissions
|
|
768
|
-
SET
|
|
769
|
-
input_applied_record_id = ${validated.recordId},
|
|
770
|
-
input_applied_sequence = ${validated.sequence},
|
|
771
|
-
state = CASE
|
|
772
|
-
WHEN state IN ('admitted', 'ready') THEN 'input-applied'
|
|
773
|
-
ELSE state
|
|
774
|
-
END
|
|
775
|
-
WHERE submission_id = ${validated.submissionId}
|
|
776
|
-
RETURNING *, ${definitionJson(sql)} AS agent_digests_json`.pipe(rows.submissions.write, Effect.mapError(internalFailure(operation)));
|
|
777
|
-
}));
|
|
817
|
+
yield* inWriteTransaction(operation, markInputAppliedInTransaction(validated));
|
|
778
818
|
yield* hitFailpoint("ledger:mark-input-applied:after", operation);
|
|
779
819
|
});
|
|
820
|
+
const appendInput = Effect.fnUntraced(function* (submissionId, request) {
|
|
821
|
+
const operation = "append original input and context";
|
|
822
|
+
const prepared = yield* prepareCanonicalAppend(request).pipe(Effect.provideService(Crypto.Crypto, crypto));
|
|
823
|
+
const record = prepared.request.batch.records[0];
|
|
824
|
+
const context = prepared.request.executions?.flatMap((update) => update.facts ?? []).find(({ payload }) => payload._tag === "RunContextRecorded");
|
|
825
|
+
if (prepared.request.executions?.length !== 1 || prepared.request.executions[0]?.previousRevision !== 0 || prepared.request.batch.records.length !== 1 || record?.payload._tag !== "UserInputRecorded" || record.payload.kind !== "user" || record.payload.submissionId !== submissionId || record.payload.runId !== runIdForSubmission(submissionId) || record.recordId !== submissionInputRecordId(submissionId) || prepared.request.batch.batchId !== submissionInputBatchId(submissionId) || context?.payload._tag === "RunContextRecorded" && context.payload.historyThrough !== prepared.request.expectedTailSequence) return yield* ThreadStoreError.make({
|
|
826
|
+
operation,
|
|
827
|
+
message: "Original input publication has a different context boundary"
|
|
828
|
+
});
|
|
829
|
+
const mapError = (cause) => ThreadStoreError.make({
|
|
830
|
+
operation,
|
|
831
|
+
message: cause.message,
|
|
832
|
+
cause
|
|
833
|
+
});
|
|
834
|
+
yield* journal.prepareAppend(prepared.raw).pipe(Effect.mapError(mapError));
|
|
835
|
+
return yield* owner.withProgress(prepared.request.threadId, owner.withMutation(Effect.gen(function* () {
|
|
836
|
+
yield* hitFailpoint("append:before", operation);
|
|
837
|
+
yield* hitFailpoint("ledger:mark-input-applied:before", operation);
|
|
838
|
+
const result = yield* journal.withWriteTransaction(operation)(Effect.gen(function* () {
|
|
839
|
+
const submission = yield* requireSubmission(operation, submissionId);
|
|
840
|
+
yield* requireOwner(operation, submission);
|
|
841
|
+
if (submission.thread_id !== prepared.request.threadId) return yield* LedgerError.make({
|
|
842
|
+
operation,
|
|
843
|
+
message: "Original input belongs to another Thread"
|
|
844
|
+
});
|
|
845
|
+
const result = yield* journal.appendPrepared(prepared.raw);
|
|
846
|
+
yield* markInputAppliedInTransaction(MarkInputAppliedRequest.make({
|
|
847
|
+
submissionId,
|
|
848
|
+
recordId: record.recordId,
|
|
849
|
+
sequence: result.firstSequence
|
|
850
|
+
}));
|
|
851
|
+
return result;
|
|
852
|
+
})).pipe(Effect.mapError((error) => error._tag === "DoAppendConflict" ? AppendConflict.make({
|
|
853
|
+
threadId: prepared.request.threadId,
|
|
854
|
+
batchId: prepared.request.batch.batchId,
|
|
855
|
+
reason: error.reason,
|
|
856
|
+
...error.actualTailSequence === void 0 ? {} : { actualTailSequence: error.actualTailSequence }
|
|
857
|
+
}) : error._tag === "OwnershipLost" ? error : mapError(error)));
|
|
858
|
+
yield* hitFailpoint("ledger:mark-input-applied:after", operation);
|
|
859
|
+
yield* hitFailpoint("append:after", operation);
|
|
860
|
+
return result;
|
|
861
|
+
}).pipe(Effect.mapError((error) => error._tag === "OwnershipLost" || error._tag === "ThreadStoreError" || error._tag === "AppendConflict" ? error : mapError(error)))));
|
|
862
|
+
});
|
|
780
863
|
const publish = Effect.fn("DoSubmissionLedger.publishSettlement")(function* (input) {
|
|
781
864
|
const operation = "publish settlement";
|
|
782
865
|
const { request, record, settlement } = yield* validatePublication(input);
|
|
@@ -899,7 +982,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
899
982
|
});
|
|
900
983
|
const finalizeSettlement = Effect.fn("DoSubmissionLedger.finalizeSettlement")(function* (request) {
|
|
901
984
|
const operation = "ledger finalize settlement";
|
|
902
|
-
const validated = yield*
|
|
985
|
+
const validated = yield* decodeSettlementFinalizationType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
903
986
|
yield* hitFailpoint("ledger:finalize-settlement:before", operation);
|
|
904
987
|
const replay = yield* state.read(Effect.gen(function* () {
|
|
905
988
|
const submission = yield* readSubmission(operation, validated.submissionId);
|
|
@@ -1059,9 +1142,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1059
1142
|
});
|
|
1060
1143
|
const claimJoining = Effect.fnUntraced(function* (request) {
|
|
1061
1144
|
const operation = "ledger claim joining";
|
|
1062
|
-
const validated = yield*
|
|
1145
|
+
const validated = yield* decodeClaimJoiningRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1063
1146
|
yield* hitFailpoint("ledger:claim-joining:before", operation);
|
|
1064
|
-
const claims = yield*
|
|
1147
|
+
const claims = yield* owner.withMutation(Effect.gen(function* () {
|
|
1065
1148
|
const host = yield* requireSubmission(operation, validated.hostSubmissionId);
|
|
1066
1149
|
if (host.thread_id !== validated.threadId) return yield* LedgerError.make({
|
|
1067
1150
|
operation,
|
|
@@ -1069,36 +1152,42 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1069
1152
|
});
|
|
1070
1153
|
yield* requireOwner(operation, host);
|
|
1071
1154
|
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
|
-
|
|
1155
|
+
const later = yield* submissionViews.matching(JSON.stringify([
|
|
1156
|
+
"joining-suffix",
|
|
1157
|
+
validated.threadId,
|
|
1158
|
+
host.queue_sequence
|
|
1159
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > host.queue_sequence, sql`
|
|
1160
|
+
SELECT ${submissionColumns}
|
|
1161
|
+
FROM effect_agent_submissions
|
|
1162
|
+
WHERE thread_id = ${validated.threadId}
|
|
1163
|
+
AND queue_sequence > ${host.queue_sequence}
|
|
1164
|
+
ORDER BY queue_sequence ASC
|
|
1165
|
+
`, 0).pipe(Effect.mapError((error) => error._tag === "SqlError" ? sqlFailure(operation)(error) : internalFailure(operation)(error)));
|
|
1166
|
+
if (later.length === 0) return [];
|
|
1167
|
+
return yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
1168
|
+
const claimed = [];
|
|
1169
|
+
for (const row of later) {
|
|
1170
|
+
if (claimed.length >= validated.maxCount) break;
|
|
1171
|
+
if ((row.state === "joining" || row.state === "joined") && row.joined_host_submission_id === validated.hostSubmissionId) continue;
|
|
1172
|
+
if (row.state === "settled" && row.settled_outcome === "aborted") continue;
|
|
1173
|
+
if (row.state !== "ready") break;
|
|
1174
|
+
const canonical = yield* readCanonicalSettlement(operation, row);
|
|
1175
|
+
if (canonical?.settlement.outcome === "aborted") continue;
|
|
1176
|
+
if (canonical !== void 0) break;
|
|
1177
|
+
yield* sql`
|
|
1090
1178
|
UPDATE effect_agent_submissions
|
|
1091
1179
|
SET state = 'joining', joined_host_submission_id = ${validated.hostSubmissionId}
|
|
1092
1180
|
WHERE submission_id = ${row.submission_id}
|
|
1093
1181
|
RETURNING *, ${definitionJson(sql)} AS agent_digests_json`.pipe(rows.submissions.write, Effect.mapError(internalFailure(operation)));
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1182
|
+
const inputPayload = yield* parseStoredJsonText(row.input_json).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_submissions", row.submission_id, error.message)));
|
|
1183
|
+
claimed.push(yield* decodeJoiningClaim({
|
|
1184
|
+
submissionId: row.submission_id,
|
|
1185
|
+
queueSequence: row.queue_sequence,
|
|
1186
|
+
inputPayload
|
|
1187
|
+
}).pipe(Effect.mapError(internalFailure(operation))));
|
|
1188
|
+
}
|
|
1189
|
+
return claimed;
|
|
1190
|
+
}));
|
|
1102
1191
|
}));
|
|
1103
1192
|
yield* hitFailpoint("ledger:claim-joining:after", operation);
|
|
1104
1193
|
return claims;
|
|
@@ -1668,20 +1757,21 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1668
1757
|
ORDER BY thread_id ASC, queue_sequence ASC
|
|
1669
1758
|
LIMIT ${SCAN_PAGE_SIZE}
|
|
1670
1759
|
`).pipe(Effect.mapError(sqlFailure(operation)));
|
|
1671
|
-
const decoded = yield* decodeRows(
|
|
1760
|
+
const decoded = yield* decodeRows(SubmissionWorkItems, "effect_agent_submissions", "nonterminal_scan", rows, "SubmissionWorkItem").pipe(Effect.mapError(internalFailure(operation)));
|
|
1672
1761
|
const last = decoded[decoded.length - 1];
|
|
1673
1762
|
return [decoded, last === void 0 || decoded.length < SCAN_PAGE_SIZE ? Option.none() : Option.some({
|
|
1674
1763
|
threadId: last.threadId,
|
|
1675
1764
|
queueSequence: last.queueSequence
|
|
1676
1765
|
})];
|
|
1677
1766
|
});
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1767
|
+
const activeNonterminal = cached(workRows.matching("nonterminal", (row) => row.state !== "settled", sql`SELECT submission_id, thread_id, queue_sequence, principal, idempotency_key,
|
|
1768
|
+
deployment_id, receipt_id, state
|
|
1769
|
+
FROM effect_agent_submissions WHERE state <> 'settled' LIMIT 129`, 128), "ledger scan nonterminal");
|
|
1770
|
+
const boundedNonterminal = state.read(Effect.gen(function* () {
|
|
1771
|
+
const active = yield* activeNonterminal;
|
|
1772
|
+
if (active.length > 128) return void 0;
|
|
1683
1773
|
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
|
-
|
|
1774
|
+
return yield* decodeSubmissionWorkItems(sorted.map((row) => ({
|
|
1685
1775
|
submissionId: row.submission_id,
|
|
1686
1776
|
threadId: row.thread_id,
|
|
1687
1777
|
queueSequence: row.queue_sequence,
|
|
@@ -1691,11 +1781,13 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1691
1781
|
receiptId: row.receipt_id,
|
|
1692
1782
|
state: row.state
|
|
1693
1783
|
}))).pipe(Effect.mapError(internalFailure("ledger scan nonterminal")));
|
|
1694
|
-
|
|
1695
|
-
|
|
1784
|
+
}));
|
|
1785
|
+
const pagedNonterminal = Stream.paginate(void 0, scanPage);
|
|
1786
|
+
const scanNonterminal = Stream.unwrap(Effect.map(boundedNonterminal, (work) => work === void 0 ? pagedNonterminal : Stream.fromIterable(work)));
|
|
1787
|
+
const listNonterminal = Effect.filterOrElse(boundedNonterminal, (work) => work !== void 0, () => Stream.runCollect(pagedNonterminal));
|
|
1696
1788
|
const readAbortIntentForSubmission = Effect.fnUntraced(function* (request) {
|
|
1697
1789
|
const operation = "ledger read abort intent";
|
|
1698
|
-
const validated = yield*
|
|
1790
|
+
const validated = yield* decodeAbortIntentRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1699
1791
|
return yield* state.read(Effect.gen(function* () {
|
|
1700
1792
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
1701
1793
|
const intent = yield* readAbortIntent(operation, validated.submissionId);
|
|
@@ -1704,7 +1796,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1704
1796
|
});
|
|
1705
1797
|
const loadRecoverySnapshot = Effect.fnUntraced(function* (request) {
|
|
1706
1798
|
const operation = "ledger load recovery snapshot";
|
|
1707
|
-
const validated = yield*
|
|
1799
|
+
const validated = yield* decodeRecoverySnapshotRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1708
1800
|
return yield* state.read(Effect.gen(function* () {
|
|
1709
1801
|
const submissionRow = yield* requireSubmission(operation, validated.submissionId);
|
|
1710
1802
|
const submission = yield* decodeSubmissionSnapshot(operation, submissionRow);
|
|
@@ -1717,8 +1809,8 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1717
1809
|
const abortRow = yield* readAbortIntent(operation, validated.submissionId);
|
|
1718
1810
|
if (Option.isSome(abortRow)) abortIntent = yield* abortIntentFromRow(operation, submissionRow, validated.submissionId, abortRow.value);
|
|
1719
1811
|
const joinRows = (yield* cached(rows.submissions.by("joined_host_submission_id", validated.submissionId), operation)).filter((row) => row.joined_host_submission_id === validated.submissionId).sort((a, b) => a.queue_sequence - b.queue_sequence);
|
|
1720
|
-
const
|
|
1721
|
-
const
|
|
1812
|
+
const joins = [];
|
|
1813
|
+
for (const row of joinRows) joins.push(yield* decodeJoinSnapshot({
|
|
1722
1814
|
submissionId: row.submission_id,
|
|
1723
1815
|
state: row.state,
|
|
1724
1816
|
hostSubmissionId: validated.submissionId
|
|
@@ -1734,16 +1826,18 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1734
1826
|
}).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_submissions", validated.submissionId, error.message)));
|
|
1735
1827
|
}
|
|
1736
1828
|
const decisionRows = yield* readApprovalDecisions(operation, validated.submissionId);
|
|
1737
|
-
const approvalDecisions =
|
|
1829
|
+
const approvalDecisions = [];
|
|
1830
|
+
for (const row of decisionRows) approvalDecisions.push(yield* approvalIntentFromRow(operation, row));
|
|
1738
1831
|
const resolutionRows = yield* readUnknownResolutions(operation, validated.submissionId);
|
|
1739
|
-
const unknownResolutions =
|
|
1832
|
+
const unknownResolutions = [];
|
|
1833
|
+
for (const row of resolutionRows) unknownResolutions.push(yield* unknownResolutionIntentFromRow(operation, row));
|
|
1740
1834
|
const childReservationRows = (yield* cached(rows.childReservations.by("parent_submission_id", validated.submissionId), operation)).filter((row) => row.parent_submission_id === validated.submissionId).sort((a, b) => a.parent_tool_call_id.localeCompare(b.parent_tool_call_id));
|
|
1741
|
-
const
|
|
1742
|
-
const
|
|
1835
|
+
const childReservations = [];
|
|
1836
|
+
for (const row of childReservationRows) childReservations.push(yield* childReservationSnapshotFromRow(operation, row));
|
|
1743
1837
|
const markers = yield* readChildSettlementMarkers(operation, validated.submissionId);
|
|
1744
1838
|
const markersByChild = new Map(markers.map((row) => [row.child_submission_id, row]));
|
|
1745
1839
|
const childAttachments = [];
|
|
1746
|
-
for (const row of
|
|
1840
|
+
for (const row of childReservationRows) {
|
|
1747
1841
|
if (row.child_submission_id === null) continue;
|
|
1748
1842
|
const child = yield* readSubmission(operation, row.child_submission_id);
|
|
1749
1843
|
if (Option.isSome(child)) {
|
|
@@ -1794,6 +1888,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1794
1888
|
resolveAdmission,
|
|
1795
1889
|
selectHead,
|
|
1796
1890
|
markInputApplied,
|
|
1891
|
+
appendInput,
|
|
1797
1892
|
finalizeSettlement: (request) => owner.withMutation(finalizeSettlement(request)),
|
|
1798
1893
|
requestAbort,
|
|
1799
1894
|
stopWorker,
|
|
@@ -1811,6 +1906,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1811
1906
|
beginChildBudgetRelease,
|
|
1812
1907
|
releaseChildBudget,
|
|
1813
1908
|
scanNonterminal,
|
|
1909
|
+
listNonterminal,
|
|
1814
1910
|
loadRecoverySnapshot,
|
|
1815
1911
|
readAbortIntent: readAbortIntentForSubmission
|
|
1816
1912
|
})).pipe(Context.add(StorageOwner, owner), Context.add(SettlementPublisher, { publish }));
|