@yielded/agent 0.1.0-beta.177 → 0.1.0-beta.179
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-Bpg24yCK.d.mts → Admin-NvXFPDIM.d.mts} +26 -6
- package/dist/{DurableAgentRuntime-CGW93k81.mjs → DurableAgentRuntime-CWhu1exp.mjs} +49 -69
- package/dist/DurableAgentRuntime-CWhu1exp.mjs.map +1 -0
- package/dist/{EventSource-A6TB7t-f.d.mts → EventSource-DNyaWmyQ.d.mts} +2 -2
- package/dist/{MessageDelivery-BkWrcQUd.d.mts → MessageDelivery-CLzWJImC.d.mts} +42 -42
- package/dist/{PreparedInputAdmission-DKIfqRZT.d.mts → PreparedInputAdmission-BQ9UCLFS.d.mts} +3 -3
- package/dist/{RunContinuation-D42RFqjS.mjs → RunContinuation-BF95Ncv2.mjs} +9 -11
- package/dist/RunContinuation-BF95Ncv2.mjs.map +1 -0
- package/dist/{RunContinuation-Ce2pR8VD.d.mts → RunContinuation-CL0wBsQE.d.mts} +3 -6
- package/dist/{RunStorage-BRGP3Tcu.mjs → RunStorage-DlfvMfHM.mjs} +20 -6
- package/dist/RunStorage-DlfvMfHM.mjs.map +1 -0
- package/dist/{Subscription-D5sOrmlI.d.mts → Subscription-D2yn6Eo3.d.mts} +2 -2
- package/dist/{SubscriptionInput-CxSXZUiC.d.mts → SubscriptionInput-Cog4x7Rd.d.mts} +2 -2
- package/dist/{ThreadImport-DUcPj5jC.mjs → ThreadImport-BoTfjjrz.mjs} +4 -4
- package/dist/{ThreadImport-DUcPj5jC.mjs.map → ThreadImport-BoTfjjrz.mjs.map} +1 -1
- package/dist/{ThreadImport-C6IiPJMW.d.mts → ThreadImport-em89zmM-.d.mts} +4 -4
- package/dist/{ThreadStore-Cn6FDWX9.mjs → ThreadStore-D2rqtt7k.mjs} +13 -8
- package/dist/ThreadStore-D2rqtt7k.mjs.map +1 -0
- package/dist/{ThreadTransfer-BWnAHIge.mjs → ThreadTransfer-BFolkpEp.mjs} +2 -2
- package/dist/{ThreadTransfer-BWnAHIge.mjs.map → ThreadTransfer-BFolkpEp.mjs.map} +1 -1
- package/dist/{WorkerAdmission-cfiK9aRi.mjs → WorkerAdmission-CtX1HRkm.mjs} +2 -2
- package/dist/{WorkerAdmission-cfiK9aRi.mjs.map → WorkerAdmission-CtX1HRkm.mjs.map} +1 -1
- package/dist/capabilities/BrowserUse.d.mts +36 -18
- package/dist/capabilities/BrowserUse.mjs +43 -11
- package/dist/capabilities/BrowserUse.mjs.map +1 -1
- package/dist/capabilities/CodeMode.mjs +1 -0
- package/dist/capabilities/CodeMode.mjs.map +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/AgentRegistration.d.mts +1 -1
- package/dist/durable/Certification.d.mts +1 -1
- package/dist/durable/CommittedActivity.d.mts +1 -1
- package/dist/durable/CommittedActivity.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/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/MessageDeliveryStoreConformance.d.mts +2 -2
- package/dist/durable/PersistentHistory.d.mts +1 -1
- package/dist/durable/PersistentHistory.mjs +2 -2
- package/dist/durable/PreparedInputAdmission.d.mts +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/RunStorage.d.mts +1 -1
- package/dist/durable/RunStorage.mjs +1 -1
- package/dist/durable/Scheduling.d.mts +1 -1
- package/dist/durable/SettlementPublisher.d.mts +1 -1
- package/dist/durable/SettlementPublisher.mjs +1 -1
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.mjs +2 -2
- 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/SubscriptionStoreConformance.d.mts +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/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 +3 -3
- package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
- package/dist/durable/ThreadReader.d.mts +1 -1
- package/dist/durable/ThreadReader.mjs +1 -1
- package/dist/durable/ThreadStore.d.mts +2 -2
- package/dist/durable/ThreadStore.mjs +2 -2
- package/dist/durable/ThreadStoreConformance.d.mts +2 -1
- package/dist/durable/ThreadStoreConformance.mjs +2 -2
- 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 +2 -2
- package/dist/durable/WorkerAdmission.d.mts +1 -1
- package/dist/durable/WorkerAdmission.mjs +1 -1
- package/dist/durable/WorkerHost.d.mts +1 -1
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +6 -6
- package/dist/{run-context-reader-BtBPX_nC.d.mts → run-context-reader-kpO9xhP2.d.mts} +2 -2
- package/dist/sandbox/CodeExecutor.d.mts +3 -1
- package/dist/sandbox/CodeExecutor.mjs +3 -1
- package/dist/sandbox/CodeExecutor.mjs.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/BrowserUse.ts +53 -15
- package/src/capabilities/CodeMode.ts +1 -0
- package/src/durable/DurableAgentRuntime.ts +78 -143
- package/src/durable/RunContinuation.ts +44 -32
- package/src/durable/RunStorage.ts +56 -15
- package/src/durable/ThreadStore.ts +11 -0
- package/src/durable/internal/prompt-history-cache.ts +19 -3
- package/src/durable/internal/record-encoding.ts +8 -7
- package/src/sandbox/CodeExecutor.ts +3 -1
- package/dist/DurableAgentRuntime-CGW93k81.mjs.map +0 -1
- package/dist/RunContinuation-D42RFqjS.mjs.map +0 -1
- package/dist/RunStorage-BRGP3Tcu.mjs.map +0 -1
- package/dist/ThreadStore-Cn6FDWX9.mjs.map +0 -1
|
@@ -174,6 +174,7 @@ import {
|
|
|
174
174
|
type CommittedPromptSuffix,
|
|
175
175
|
type PromptHistory,
|
|
176
176
|
} from "./internal/prompt-history-cache.ts";
|
|
177
|
+
import { captureRecord } from "./internal/record-encoding.ts";
|
|
177
178
|
import { RunContextReader } from "./internal/run-context-reader.ts";
|
|
178
179
|
import { readRunContext } from "./internal/run-context.ts";
|
|
179
180
|
import * as ThreadInitialization from "./internal/thread-initialization.ts";
|
|
@@ -403,7 +404,6 @@ import {
|
|
|
403
404
|
getRunInput,
|
|
404
405
|
ThreadReader,
|
|
405
406
|
MAX_THREAD_EXPORT_PAGE_BYTES,
|
|
406
|
-
PreparedAppend,
|
|
407
407
|
type CommitBatch,
|
|
408
408
|
type ExecutionUpdate,
|
|
409
409
|
} from "./ThreadStore.ts";
|
|
@@ -4918,6 +4918,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
4918
4918
|
progressThrough: CanonicalSequence | undefined,
|
|
4919
4919
|
continuation: RunContinuation | undefined,
|
|
4920
4920
|
priorContext: RunJournalContext | undefined,
|
|
4921
|
+
operational: ReadonlyArray<RecordEnvelope>,
|
|
4921
4922
|
journalMetadata: JournalMetadata | undefined,
|
|
4922
4923
|
lineage: AttemptLineage,
|
|
4923
4924
|
approvalDecisions: ReadonlyArray<ApprovalDecisionIntent>,
|
|
@@ -5453,13 +5454,9 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
5453
5454
|
);
|
|
5454
5455
|
});
|
|
5455
5456
|
|
|
5456
|
-
const
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
? activeExecution.value.operational.find(
|
|
5460
|
-
(record) => record.recordId === runCompletedRecordId(runId),
|
|
5461
|
-
)?.payload
|
|
5462
|
-
: undefined;
|
|
5457
|
+
const recordedCompletion = operational.find(
|
|
5458
|
+
(record) => record.recordId === runCompletedRecordId(runId),
|
|
5459
|
+
)?.payload;
|
|
5463
5460
|
|
|
5464
5461
|
if (recordedCompletion !== undefined) {
|
|
5465
5462
|
if (recordedCompletion._tag !== "RunCompleted" || recordedCompletion.runId !== runId) {
|
|
@@ -7830,19 +7827,26 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
7830
7827
|
...(config.estimateCostMicrousd === undefined
|
|
7831
7828
|
? {}
|
|
7832
7829
|
: { estimateCostMicrousd: config.estimateCostMicrousd }),
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7830
|
+
// An exact committed history prefix followed only by this input creates the
|
|
7831
|
+
// initial journal above. There is no resumed accounting to reconstruct or decode.
|
|
7832
|
+
...(freshPrefix !== undefined && continuation === undefined
|
|
7833
|
+
? {}
|
|
7834
|
+
: {
|
|
7835
|
+
resumeUsage: {
|
|
7836
|
+
...journal.usage,
|
|
7837
|
+
...journal.policyUsage,
|
|
7838
|
+
...(journal.usage.modelCalls === 0 &&
|
|
7839
|
+
(journal.usage.unobservedModelCalls ?? 0) === 0 &&
|
|
7840
|
+
!records.some(
|
|
7841
|
+
({ record }) =>
|
|
7842
|
+
record.payload._tag === "ModelResponseInterrupted" &&
|
|
7843
|
+
record.payload.runId === runId,
|
|
7844
|
+
)
|
|
7845
|
+
? emptyRunTotals()
|
|
7846
|
+
: runTotalsFromSummary(yield* currentUsageSummary())),
|
|
7847
|
+
children: childUsageReportsOf(subagentState),
|
|
7848
|
+
},
|
|
7849
|
+
}),
|
|
7846
7850
|
...(journal.contextWindowId === undefined
|
|
7847
7851
|
? {}
|
|
7848
7852
|
: { initialContextWindowId: journal.contextWindowId }),
|
|
@@ -8301,136 +8305,66 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8301
8305
|
const { claim, threadId } = session;
|
|
8302
8306
|
const submissionId = claim.submissionId;
|
|
8303
8307
|
|
|
8304
|
-
// The hint
|
|
8305
|
-
//
|
|
8306
|
-
|
|
8307
|
-
let prepared =
|
|
8308
|
-
freshlyAdmitted && session.withInitialization !== undefined
|
|
8309
|
-
? yield* session.withInitialization(
|
|
8310
|
-
Effect.gen(function* () {
|
|
8311
|
-
const snapshot = yield* ledger.loadRecoverySnapshot(
|
|
8312
|
-
RecoverySnapshotRequest.make({ submissionId }),
|
|
8313
|
-
);
|
|
8314
|
-
|
|
8315
|
-
const submission = snapshot.submission;
|
|
8308
|
+
// The hint selects a read under the existing owner. Only exact empty-Run evidence
|
|
8309
|
+
// permits startup; the initial commit still checks its tail and revision-zero CAS.
|
|
8310
|
+
const preparation = freshlyAdmitted ? yield* session.prepareStart ?? Effect.void : undefined;
|
|
8316
8311
|
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
yield* session.refresh;
|
|
8329
|
-
const before = (yield* session.tail).sequence;
|
|
8330
|
-
|
|
8331
|
-
const view = yield* recoveryView(
|
|
8332
|
-
threadId,
|
|
8333
|
-
before,
|
|
8334
|
-
[submissionId],
|
|
8335
|
-
runIdForSubmission(submissionId),
|
|
8336
|
-
);
|
|
8337
|
-
|
|
8338
|
-
if (
|
|
8339
|
-
view.progress !== undefined ||
|
|
8340
|
-
view.context !== undefined ||
|
|
8341
|
-
view.operational.length !== 0 ||
|
|
8342
|
-
view.records.some(({ record }) => record.payload._tag !== "ThreadCreated")
|
|
8343
|
-
)
|
|
8344
|
-
return undefined;
|
|
8345
|
-
if (session.appendInput !== undefined) {
|
|
8346
|
-
const captured = yield* PreparedAppend.capture(
|
|
8347
|
-
AppendRequest.make({
|
|
8348
|
-
threadId,
|
|
8349
|
-
expectedTailSequence: before,
|
|
8350
|
-
batch: CanonicalBatch.make({
|
|
8351
|
-
batchId: submissionInputBatchId(submissionId),
|
|
8352
|
-
producerId: config.producerId,
|
|
8353
|
-
records: [yield* prepareOriginalInput(submission)],
|
|
8354
|
-
}),
|
|
8355
|
-
}),
|
|
8356
|
-
);
|
|
8357
|
-
|
|
8358
|
-
const record = captured.records[0]!.canonical;
|
|
8312
|
+
let prepared:
|
|
8313
|
+
| {
|
|
8314
|
+
snapshot: RecoverySnapshot;
|
|
8315
|
+
through: CanonicalSequence;
|
|
8316
|
+
view: Omit<Effect.Success<ReturnType<typeof recoveryView>>, "records"> & {
|
|
8317
|
+
readonly records: ReadonlyArray<CanonicalRecordEnvelope>;
|
|
8318
|
+
};
|
|
8319
|
+
start: Effect.Success<ReturnType<typeof makeRunStart>>;
|
|
8320
|
+
input: InitialContextInput;
|
|
8321
|
+
}
|
|
8322
|
+
| undefined;
|
|
8359
8323
|
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
});
|
|
8364
|
-
pendingOriginal = {
|
|
8365
|
-
threadId,
|
|
8366
|
-
sequence: CanonicalSequence.make(before + 1),
|
|
8367
|
-
record,
|
|
8368
|
-
};
|
|
8324
|
+
if (preparation !== undefined) {
|
|
8325
|
+
const { snapshot, identity } = preparation;
|
|
8326
|
+
const before = identity.tailSequence;
|
|
8369
8327
|
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8328
|
+
const captured = yield* Effect.fromResult(
|
|
8329
|
+
captureRecord(yield* prepareOriginalInput(snapshot.submission)),
|
|
8330
|
+
).pipe(
|
|
8331
|
+
Effect.mapError((cause) =>
|
|
8332
|
+
ThreadStoreError.make({
|
|
8333
|
+
operation: "capture startup input",
|
|
8334
|
+
message: cause.message,
|
|
8335
|
+
cause,
|
|
8336
|
+
}),
|
|
8337
|
+
),
|
|
8338
|
+
);
|
|
8377
8339
|
|
|
8378
|
-
|
|
8379
|
-
}
|
|
8380
|
-
const progress = progressWriters.get(session);
|
|
8340
|
+
const record = captured.canonical;
|
|
8381
8341
|
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8342
|
+
if (!isOriginalInputRecord(record))
|
|
8343
|
+
return yield* RunJournalError.make({ message: "Captured startup has no original input" });
|
|
8344
|
+
pendingOriginal = {
|
|
8345
|
+
threadId,
|
|
8346
|
+
sequence: CanonicalSequence.make(before + 1),
|
|
8347
|
+
record,
|
|
8348
|
+
};
|
|
8389
8349
|
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
const records = [...view.records, ...added];
|
|
8350
|
+
const view = {
|
|
8351
|
+
records: identity.records,
|
|
8352
|
+
context: undefined,
|
|
8353
|
+
progress: undefined,
|
|
8354
|
+
progressThrough: undefined,
|
|
8355
|
+
operational: [],
|
|
8356
|
+
};
|
|
8398
8357
|
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8358
|
+
const start = yield* makeRunStart(
|
|
8359
|
+
snapshot.submission,
|
|
8360
|
+
Duration.toMillis(registeredAgent.definition.policy.maxDuration),
|
|
8361
|
+
view.records,
|
|
8362
|
+
view.operational,
|
|
8363
|
+
record,
|
|
8364
|
+
).pipe(Effect.provideService(CurrentRunWriter, session));
|
|
8402
8365
|
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
accepted.throughSequence !== through ||
|
|
8406
|
-
accepted.progress.runId !== runIdForSubmission(submissionId) ||
|
|
8407
|
-
accepted.progress.submissionId !== submissionId
|
|
8408
|
-
)
|
|
8409
|
-
return undefined;
|
|
8410
|
-
|
|
8411
|
-
const start = yield* makeRunStart(
|
|
8412
|
-
submission,
|
|
8413
|
-
Duration.toMillis(registeredAgent.definition.policy.maxDuration),
|
|
8414
|
-
records,
|
|
8415
|
-
view.operational,
|
|
8416
|
-
).pipe(Effect.provideService(CurrentRunWriter, session));
|
|
8417
|
-
|
|
8418
|
-
return {
|
|
8419
|
-
snapshot,
|
|
8420
|
-
through,
|
|
8421
|
-
view: {
|
|
8422
|
-
...view,
|
|
8423
|
-
records,
|
|
8424
|
-
progress: accepted.progress,
|
|
8425
|
-
progressThrough: accepted.throughSequence,
|
|
8426
|
-
operational: accepted.operational,
|
|
8427
|
-
},
|
|
8428
|
-
start,
|
|
8429
|
-
input: undefined,
|
|
8430
|
-
};
|
|
8431
|
-
}),
|
|
8432
|
-
)
|
|
8433
|
-
: undefined;
|
|
8366
|
+
prepared = { snapshot, through: before, view, start, input: pendingOriginal };
|
|
8367
|
+
}
|
|
8434
8368
|
|
|
8435
8369
|
const preparedInput = prepared !== undefined;
|
|
8436
8370
|
|
|
@@ -8941,6 +8875,7 @@ const make = Effect.fnUntraced(function* (bindings: ReadonlyArray<ResolvedBindin
|
|
|
8941
8875
|
view.progressThrough,
|
|
8942
8876
|
view.progress,
|
|
8943
8877
|
view.context,
|
|
8878
|
+
view.operational,
|
|
8944
8879
|
takeJournalMetadata(),
|
|
8945
8880
|
lineage,
|
|
8946
8881
|
approvalDecisionIntents,
|
|
@@ -184,18 +184,25 @@ const captureFacts = (batch: CommitBatch) =>
|
|
|
184
184
|
Result.gen(function* () {
|
|
185
185
|
const inputs = batch.records;
|
|
186
186
|
|
|
187
|
-
const {
|
|
187
|
+
const {
|
|
188
|
+
batchId,
|
|
189
|
+
producerId,
|
|
190
|
+
records: slots,
|
|
191
|
+
} = validateBatchShape({
|
|
188
192
|
batchId: batch.batchId,
|
|
189
193
|
producerId: batch.producerId,
|
|
190
194
|
records: inputs,
|
|
191
195
|
});
|
|
192
196
|
|
|
193
|
-
const
|
|
194
|
-
const records
|
|
197
|
+
const first = yield* captureRecord(inputs[0]!);
|
|
198
|
+
const records: [RecordEnvelope, ...Array<RecordEnvelope>] = [first.canonical];
|
|
199
|
+
|
|
200
|
+
for (let index = 1; index < slots.length; index++)
|
|
201
|
+
records.push((yield* captureRecord(inputs[index]!)).canonical);
|
|
195
202
|
|
|
196
203
|
return Object.freeze(
|
|
197
204
|
CanonicalBatch.make(
|
|
198
|
-
{ batchId, producerId, records:
|
|
205
|
+
{ batchId, producerId, records: Object.freeze(records) },
|
|
199
206
|
{ disableChecks: true },
|
|
200
207
|
),
|
|
201
208
|
);
|
|
@@ -1646,25 +1653,30 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1646
1653
|
operational.set(fact.recordId, fact);
|
|
1647
1654
|
}
|
|
1648
1655
|
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1656
|
+
// The records above already belong to this writer. PreparedAppend captures the
|
|
1657
|
+
// complete update at the storage boundary, preserving their private encodings.
|
|
1658
|
+
const checkpoint = ExecutionCheckpoint.make(
|
|
1659
|
+
{
|
|
1660
|
+
version: 2,
|
|
1661
|
+
progressRecord: record,
|
|
1662
|
+
operational: [...operational.values()],
|
|
1663
|
+
canonicalRecords,
|
|
1664
|
+
originalSequence:
|
|
1665
|
+
originalSequence ??
|
|
1666
|
+
CanonicalSequence.make(
|
|
1667
|
+
after +
|
|
1668
|
+
ownedRecords
|
|
1669
|
+
.filter((fact) => !isOperationalRecord(fact))
|
|
1670
|
+
.findIndex((fact) => fact.recordId === originalInput.recordId) +
|
|
1671
|
+
1,
|
|
1672
|
+
),
|
|
1673
|
+
throughSequence: CanonicalSequence.make(
|
|
1674
|
+
after + ownedRecords.filter((fact) => !isOperationalRecord(fact)).length,
|
|
1662
1675
|
),
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
}).pipe(Effect.mapError((cause) => failure("Active execution exceeds its bounds", cause)));
|
|
1676
|
+
batchId: batch.batchId,
|
|
1677
|
+
},
|
|
1678
|
+
{ disableChecks: true },
|
|
1679
|
+
);
|
|
1668
1680
|
|
|
1669
1681
|
const state = {
|
|
1670
1682
|
continuation,
|
|
@@ -1687,13 +1699,16 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1687
1699
|
);
|
|
1688
1700
|
yield* checkFutureShapes(state);
|
|
1689
1701
|
executions.push(
|
|
1690
|
-
ExecutionUpdate.make(
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1702
|
+
ExecutionUpdate.make(
|
|
1703
|
+
{
|
|
1704
|
+
previousRevision: previous?.continuation.revision ?? 0,
|
|
1705
|
+
checkpoint,
|
|
1706
|
+
facts: changed,
|
|
1707
|
+
// Pending operations and handoffs retain their own recovery rows and original facts.
|
|
1708
|
+
retire: position === "settled",
|
|
1709
|
+
},
|
|
1710
|
+
{ disableChecks: true },
|
|
1711
|
+
),
|
|
1697
1712
|
);
|
|
1698
1713
|
accepted.set(runId, state);
|
|
1699
1714
|
}
|
|
@@ -1940,9 +1955,6 @@ export const makeProgressWriter = Effect.fnUntraced(function* (
|
|
|
1940
1955
|
reserve,
|
|
1941
1956
|
defer,
|
|
1942
1957
|
check,
|
|
1943
|
-
/** Internal read view immediately after this writer's acknowledged commit, while
|
|
1944
|
-
* holding its initialization gates. Never authority across ownership or writes. */
|
|
1945
|
-
acceptedCheckpoint: (runId: RunId) => cached.get(runId)?.checkpoint,
|
|
1946
1958
|
/** Scope a verified empty execution/evidence view to one owned initialization body.
|
|
1947
1959
|
* The caller holds progress+mutation gates; a changed writer or tail never reuses it. */
|
|
1948
1960
|
withVerifiedEmptyRun: <A, E, R>(
|
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
type Claim,
|
|
18
18
|
type ClaimRequest,
|
|
19
19
|
type InputAppliedMarker,
|
|
20
|
+
type RecoverySnapshot,
|
|
21
|
+
RecoverySnapshotRequest,
|
|
20
22
|
LedgerError,
|
|
21
23
|
MarkInputAppliedRequest,
|
|
22
24
|
MarkJoinedRequest,
|
|
@@ -34,6 +36,8 @@ import {
|
|
|
34
36
|
type CommitBatch,
|
|
35
37
|
type ExecutionUpdate,
|
|
36
38
|
PreparedAppend,
|
|
39
|
+
FreshRunRead,
|
|
40
|
+
type ThreadIdentity,
|
|
37
41
|
ThreadMaterialization,
|
|
38
42
|
ThreadNotMaterialized,
|
|
39
43
|
ThreadStore,
|
|
@@ -115,11 +119,12 @@ export interface RunStorageSession extends RunWriter, RunOwnership {
|
|
|
115
119
|
readonly claim: Claim;
|
|
116
120
|
/** Atomic original input/context plus the ledger marker, when the adapter supports it. */
|
|
117
121
|
readonly appendInput?: RunWriter["append"];
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
readonly
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
/** Read current controls, root identity and empty-Run evidence under this owner.
|
|
123
|
+
* Its tail is adopted by the writer; append still checks the tail and revision. */
|
|
124
|
+
readonly prepareStart?: Effect.Effect<
|
|
125
|
+
{ readonly snapshot: RecoverySnapshot; readonly identity: ThreadIdentity } | undefined,
|
|
126
|
+
LedgerError | ThreadStoreFailure
|
|
127
|
+
>;
|
|
123
128
|
readonly refresh: Effect.Effect<void, ThreadStoreFailure>;
|
|
124
129
|
readonly publishSettlement: (
|
|
125
130
|
batch: CanonicalBatch,
|
|
@@ -182,14 +187,12 @@ const makeWriter = Effect.fnUntraced(function* (threadId: ThreadId) {
|
|
|
182
187
|
const publisher = yield* ThreadStore;
|
|
183
188
|
|
|
184
189
|
const append: RunWriter["append"] = Effect.fnUntraced(function* (batch, executions) {
|
|
185
|
-
const captured = yield* PreparedAppend.capture(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}),
|
|
192
|
-
).pipe(
|
|
190
|
+
const captured = yield* PreparedAppend.capture({
|
|
191
|
+
threadId,
|
|
192
|
+
expectedTailSequence: tail.sequence,
|
|
193
|
+
batch,
|
|
194
|
+
...(executions === undefined ? {} : { executions }),
|
|
195
|
+
}).pipe(
|
|
193
196
|
Effect.mapError((cause) =>
|
|
194
197
|
ThreadStoreError.make({
|
|
195
198
|
operation: "capture append",
|
|
@@ -343,8 +346,46 @@ export const make = Effect.gen(function* () {
|
|
|
343
346
|
...writer,
|
|
344
347
|
claim: claimed,
|
|
345
348
|
...(appendInput === undefined ? {} : { appendInput }),
|
|
346
|
-
|
|
347
|
-
|
|
349
|
+
...(store.readFreshRun === undefined || appendInput === undefined
|
|
350
|
+
? {}
|
|
351
|
+
: {
|
|
352
|
+
prepareStart: owner.withProgress(
|
|
353
|
+
request.threadId,
|
|
354
|
+
generation.use(
|
|
355
|
+
Effect.gen(function* () {
|
|
356
|
+
const snapshot = yield* ledger.loadRecoverySnapshot(
|
|
357
|
+
RecoverySnapshotRequest.make({ submissionId: claimed.submissionId }),
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
const submission = snapshot.submission;
|
|
361
|
+
|
|
362
|
+
if (
|
|
363
|
+
submission.threadId !== request.threadId ||
|
|
364
|
+
submission.state !== "ready" ||
|
|
365
|
+
submission.workerAdmission !== undefined ||
|
|
366
|
+
submission.messageAdmission !== undefined ||
|
|
367
|
+
submission.parentLinkage !== undefined ||
|
|
368
|
+
snapshot.inputApplied !== undefined ||
|
|
369
|
+
snapshot.abortIntent !== undefined ||
|
|
370
|
+
snapshot.approvalDecisions.length !== 0
|
|
371
|
+
)
|
|
372
|
+
return undefined;
|
|
373
|
+
|
|
374
|
+
const identity = yield* store.readFreshRun!(
|
|
375
|
+
FreshRunRead.make({
|
|
376
|
+
threadId: request.threadId,
|
|
377
|
+
submissionId: claimed.submissionId,
|
|
378
|
+
}),
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
if (Option.isNone(identity)) return undefined;
|
|
382
|
+
adoptTail(identity.value.tailSequence);
|
|
383
|
+
|
|
384
|
+
return { snapshot, identity: identity.value };
|
|
385
|
+
}),
|
|
386
|
+
),
|
|
387
|
+
),
|
|
388
|
+
}),
|
|
348
389
|
release: generation.release,
|
|
349
390
|
refresh: writer.refresh,
|
|
350
391
|
markInputApplied: (marker) =>
|
|
@@ -836,6 +836,11 @@ export class ThreadIdentityRequest extends Schema.Class<ThreadIdentityRequest>(
|
|
|
836
836
|
"@effect-agent/thread/ThreadIdentityRequest",
|
|
837
837
|
)({ threadId: ThreadId }) {}
|
|
838
838
|
|
|
839
|
+
export class FreshRunRead extends Schema.Class<FreshRunRead>("@effect-agent/thread/FreshRunRead")({
|
|
840
|
+
threadId: ThreadId,
|
|
841
|
+
submissionId: SubmissionId,
|
|
842
|
+
}) {}
|
|
843
|
+
|
|
839
844
|
/**
|
|
840
845
|
* One consistent snapshot: Thread ID, canonical tail, admission presence, first record,
|
|
841
846
|
* exact worker origin, then exact subagent lineage. A row selected twice appears only
|
|
@@ -1246,6 +1251,12 @@ export class ThreadStore extends Context.Service<
|
|
|
1246
1251
|
readonly readIdentity: (
|
|
1247
1252
|
request: ThreadIdentityRequest,
|
|
1248
1253
|
) => Effect.Effect<ThreadIdentity, ThreadStoreError | ThreadNotMaterialized>;
|
|
1254
|
+
/** Owner-held preparation for an admitted root Run. Some proves an initialized root
|
|
1255
|
+
* identity and no checkpoint, Run membership or exact input/abort/settlement record.
|
|
1256
|
+
* None requires ordinary recovery; it never authorizes overwriting existing evidence. */
|
|
1257
|
+
readonly readFreshRun?: (
|
|
1258
|
+
request: FreshRunRead,
|
|
1259
|
+
) => Effect.Effect<Option.Option<ThreadIdentity>, ThreadStoreError | ThreadNotMaterialized>;
|
|
1249
1260
|
readonly readWorkerCapacity?: (
|
|
1250
1261
|
request: ThreadWorkerCapacityRequest,
|
|
1251
1262
|
) => Effect.Effect<ThreadWorkerCapacity, ThreadStoreError | ThreadNotMaterialized>;
|
|
@@ -294,8 +294,9 @@ export const makeCommittedPromptSuffix = (
|
|
|
294
294
|
return;
|
|
295
295
|
}
|
|
296
296
|
// Prepared append facts already have privately frozen encodings; the original input and
|
|
297
|
-
// winning settlement are captured here before retention.
|
|
298
|
-
//
|
|
297
|
+
// winning settlement are captured here before retention. An input contributes only its
|
|
298
|
+
// owned identity; other facts still decode the prompt projection used by readPrompt.
|
|
299
|
+
// Failure invalidates this derivative, not the commit.
|
|
299
300
|
try {
|
|
300
301
|
for (const fact of facts) {
|
|
301
302
|
const captured = captureRecord(fact);
|
|
@@ -332,10 +333,25 @@ export const makeCommittedPromptSuffix = (
|
|
|
332
333
|
return;
|
|
333
334
|
}
|
|
334
335
|
|
|
336
|
+
const record: PromptRecord =
|
|
337
|
+
payload._tag === "UserInputRecorded"
|
|
338
|
+
? {
|
|
339
|
+
recordId: owned.canonical.recordId,
|
|
340
|
+
payload: {
|
|
341
|
+
_tag: payload._tag,
|
|
342
|
+
kind: payload.kind,
|
|
343
|
+
...(payload.runId === undefined ? {} : { runId: payload.runId }),
|
|
344
|
+
...(payload.submissionId === undefined
|
|
345
|
+
? {}
|
|
346
|
+
: { submissionId: payload.submissionId }),
|
|
347
|
+
},
|
|
348
|
+
}
|
|
349
|
+
: decodeCommittedPromptRecord(owned.wire);
|
|
350
|
+
|
|
335
351
|
const entry: PromptRecordEnvelope = {
|
|
336
352
|
threadId: original.threadId,
|
|
337
353
|
sequence: CanonicalSequence.make(through + 1),
|
|
338
|
-
record
|
|
354
|
+
record,
|
|
339
355
|
};
|
|
340
356
|
|
|
341
357
|
const footprint = suffixRecordFootprint(entry, remaining);
|
|
@@ -118,14 +118,14 @@ const capturePayload = (payload: CanonicalRecordPayload) => {
|
|
|
118
118
|
Object.setPrototypeOf(copy, Object.getPrototypeOf(payload));
|
|
119
119
|
const copies = new WeakMap<object, object>([[payload, copy]]);
|
|
120
120
|
|
|
121
|
-
const pending: Array<object> = [copy];
|
|
122
|
-
|
|
123
121
|
const owned: Array<object> = [copy];
|
|
124
122
|
|
|
125
|
-
|
|
126
|
-
const next =
|
|
123
|
+
for (let index = 0; index < owned.length; index++) {
|
|
124
|
+
const next = owned[index]!;
|
|
125
|
+
|
|
126
|
+
for (const key of Object.keys(next)) {
|
|
127
|
+
const value = Reflect.get(next, key);
|
|
127
128
|
|
|
128
|
-
for (const [key, value] of Object.entries(next)) {
|
|
129
129
|
if (!Predicate.isObjectOrArray(value)) continue;
|
|
130
130
|
let child = copies.get(value);
|
|
131
131
|
|
|
@@ -134,7 +134,6 @@ const capturePayload = (payload: CanonicalRecordPayload) => {
|
|
|
134
134
|
|
|
135
135
|
copies.set(value, created);
|
|
136
136
|
owned.push(created);
|
|
137
|
-
pending.push(created);
|
|
138
137
|
child = created;
|
|
139
138
|
}
|
|
140
139
|
setOwn(next, key, child);
|
|
@@ -152,7 +151,9 @@ const ownWire = <Wire extends RecordJson>(wire: Wire, copies: WeakMap<object, ob
|
|
|
152
151
|
while (pending.length > 0) {
|
|
153
152
|
const next = pending.pop()!;
|
|
154
153
|
|
|
155
|
-
for (const
|
|
154
|
+
for (const key of Object.keys(next)) {
|
|
155
|
+
const value = Reflect.get(next, key);
|
|
156
|
+
|
|
156
157
|
if (!Predicate.isObjectOrArray(value)) continue;
|
|
157
158
|
const copy = copies.get(value);
|
|
158
159
|
|
|
@@ -159,7 +159,9 @@ export class CodeHostCallSuccess extends Schema.TaggedClass<CodeHostCallSuccess>
|
|
|
159
159
|
/**
|
|
160
160
|
* A host call settled with a Schema-encoded typed failure envelope. Inside the
|
|
161
161
|
* generated program the call's Promise rejects with the envelope value, so a
|
|
162
|
-
* program can catch and branch on expected failures.
|
|
162
|
+
* program can catch and branch on expected failures. Object and array failures
|
|
163
|
+
* stringify to their encoded JSON, preserving recovery details in String(error)
|
|
164
|
+
* without changing the enumerable fields returned or rethrown by the program.
|
|
163
165
|
*/
|
|
164
166
|
export class CodeHostCallFailure extends Schema.TaggedClass<CodeHostCallFailure>()(
|
|
165
167
|
"CodeHostCallFailure",
|