effect-agent 0.1.0-beta.152 → 0.1.0-beta.153
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-CKIdJoP8.d.mts → Admin-BjmupLN3.d.mts} +36 -17
- package/dist/{Agent-Cjd_ZveM.d.mts → Agent-BCyrGaWg.d.mts} +2 -2
- package/dist/{AgentPolicy-BqDoSXO6.d.mts → AgentPolicy-CnXWWwdg.d.mts} +5 -1
- package/dist/{AgentRuntime-sXpKcyxu.d.mts → AgentRuntime-BAjT5gXl.d.mts} +10 -10
- package/dist/{AgentRuntime-D8U9gl9Q.mjs → AgentRuntime-IF_1GoUf.mjs} +54 -11
- package/dist/AgentRuntime-IF_1GoUf.mjs.map +1 -0
- package/dist/{ContextCompactor-WwSIG_Z2.d.mts → ContextCompactor-CPlStZRc.d.mts} +2 -2
- package/dist/{Digest-U69rDHuO.d.mts → Digest-CaJ2RIsF.d.mts} +2 -2
- package/dist/{DurableAgentRuntime-DQFV26SB.mjs → DurableAgentRuntime-BQzYkFVy.mjs} +185 -88
- package/dist/DurableAgentRuntime-BQzYkFVy.mjs.map +1 -0
- package/dist/{EventSource-CMbXXmwe.d.mts → EventSource-C8CKwQy5.d.mts} +3 -3
- package/dist/InMemory.d.mts +1 -1
- package/dist/{Messaging-ccQURKCf.d.mts → Messaging-B1zumorg.d.mts} +3 -3
- package/dist/{MessagingHost-D04wE-7W.d.mts → MessagingHost-B4jqlJmx.d.mts} +3 -3
- package/dist/{Output-CFD1CPfU.d.mts → Output-WL7JexCm.d.mts} +2 -2
- package/dist/{PreparedInputAdmission-Bt6rgtVu.d.mts → PreparedInputAdmission-CU1PzUVD.d.mts} +4 -4
- package/dist/{Records-B5GFWCpn.d.mts → Records-BrEpibum.d.mts} +17 -6
- package/dist/{RunEvent-DIrzkjLr.d.mts → RunEvent-DV_llBcq.d.mts} +18 -4
- package/dist/{RunJournal-Gd83HYqG.mjs → RunJournal-ixFRCyW3.mjs} +29 -7
- package/dist/RunJournal-ixFRCyW3.mjs.map +1 -0
- package/dist/{RunOptions-Bv9NpkPZ.d.mts → RunOptions-CkRYnlJa.d.mts} +22 -8
- package/dist/{RunPolicyUsage-ClZxyR46.d.mts → RunPolicyUsage-CUudVtg_.d.mts} +3 -1
- package/dist/{Schedule-CtYREFnz.d.mts → Schedule-B_z7PMg-.d.mts} +2 -2
- package/dist/{Subagent-hG9lJ7tJ.mjs → Subagent-CmFtZaeI.mjs} +2 -2
- package/dist/{Subagent-hG9lJ7tJ.mjs.map → Subagent-CmFtZaeI.mjs.map} +1 -1
- package/dist/{Subagent-VHrANXFy.d.mts → Subagent-Dld4W1BY.d.mts} +7 -7
- package/dist/{SubagentHost-C-4A7tA2.d.mts → SubagentHost--HBuY8fF.d.mts} +4 -4
- package/dist/{Subscription-BJAzYNw1.d.mts → Subscription-BomcQ9_W.d.mts} +5 -5
- package/dist/{SubscriptionInput-CkBJt0AS.d.mts → SubscriptionInput-gpZSR9vB.d.mts} +3 -3
- package/dist/{ThreadHistory-tS1KwxHR.d.mts → ThreadHistory-ZEu_ja6L.d.mts} +2 -2
- package/dist/{Worker-fwWkBg12.d.mts → Worker-2r2zGDkh.d.mts} +2 -2
- package/dist/{WorkerAdmission-CJ_oWRuS.mjs → WorkerAdmission-CNbm4o_x.mjs} +3 -3
- package/dist/{WorkerAdmission-CJ_oWRuS.mjs.map → WorkerAdmission-CNbm4o_x.mjs.map} +1 -1
- package/dist/{agent-registration-CKNsrpwo.mjs → agent-registration-U3kmV7nW.mjs} +18 -18
- package/dist/agent-registration-U3kmV7nW.mjs.map +1 -0
- package/dist/capabilities/Commands.d.mts +1 -1
- package/dist/capabilities/Messaging.d.mts +1 -1
- package/dist/capabilities/Redaction.d.mts +1 -1
- package/dist/capabilities/RunHooks.d.mts +1 -1
- package/dist/capabilities/Subagent.d.mts +2 -2
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/core/Agent.d.mts +1 -1
- package/dist/core/AgentPolicy.d.mts +1 -1
- package/dist/core/AgentPolicy.mjs +2 -0
- package/dist/core/AgentPolicy.mjs.map +1 -1
- package/dist/core/RunEvent.d.mts +2 -2
- package/dist/core/RunEvent.mjs +10 -1
- package/dist/core/RunEvent.mjs.map +1 -1
- package/dist/core/RunPolicyUsage.d.mts +1 -1
- package/dist/core/RunPolicyUsage.mjs +6 -1
- package/dist/core/RunPolicyUsage.mjs.map +1 -1
- package/dist/core/Worker.d.mts +1 -1
- package/dist/durable/ActivityStore.d.mts +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/AgentRegistration.d.mts +2 -2
- package/dist/durable/AgentRegistration.mjs +3 -2
- package/dist/durable/AgentRegistration.mjs.map +1 -1
- package/dist/durable/Certification.d.mts +1 -1
- package/dist/durable/CommittedActivity.d.mts +3 -3
- package/dist/durable/Digest.d.mts +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/MessageDelivery.d.mts +5 -5
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +24 -24
- package/dist/durable/PersistentHistory.d.mts +2 -2
- package/dist/durable/PersistentHistory.mjs +1 -1
- package/dist/durable/PreparedInputAdmission.d.mts +1 -1
- package/dist/durable/Records.d.mts +2 -2
- package/dist/durable/Records.mjs +16 -1
- package/dist/durable/Records.mjs.map +1 -1
- package/dist/durable/Recovery.d.mts +1 -1
- package/dist/durable/RunJournal.d.mts +1 -1
- package/dist/durable/RunJournal.mjs +1 -1
- package/dist/durable/Schedule.d.mts +1 -1
- package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
- package/dist/durable/ScheduleTransition.d.mts +1 -1
- package/dist/durable/Scheduling.d.mts +3 -3
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.d.mts +2 -2
- package/dist/durable/SubmissionLedgerConformance.mjs +1 -1
- package/dist/durable/SubmissionStatus.d.mts +1 -1
- package/dist/durable/Subscription.d.mts +1 -1
- package/dist/durable/SubscriptionInput.d.mts +1 -1
- package/dist/durable/SubscriptionInput.mjs +1 -1
- package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
- package/dist/durable/SubscriptionTools.d.mts +4 -4
- package/dist/durable/SubscriptionTransition.d.mts +1 -1
- package/dist/durable/Subscriptions.d.mts +6 -6
- package/dist/durable/ThreadContextHistory.d.mts +1 -1
- package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
- package/dist/durable/ThreadInvariants.d.mts +2 -2
- package/dist/durable/ThreadInvariants.mjs +1 -1
- package/dist/durable/ThreadProjection.d.mts +1 -1
- package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
- package/dist/durable/ThreadStore.d.mts +1 -1
- package/dist/durable/ThreadStore.mjs +1 -1
- package/dist/durable/ThreadStoreConformance.d.mts +1 -1
- package/dist/durable/ThreadStoreConformance.mjs +1 -1
- package/dist/durable/WorkerAdmission.d.mts +3 -3
- package/dist/durable/WorkerAdmission.mjs +1 -1
- package/dist/durable/WorkerHost.d.mts +5 -5
- package/dist/engine/AgentRuntime.d.mts +1 -1
- package/dist/engine/AgentRuntime.mjs +1 -1
- package/dist/engine/Compaction.d.mts +1 -1
- package/dist/engine/ContextCompactor.d.mts +1 -1
- package/dist/engine/MessagingHost.d.mts +1 -1
- package/dist/engine/Output.d.mts +1 -1
- package/dist/engine/RunOptions.d.mts +1 -1
- package/dist/engine/RunOptions.mjs.map +1 -1
- package/dist/engine/SubagentHost.d.mts +1 -1
- package/dist/engine/ThreadHistory.d.mts +1 -1
- package/dist/index.d.mts +22 -22
- package/dist/index.mjs +5 -5
- package/package.json +1 -1
- package/src/core/AgentPolicy.ts +2 -0
- package/src/core/RunEvent.ts +9 -0
- package/src/core/RunPolicyUsage.ts +2 -0
- package/src/durable/AgentRegistration.ts +2 -0
- package/src/durable/DurableAgentRuntime.ts +320 -137
- package/src/durable/Records.ts +12 -0
- package/src/durable/RunJournal.ts +88 -27
- package/src/durable/internal/agent-registration.ts +58 -35
- package/src/engine/RunOptions.ts +17 -2
- package/src/engine/internal/agent-runtime.ts +115 -8
- package/dist/AgentRuntime-D8U9gl9Q.mjs.map +0 -1
- package/dist/DurableAgentRuntime-DQFV26SB.mjs.map +0 -1
- package/dist/RunJournal-Gd83HYqG.mjs.map +0 -1
- package/dist/agent-registration-CKNsrpwo.mjs.map +0 -1
|
@@ -151,6 +151,7 @@ import {
|
|
|
151
151
|
type ResolvedBinding,
|
|
152
152
|
resolveDefinitionBinding,
|
|
153
153
|
resolveWorkerBinding,
|
|
154
|
+
CurrentBindingSelection,
|
|
154
155
|
} from "./internal/agent-registration.ts";
|
|
155
156
|
import { makeAgentUpdateRuntime } from "./internal/agent-updates.ts";
|
|
156
157
|
import { inspectForeignDiagnostic, safeUnknownString } from "./internal/foreign-diagnostic.ts";
|
|
@@ -184,6 +185,7 @@ import {
|
|
|
184
185
|
CompactionCreated,
|
|
185
186
|
DefinitionDigests,
|
|
186
187
|
ModelResponseInterrupted,
|
|
188
|
+
ModelCallAborted,
|
|
187
189
|
PersistedJson,
|
|
188
190
|
ProducerEpoch,
|
|
189
191
|
RecordEnvelope,
|
|
@@ -240,6 +242,7 @@ import {
|
|
|
240
242
|
modelResponseRecordId,
|
|
241
243
|
projectRunJournalStream,
|
|
242
244
|
type JournalBoundary,
|
|
245
|
+
type RunJournalProjection,
|
|
243
246
|
runCompletedRecordId,
|
|
244
247
|
runCompletionDigest,
|
|
245
248
|
runIdForSubmission,
|
|
@@ -296,6 +299,7 @@ import {
|
|
|
296
299
|
ClaimHandoff,
|
|
297
300
|
SubmissionScheduling,
|
|
298
301
|
ClaimJoiningRequest,
|
|
302
|
+
type JoiningClaim,
|
|
299
303
|
ClaimRequest,
|
|
300
304
|
IdempotencyKey,
|
|
301
305
|
LedgerError,
|
|
@@ -1257,11 +1261,25 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
1257
1261
|
bindings: ReadonlyArray<ResolvedBinding>,
|
|
1258
1262
|
) {
|
|
1259
1263
|
const registeredBindings = [...bindings];
|
|
1264
|
+
const bindingSelection = yield* CurrentBindingSelection;
|
|
1260
1265
|
const workerAdmissionPort = yield* WorkerAdmissionPort;
|
|
1261
1266
|
const ledger = yield* SubmissionLedger;
|
|
1262
1267
|
const submissionScheduling = yield* SubmissionScheduling;
|
|
1263
1268
|
const store = yield* ThreadStore;
|
|
1264
1269
|
|
|
1270
|
+
// Disposable: canonical tail and owner identify the exact projection, never ownership.
|
|
1271
|
+
// Retain only the most recent view; persisted checkpoints still govern cold recovery.
|
|
1272
|
+
let projectedJournal:
|
|
1273
|
+
| {
|
|
1274
|
+
readonly threadId: ThreadId;
|
|
1275
|
+
readonly through: CanonicalSequence;
|
|
1276
|
+
readonly runId: RunId;
|
|
1277
|
+
readonly seedThrough: CanonicalSequence | undefined;
|
|
1278
|
+
readonly journal: RunJournalProjection;
|
|
1279
|
+
readonly boundaries: ReadonlyArray<JournalBoundary>;
|
|
1280
|
+
}
|
|
1281
|
+
| undefined;
|
|
1282
|
+
|
|
1265
1283
|
const wake = yield* WakeScheduler;
|
|
1266
1284
|
const failpoint = yield* DurableRuntimeFailpoint;
|
|
1267
1285
|
const config = yield* DurableRuntimeConfig;
|
|
@@ -1301,20 +1319,11 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
1301
1319
|
Effect.provideService(effect, Crypto.Crypto, crypto);
|
|
1302
1320
|
|
|
1303
1321
|
const contractsFor = (definition: Agent.AnyDefinition) => {
|
|
1304
|
-
const registered = registeredBindings.filter(
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
// Attempts may restore the accepted Run policy on a Definition copy. Replay contracts
|
|
1308
|
-
// describe Tools, so retain the registration's semantic versions while all declarations
|
|
1309
|
-
// that affect those contracts are unchanged. Replaced Tools or completion declarations
|
|
1310
|
-
// must not inherit another executable's replay authority.
|
|
1311
|
-
const current =
|
|
1312
|
-
binding?.definition.toolkit === definition.toolkit &&
|
|
1313
|
-
binding.definition.completion === definition.completion &&
|
|
1314
|
-
binding.definition.completionFromTools === definition.completionFromTools
|
|
1315
|
-
? binding
|
|
1316
|
-
: undefined;
|
|
1322
|
+
const registered = registeredBindings.filter(
|
|
1323
|
+
(binding) => binding.agentId === definition.id && Object.is(binding.definition, definition),
|
|
1324
|
+
);
|
|
1317
1325
|
|
|
1326
|
+
const current = registered.length === 1 ? registered[0] : undefined;
|
|
1318
1327
|
const contracts = current?.digests.replay?.tools;
|
|
1319
1328
|
|
|
1320
1329
|
return contracts === undefined
|
|
@@ -1324,9 +1333,15 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
1324
1333
|
: Effect.succeed(contracts);
|
|
1325
1334
|
};
|
|
1326
1335
|
|
|
1327
|
-
const
|
|
1328
|
-
|
|
1329
|
-
|
|
1336
|
+
const resolveCurrentBinding = (submission: SubmissionSnapshot) =>
|
|
1337
|
+
resolveWorkerBinding(registeredBindings, submission).pipe(
|
|
1338
|
+
Effect.provideService(CurrentBindingSelection, bindingSelection),
|
|
1339
|
+
);
|
|
1340
|
+
|
|
1341
|
+
const currentOperationsFor = Effect.fnUntraced(function* (submission: SubmissionSnapshot) {
|
|
1342
|
+
const binding = yield* resolveCurrentBinding(submission).pipe(
|
|
1343
|
+
Effect.catchTag("BindingUnavailable", () => Effect.succeed(undefined)),
|
|
1344
|
+
);
|
|
1330
1345
|
|
|
1331
1346
|
return binding === undefined
|
|
1332
1347
|
? undefined
|
|
@@ -4551,6 +4566,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
4551
4566
|
journalMetadata: JournalMetadata | undefined,
|
|
4552
4567
|
lineage: AttemptLineage,
|
|
4553
4568
|
approvalDecisions: ReadonlyArray<ApprovalDecisionIntent>,
|
|
4569
|
+
currentContracts: Readonly<Record<string, Digest>>,
|
|
4554
4570
|
runTiming: { readonly startedAt: DateTime.Utc; readonly deadline: DateTime.Utc },
|
|
4555
4571
|
yieldAfter?: DateTime.Utc,
|
|
4556
4572
|
) =>
|
|
@@ -4560,13 +4576,31 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
4560
4576
|
const runId = runIdForSubmission(submissionId);
|
|
4561
4577
|
const boundaries: Array<JournalBoundary> = [];
|
|
4562
4578
|
|
|
4563
|
-
const
|
|
4564
|
-
|
|
4579
|
+
const cached = projectedJournal;
|
|
4580
|
+
|
|
4581
|
+
const journal =
|
|
4582
|
+
cached !== undefined &&
|
|
4583
|
+
cached.threadId === ctx.threadId &&
|
|
4584
|
+
cached.through === canonicalThrough &&
|
|
4585
|
+
cached.runId === runId &&
|
|
4586
|
+
cached.seedThrough === journalSeed?.throughSequence
|
|
4587
|
+
? (boundaries.push(...cached.boundaries), cached.journal)
|
|
4588
|
+
: yield* projectRunJournalStream(
|
|
4589
|
+
canonical,
|
|
4590
|
+
runId,
|
|
4591
|
+
(boundary) => boundaries.push(boundary),
|
|
4592
|
+
journalSeed,
|
|
4593
|
+
journalMetadata,
|
|
4594
|
+
);
|
|
4595
|
+
|
|
4596
|
+
projectedJournal = {
|
|
4597
|
+
threadId: ctx.threadId,
|
|
4598
|
+
through: canonicalThrough,
|
|
4565
4599
|
runId,
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4600
|
+
seedThrough: journalSeed?.throughSequence,
|
|
4601
|
+
journal,
|
|
4602
|
+
boundaries,
|
|
4603
|
+
};
|
|
4570
4604
|
|
|
4571
4605
|
const saveRecoveryCheckpoint = Effect.fn("DurableAgentRuntime.saveRecoveryCheckpoint")(
|
|
4572
4606
|
function* (compactionId: RecordId): Effect.fn.Return<void, DurableWorkerFailure> {
|
|
@@ -4873,8 +4907,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
4873
4907
|
journalSeed,
|
|
4874
4908
|
);
|
|
4875
4909
|
|
|
4876
|
-
const currentContracts = yield* contractsFor(agent.definition);
|
|
4877
|
-
|
|
4878
4910
|
const rolloverOperation =
|
|
4879
4911
|
journal.pendingContextToolCallId === undefined
|
|
4880
4912
|
? undefined
|
|
@@ -5009,15 +5041,43 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
5009
5041
|
|
|
5010
5042
|
// Staging also backs the cumulative summary; keep it intact and track canonical prefixes.
|
|
5011
5043
|
const committedUsageLengths = new Map<number, number>();
|
|
5044
|
+
const committedUnobservedCalls = new Map<number, number>();
|
|
5045
|
+
|
|
5046
|
+
const usageForCommit = (turn: number) => {
|
|
5047
|
+
const staged = stagedUsage.get(turn);
|
|
5048
|
+
|
|
5049
|
+
if (staged === undefined) return undefined;
|
|
5050
|
+
const modelUsage = staged.modelUsage.slice(committedUsageLengths.get(turn) ?? 0);
|
|
5051
|
+
|
|
5052
|
+
if (modelUsage.length === 0) return undefined;
|
|
5053
|
+
|
|
5054
|
+
return {
|
|
5055
|
+
modelUsage,
|
|
5056
|
+
inputTokens: modelUsage.reduce((sum, call) => sum + call.inputTokens.total, 0),
|
|
5057
|
+
outputTokens: modelUsage.reduce((sum, call) => sum + call.outputTokens.total, 0),
|
|
5058
|
+
costMicrousd: modelUsage.reduce((sum, call) => sum + call.costMicrousd, 0),
|
|
5059
|
+
};
|
|
5060
|
+
};
|
|
5061
|
+
|
|
5062
|
+
const unobservedForCommit = (turn: number) =>
|
|
5063
|
+
(stagedUnobservedCalls.get(turn) ?? 0) - (committedUnobservedCalls.get(turn) ?? 0);
|
|
5012
5064
|
|
|
5013
5065
|
const recordCommittedUsage = (batch: CanonicalBatch) => {
|
|
5014
5066
|
for (const record of batch.records) {
|
|
5015
|
-
if (
|
|
5067
|
+
if (
|
|
5068
|
+
record.payload._tag !== "ModelResponseRecorded" &&
|
|
5069
|
+
record.payload._tag !== "ModelCallAborted"
|
|
5070
|
+
)
|
|
5071
|
+
continue;
|
|
5016
5072
|
const payload = record.payload;
|
|
5017
5073
|
|
|
5018
5074
|
committedUsageLengths.set(
|
|
5019
5075
|
payload.turn,
|
|
5020
|
-
|
|
5076
|
+
(committedUsageLengths.get(payload.turn) ?? 0) + (payload.modelUsage?.length ?? 0),
|
|
5077
|
+
);
|
|
5078
|
+
committedUnobservedCalls.set(
|
|
5079
|
+
payload.turn,
|
|
5080
|
+
(committedUnobservedCalls.get(payload.turn) ?? 0) + (payload.unobservedModelCalls ?? 0),
|
|
5021
5081
|
);
|
|
5022
5082
|
}
|
|
5023
5083
|
};
|
|
@@ -5430,7 +5490,9 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
5430
5490
|
completedExhausted: undefined,
|
|
5431
5491
|
});
|
|
5432
5492
|
|
|
5433
|
-
const turnCounter = yield* Ref.make(
|
|
5493
|
+
const turnCounter = yield* Ref.make(
|
|
5494
|
+
journal.committedTurns + (journal.policyUsage.modelRestarts ?? 0),
|
|
5495
|
+
);
|
|
5434
5496
|
|
|
5435
5497
|
const idGenerator: (typeof IdGenerator)["Service"] = {
|
|
5436
5498
|
nextThreadId: Effect.succeed(submission.threadId),
|
|
@@ -5543,6 +5605,37 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
5543
5605
|
};
|
|
5544
5606
|
|
|
5545
5607
|
const durability: RunDurabilityHook<CoordinatorHalt | CompactionError, never> = {
|
|
5608
|
+
commitModelRestart: (restart) =>
|
|
5609
|
+
recordHalt(
|
|
5610
|
+
Effect.gen(function* () {
|
|
5611
|
+
if (knownIds.has(modelResponseRecordId(runId, restart.turn)))
|
|
5612
|
+
return yield* RunJournalError.make({
|
|
5613
|
+
message: "Cannot restart a canonical model response",
|
|
5614
|
+
});
|
|
5615
|
+
const recordId = decodeRecordIdSync(`model-aborted:${runId}:${restart.restart}`);
|
|
5616
|
+
|
|
5617
|
+
const record = yield* makeEnvelope(
|
|
5618
|
+
recordId,
|
|
5619
|
+
ModelCallAborted.make({
|
|
5620
|
+
runId,
|
|
5621
|
+
...restart,
|
|
5622
|
+
reason: "joined-input",
|
|
5623
|
+
modelUsage: usageForCommit(restart.turn)?.modelUsage ?? [],
|
|
5624
|
+
unobservedModelCalls: unobservedForCommit(restart.turn),
|
|
5625
|
+
}),
|
|
5626
|
+
);
|
|
5627
|
+
|
|
5628
|
+
const batch = CanonicalBatch.make({
|
|
5629
|
+
batchId: decodeBatchIdSync(recordId),
|
|
5630
|
+
producerId: config.producerId,
|
|
5631
|
+
records: [record],
|
|
5632
|
+
});
|
|
5633
|
+
|
|
5634
|
+
yield* appendBatch(ctx, batch);
|
|
5635
|
+
recordCommittedUsage(batch);
|
|
5636
|
+
knownIds.add(recordId);
|
|
5637
|
+
}),
|
|
5638
|
+
),
|
|
5546
5639
|
noteToolExposure: (turn, snapshot) =>
|
|
5547
5640
|
Effect.sync(() => {
|
|
5548
5641
|
stagedToolExposure.set(turn, snapshot);
|
|
@@ -5624,8 +5717,8 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
5624
5717
|
...(canonicalTurn === 1 && pendingSlice.length > 0
|
|
5625
5718
|
? { runScopedPrefixLength: pendingSlice.length }
|
|
5626
5719
|
: {}),
|
|
5627
|
-
usage:
|
|
5628
|
-
unobservedModelCalls:
|
|
5720
|
+
usage: usageForCommit(canonicalTurn),
|
|
5721
|
+
unobservedModelCalls: unobservedForCommit(canonicalTurn),
|
|
5629
5722
|
}),
|
|
5630
5723
|
);
|
|
5631
5724
|
|
|
@@ -6210,10 +6303,114 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
6210
6303
|
yield* commitPendingTurn;
|
|
6211
6304
|
});
|
|
6212
6305
|
|
|
6306
|
+
// Claims are authority, wakes are hints. A cancelled waiter retains every claim
|
|
6307
|
+
// for the seam drain; it never appends input while an old response can still commit.
|
|
6308
|
+
type PreparedJoin = {
|
|
6309
|
+
readonly claim: JoiningClaim;
|
|
6310
|
+
readonly input: Pick<UserInputRecorded, "input" | "messageAdmission">;
|
|
6311
|
+
readonly rendered: Prompt.RawInput;
|
|
6312
|
+
};
|
|
6313
|
+
|
|
6314
|
+
const pendingJoinClaims: Array<{ readonly claim: JoiningClaim; prepared?: PreparedJoin }> =
|
|
6315
|
+
[];
|
|
6316
|
+
|
|
6317
|
+
const claimInputs = Effect.fnUntraced(function* (maxCount: number) {
|
|
6318
|
+
const ownershipToken = yield* Ref.get(tokenRef);
|
|
6319
|
+
|
|
6320
|
+
const claims = yield* ledger.claimJoining(
|
|
6321
|
+
ClaimJoiningRequest.make({
|
|
6322
|
+
threadId: submission.threadId,
|
|
6323
|
+
hostSubmissionId: submissionId,
|
|
6324
|
+
ownershipToken,
|
|
6325
|
+
maxCount,
|
|
6326
|
+
}),
|
|
6327
|
+
);
|
|
6328
|
+
|
|
6329
|
+
pendingJoinClaims.push(...claims.map((claim) => ({ claim })));
|
|
6330
|
+
|
|
6331
|
+
return claims.length;
|
|
6332
|
+
}, Effect.uninterruptible);
|
|
6333
|
+
|
|
6334
|
+
const revertClaims = Effect.fnUntraced(function* (
|
|
6335
|
+
claims: ReadonlyArray<(typeof pendingJoinClaims)[number]>,
|
|
6336
|
+
) {
|
|
6337
|
+
for (const pending of claims) {
|
|
6338
|
+
yield* ledger.revertJoining(
|
|
6339
|
+
RevertJoiningRequest.make({ submissionId: pending.claim.submissionId }),
|
|
6340
|
+
);
|
|
6341
|
+
pendingJoinClaims.splice(pendingJoinClaims.indexOf(pending), 1);
|
|
6342
|
+
}
|
|
6343
|
+
}, Effect.uninterruptible);
|
|
6344
|
+
|
|
6345
|
+
// Preparation remains interruptible; a completed render stays with its claim so
|
|
6346
|
+
// cancellation of the waiter cannot lose it or invoke the callback again at the seam.
|
|
6347
|
+
const prepareInputs = Effect.fnUntraced(function* (limit: number, firstReady = false) {
|
|
6348
|
+
if (
|
|
6349
|
+
pendingJoinClaims.length < limit &&
|
|
6350
|
+
(yield* claimInputs(limit - pendingJoinClaims.length)) > 0
|
|
6351
|
+
)
|
|
6352
|
+
yield* hit("join:after-claim");
|
|
6353
|
+
const prepared: Array<PreparedJoin> = [];
|
|
6354
|
+
|
|
6355
|
+
for (const pending of pendingJoinClaims.slice(0, limit)) {
|
|
6356
|
+
const claim = pending.claim;
|
|
6357
|
+
|
|
6358
|
+
const snapshot = yield* ledger.loadRecoverySnapshot(
|
|
6359
|
+
RecoverySnapshotRequest.make({ submissionId: claim.submissionId }),
|
|
6360
|
+
);
|
|
6361
|
+
|
|
6362
|
+
if (snapshot.abortIntent !== undefined) {
|
|
6363
|
+
yield* revertClaims([pending]);
|
|
6364
|
+
continue;
|
|
6365
|
+
}
|
|
6366
|
+
if (pending.prepared === undefined) {
|
|
6367
|
+
const input = {
|
|
6368
|
+
input: claim.inputPayload,
|
|
6369
|
+
...(snapshot.submission.messageAdmission === undefined
|
|
6370
|
+
? {}
|
|
6371
|
+
: { messageAdmission: snapshot.submission.messageAdmission }),
|
|
6372
|
+
};
|
|
6373
|
+
|
|
6374
|
+
const rendered = yield* Effect.result(renderJoinedInput(input));
|
|
6375
|
+
|
|
6376
|
+
if (Result.isFailure(rendered)) {
|
|
6377
|
+
// A rejected prompt and its suffix retain their own Runs in queue order.
|
|
6378
|
+
yield* revertClaims(pendingJoinClaims.slice(pendingJoinClaims.indexOf(pending)));
|
|
6379
|
+
break;
|
|
6380
|
+
}
|
|
6381
|
+
pending.prepared = { claim, input, rendered: rendered.success };
|
|
6382
|
+
}
|
|
6383
|
+
prepared.push(pending.prepared);
|
|
6384
|
+
if (firstReady) break;
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
return prepared;
|
|
6388
|
+
});
|
|
6389
|
+
|
|
6390
|
+
const awaitJoin = recordHalt(
|
|
6391
|
+
Effect.gen(function* () {
|
|
6392
|
+
while (true) {
|
|
6393
|
+
const ready = yield* Effect.scoped(
|
|
6394
|
+
Effect.gen(function* () {
|
|
6395
|
+
const notified = yield* wake.subscribe(submission.threadId);
|
|
6396
|
+
|
|
6397
|
+
if ((yield* prepareInputs(MAX_JOIN_DRAIN, true)).length > 0) return true;
|
|
6398
|
+
yield* notified;
|
|
6399
|
+
|
|
6400
|
+
return false;
|
|
6401
|
+
}),
|
|
6402
|
+
);
|
|
6403
|
+
|
|
6404
|
+
if (ready) return;
|
|
6405
|
+
}
|
|
6406
|
+
}),
|
|
6407
|
+
);
|
|
6408
|
+
|
|
6213
6409
|
const input: RunInputHook<
|
|
6214
6410
|
CoordinatorHalt | Agent.Failure<typeof agent>,
|
|
6215
6411
|
Agent.DefinitionRequirements<(typeof agent)["definition"]>
|
|
6216
6412
|
> = {
|
|
6413
|
+
awaitJoin,
|
|
6217
6414
|
drain: (policy) =>
|
|
6218
6415
|
Effect.gen(function* () {
|
|
6219
6416
|
const joinedInputs = yield* recordHalt(
|
|
@@ -6233,8 +6430,9 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
6233
6430
|
|
|
6234
6431
|
joinBacklog = hostSnapshot.joins;
|
|
6235
6432
|
}
|
|
6433
|
+
// These inputs were already consumed by an earlier attempt. Restore the
|
|
6434
|
+
// entire uncovered prompt; only fresh claims are subject to the drain bound.
|
|
6236
6435
|
for (const join of joinBacklog) {
|
|
6237
|
-
if (joinedInputs.length >= limit) break;
|
|
6238
6436
|
const joinId = join.submissionId;
|
|
6239
6437
|
|
|
6240
6438
|
if (deliveredJoinInputs.has(joinId)) continue;
|
|
@@ -6269,109 +6467,62 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
6269
6467
|
yield* preserveToolResults;
|
|
6270
6468
|
joinedInputs.push(payload);
|
|
6271
6469
|
}
|
|
6272
|
-
|
|
6273
|
-
const ownershipToken = yield* Ref.get(tokenRef);
|
|
6274
|
-
|
|
6275
|
-
const claims = yield* ledger.claimJoining(
|
|
6276
|
-
ClaimJoiningRequest.make({
|
|
6277
|
-
threadId: submission.threadId,
|
|
6278
|
-
hostSubmissionId: submissionId,
|
|
6279
|
-
ownershipToken,
|
|
6280
|
-
maxCount: limit - joinedInputs.length,
|
|
6281
|
-
}),
|
|
6282
|
-
);
|
|
6470
|
+
const claims = yield* prepareInputs(limit);
|
|
6283
6471
|
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6472
|
+
pendingJoinClaims.splice(0, claims.length);
|
|
6473
|
+
for (const { claim, input: payload, rendered } of claims) {
|
|
6474
|
+
yield* preserveToolResults;
|
|
6475
|
+
const recordId = submissionInputRecordId(claim.submissionId);
|
|
6476
|
+
let sequence: CanonicalSequence;
|
|
6477
|
+
const existing = joinedInputEnvelopes.get(claim.submissionId);
|
|
6478
|
+
|
|
6479
|
+
if (existing !== undefined) {
|
|
6480
|
+
// Defensive reattach: the exact record is already canonical, so only the
|
|
6481
|
+
// marker and the delivery remain (DUR-016 — never a duplicate append).
|
|
6482
|
+
sequence = existing.sequence;
|
|
6483
|
+
} else {
|
|
6484
|
+
const envelope = yield* makeEnvelope(
|
|
6485
|
+
recordId,
|
|
6486
|
+
UserInputRecorded.make({
|
|
6487
|
+
submissionId: claim.submissionId,
|
|
6488
|
+
kind: "steering",
|
|
6489
|
+
runId,
|
|
6490
|
+
input: claim.inputPayload,
|
|
6491
|
+
...(payload.messageAdmission === undefined
|
|
6492
|
+
? {}
|
|
6493
|
+
: { messageAdmission: payload.messageAdmission }),
|
|
6494
|
+
}),
|
|
6290
6495
|
);
|
|
6291
6496
|
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
);
|
|
6299
|
-
continue;
|
|
6300
|
-
}
|
|
6301
|
-
|
|
6302
|
-
const payload = {
|
|
6303
|
-
input: claim.inputPayload,
|
|
6304
|
-
...(claimSnapshot.submission.messageAdmission === undefined
|
|
6305
|
-
? {}
|
|
6306
|
-
: { messageAdmission: claimSnapshot.submission.messageAdmission }),
|
|
6307
|
-
};
|
|
6308
|
-
|
|
6309
|
-
const rendered = yield* Effect.result(renderJoinedInput(payload));
|
|
6310
|
-
|
|
6311
|
-
if (Result.isFailure(rendered)) {
|
|
6312
|
-
// The rejecting input gets its own Run and normal typed failure.
|
|
6313
|
-
// Leave it and the unconsumed suffix ready, preserving queue order
|
|
6314
|
-
// and preventing one invalid prompt from failing unrelated receipts.
|
|
6315
|
-
for (const remaining of claims.slice(claims.indexOf(claim))) {
|
|
6316
|
-
yield* ledger.revertJoining(
|
|
6317
|
-
RevertJoiningRequest.make({ submissionId: remaining.submissionId }),
|
|
6318
|
-
);
|
|
6319
|
-
}
|
|
6320
|
-
break;
|
|
6321
|
-
}
|
|
6322
|
-
yield* preserveToolResults;
|
|
6323
|
-
const recordId = submissionInputRecordId(claim.submissionId);
|
|
6324
|
-
let sequence: CanonicalSequence;
|
|
6325
|
-
const existing = joinedInputEnvelopes.get(claim.submissionId);
|
|
6326
|
-
|
|
6327
|
-
if (existing !== undefined) {
|
|
6328
|
-
// Defensive reattach: the exact record is already canonical, so only the
|
|
6329
|
-
// marker and the delivery remain (DUR-016 — never a duplicate append).
|
|
6330
|
-
sequence = existing.sequence;
|
|
6331
|
-
} else {
|
|
6332
|
-
const envelope = yield* makeEnvelope(
|
|
6333
|
-
recordId,
|
|
6334
|
-
UserInputRecorded.make({
|
|
6335
|
-
submissionId: claim.submissionId,
|
|
6336
|
-
kind: "steering",
|
|
6337
|
-
runId,
|
|
6338
|
-
input: claim.inputPayload,
|
|
6339
|
-
...(claimSnapshot.submission.messageAdmission === undefined
|
|
6340
|
-
? {}
|
|
6341
|
-
: { messageAdmission: claimSnapshot.submission.messageAdmission }),
|
|
6342
|
-
}),
|
|
6343
|
-
);
|
|
6344
|
-
|
|
6345
|
-
const result = yield* appendBatch(
|
|
6346
|
-
ctx,
|
|
6347
|
-
CanonicalBatch.make({
|
|
6348
|
-
batchId: submissionInputBatchId(claim.submissionId),
|
|
6349
|
-
producerId: config.producerId,
|
|
6350
|
-
records: [envelope],
|
|
6351
|
-
}),
|
|
6352
|
-
);
|
|
6353
|
-
|
|
6354
|
-
sequence = result.firstSequence;
|
|
6355
|
-
knownIds.add(recordId);
|
|
6356
|
-
yield* hit("join:after-canonical-append");
|
|
6357
|
-
}
|
|
6358
|
-
// Re-read the token: the concurrent lease renewal may rotate it mid-batch.
|
|
6359
|
-
const markToken = yield* Ref.get(tokenRef);
|
|
6360
|
-
|
|
6361
|
-
yield* ledger.markJoined(
|
|
6362
|
-
MarkJoinedRequest.make({
|
|
6363
|
-
submissionId: claim.submissionId,
|
|
6364
|
-
ownershipToken: markToken,
|
|
6365
|
-
recordId,
|
|
6366
|
-
sequence,
|
|
6497
|
+
const result = yield* appendBatch(
|
|
6498
|
+
ctx,
|
|
6499
|
+
CanonicalBatch.make({
|
|
6500
|
+
batchId: submissionInputBatchId(claim.submissionId),
|
|
6501
|
+
producerId: config.producerId,
|
|
6502
|
+
records: [envelope],
|
|
6367
6503
|
}),
|
|
6368
6504
|
);
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
});
|
|
6505
|
+
|
|
6506
|
+
sequence = result.firstSequence;
|
|
6507
|
+
knownIds.add(recordId);
|
|
6508
|
+
yield* hit("join:after-canonical-append");
|
|
6374
6509
|
}
|
|
6510
|
+
// Re-read the token: the concurrent lease renewal may rotate it mid-batch.
|
|
6511
|
+
const markToken = yield* Ref.get(tokenRef);
|
|
6512
|
+
|
|
6513
|
+
yield* ledger.markJoined(
|
|
6514
|
+
MarkJoinedRequest.make({
|
|
6515
|
+
submissionId: claim.submissionId,
|
|
6516
|
+
ownershipToken: markToken,
|
|
6517
|
+
recordId,
|
|
6518
|
+
sequence,
|
|
6519
|
+
}),
|
|
6520
|
+
);
|
|
6521
|
+
deliveredJoinInputs.add(claim.submissionId);
|
|
6522
|
+
joinedInputs.push({
|
|
6523
|
+
...payload,
|
|
6524
|
+
rendered,
|
|
6525
|
+
});
|
|
6375
6526
|
}
|
|
6376
6527
|
|
|
6377
6528
|
return joinedInputs;
|
|
@@ -7306,8 +7457,8 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
7306
7457
|
createdAt,
|
|
7307
7458
|
...(runScopedPrefixLength > 0 ? { runScopedPrefixLength } : {}),
|
|
7308
7459
|
...(completedRun === undefined ? {} : { runCompletion: completedRun }),
|
|
7309
|
-
usage:
|
|
7310
|
-
unobservedModelCalls:
|
|
7460
|
+
usage: usageForCommit(canonicalTurn),
|
|
7461
|
+
unobservedModelCalls: unobservedForCommit(canonicalTurn),
|
|
7311
7462
|
}),
|
|
7312
7463
|
);
|
|
7313
7464
|
|
|
@@ -7373,6 +7524,11 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
7373
7524
|
|
|
7374
7525
|
const handleEvent = (event: RunEvent): Effect.Effect<void, DurableWorkerFailure> => {
|
|
7375
7526
|
switch (event._tag) {
|
|
7527
|
+
case "ModelRestarted": {
|
|
7528
|
+
// A finish part can arrive before the provider stream closes. Its TurnCompleted
|
|
7529
|
+
// only staged this disposable Turn; never let the next seam commit its prefix.
|
|
7530
|
+
return Ref.update(stateRef, (state) => ({ ...state, pendingTurn: undefined }));
|
|
7531
|
+
}
|
|
7376
7532
|
case "TurnStarted": {
|
|
7377
7533
|
// Suspension owns only this Turn's siblings. Earlier results are already canonical
|
|
7378
7534
|
// under their original Turn and must never be re-recorded with a later Turn id.
|
|
@@ -8004,6 +8160,10 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
8004
8160
|
definition: { ...registeredAgent.definition, policy: childPolicy },
|
|
8005
8161
|
};
|
|
8006
8162
|
|
|
8163
|
+
// Restoring the accepted child policy changes no Tool declarations. Retain the
|
|
8164
|
+
// selected registration's contracts instead of resolving the copied Definition.
|
|
8165
|
+
const currentContracts = yield* contractsFor(registeredAgent.definition);
|
|
8166
|
+
|
|
8007
8167
|
const evidence = yield* evidenceFor(records, submissionId, true, snapshot.hostSubmissionId);
|
|
8008
8168
|
const knownIds = knownRecordIdsOf(records);
|
|
8009
8169
|
|
|
@@ -8099,7 +8259,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
8099
8259
|
reconciliationRecords,
|
|
8100
8260
|
reconciliationEvidence.openToolCalls,
|
|
8101
8261
|
knownIds,
|
|
8102
|
-
{ definition: agent.definition, contracts:
|
|
8262
|
+
{ definition: agent.definition, contracts: currentContracts },
|
|
8103
8263
|
);
|
|
8104
8264
|
|
|
8105
8265
|
if (review.uncertain.length > 0 || review.unproven.length > 0) {
|
|
@@ -8139,7 +8299,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
8139
8299
|
if (continuation !== undefined) {
|
|
8140
8300
|
const current = {
|
|
8141
8301
|
definition: agent.definition,
|
|
8142
|
-
contracts:
|
|
8302
|
+
contracts: currentContracts,
|
|
8143
8303
|
};
|
|
8144
8304
|
|
|
8145
8305
|
const operations = operationsFor(continuationRecords, runIdForSubmission(submissionId));
|
|
@@ -8314,6 +8474,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
8314
8474
|
journalMetadata?.snapshot(),
|
|
8315
8475
|
lineage,
|
|
8316
8476
|
approvalDecisionIntents,
|
|
8477
|
+
currentContracts,
|
|
8317
8478
|
runTiming,
|
|
8318
8479
|
yieldAfter,
|
|
8319
8480
|
);
|
|
@@ -8759,9 +8920,6 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
8759
8920
|
);
|
|
8760
8921
|
});
|
|
8761
8922
|
|
|
8762
|
-
const resolveCurrentBinding = (submission: SubmissionSnapshot) =>
|
|
8763
|
-
resolveWorkerBinding(registeredBindings, submission.agentId);
|
|
8764
|
-
|
|
8765
8923
|
const processThreadResolvedImpl = (
|
|
8766
8924
|
threadId: ThreadId,
|
|
8767
8925
|
): Effect.Effect<ReadonlyArray<Settlement>, DurableWorkerFailure | DurableBindingFailure> =>
|
|
@@ -9011,7 +9169,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
9011
9169
|
records,
|
|
9012
9170
|
evidence.openToolCalls.filter((call) => markableIds.has(call.toolCallId)),
|
|
9013
9171
|
knownIds,
|
|
9014
|
-
yield* currentOperationsFor(submission
|
|
9172
|
+
yield* currentOperationsFor(submission),
|
|
9015
9173
|
);
|
|
9016
9174
|
|
|
9017
9175
|
let disposition: "repaired" | "deferred" | "unknown";
|
|
@@ -9050,7 +9208,7 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
9050
9208
|
if (!snapshot.unknownResolutions.some((intent) => intent.resolution._tag === "SafeToRetry"))
|
|
9051
9209
|
return false;
|
|
9052
9210
|
const submission = snapshot.submission;
|
|
9053
|
-
const current = yield* currentOperationsFor(submission
|
|
9211
|
+
const current = yield* currentOperationsFor(submission);
|
|
9054
9212
|
const operations = operationsFor(records, runIdForSubmission(submission.submissionId));
|
|
9055
9213
|
|
|
9056
9214
|
for (const intent of snapshot.unknownResolutions) {
|
|
@@ -10988,6 +11146,29 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
10988
11146
|
}).pipe(Effect.provideService(WorkerRuntime, workerRuntime));
|
|
10989
11147
|
|
|
10990
11148
|
return DurableAgentRuntime.of({
|
|
11149
|
+
bindingRegistryKey: yield* withCrypto(
|
|
11150
|
+
digestJson({
|
|
11151
|
+
selection: bindingSelection?.key ?? null,
|
|
11152
|
+
bindings: (yield* Effect.forEach(registeredBindings, (binding) =>
|
|
11153
|
+
withCrypto(
|
|
11154
|
+
digestJson({
|
|
11155
|
+
agentId: binding.agentId,
|
|
11156
|
+
agent: binding.digests.agent,
|
|
11157
|
+
model: binding.digests.model,
|
|
11158
|
+
tools: binding.digests.tools,
|
|
11159
|
+
replay:
|
|
11160
|
+
binding.digests.replay === undefined
|
|
11161
|
+
? null
|
|
11162
|
+
: {
|
|
11163
|
+
agent: binding.digests.replay.agent,
|
|
11164
|
+
agentBehavior: binding.digests.replay.agentBehavior ?? null,
|
|
11165
|
+
tools: binding.digests.replay.tools,
|
|
11166
|
+
},
|
|
11167
|
+
}),
|
|
11168
|
+
),
|
|
11169
|
+
).pipe(Effect.orDie)).sort(),
|
|
11170
|
+
}),
|
|
11171
|
+
).pipe(Effect.orDie),
|
|
10991
11172
|
workerHost: workerRuntime.acquire,
|
|
10992
11173
|
messagingHost: messagingRuntime.acquire,
|
|
10993
11174
|
submitRegistered,
|
|
@@ -11079,6 +11260,8 @@ const make = Effect.fn("DurableAgentRuntime.make")(function* (
|
|
|
11079
11260
|
export class DurableAgentRuntime extends Context.Service<
|
|
11080
11261
|
DurableAgentRuntime,
|
|
11081
11262
|
{
|
|
11263
|
+
/** Stable registration identity for hosts parking unavailable bindings; never an admission authority. */
|
|
11264
|
+
readonly bindingRegistryKey: string;
|
|
11082
11265
|
/** Acquire an authenticated source Thread facet; its References confer no authority. */
|
|
11083
11266
|
readonly workerHost: (request: {
|
|
11084
11267
|
readonly sourceThreadId: ThreadId;
|
|
@@ -11330,7 +11513,7 @@ export class DurableAgentRuntime extends Context.Service<
|
|
|
11330
11513
|
>()("@effect-agent/thread/DurableAgentRuntime") {
|
|
11331
11514
|
/**
|
|
11332
11515
|
* Resolve typed registrations and capture their services once in the runtime's Layer Scope.
|
|
11333
|
-
* Every claimed head must
|
|
11516
|
+
* Every claimed head must select exactly one current registered Definition. Worker calls
|
|
11334
11517
|
* cannot replace these registrations or their captured services. Tool authorization is required.
|
|
11335
11518
|
*/
|
|
11336
11519
|
static layerRegistered<const Entries extends ReadonlyArray<AgentRegistration>>(
|