@zq-silk/yui 0.13.9 → 0.14.0
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/ARCHITECTURE.md +69 -428
- package/README.md +108 -298
- package/dist/agent/managedRuntimeEnvironment.js +2 -2
- package/dist/cli/commandCatalog.js +39 -77
- package/dist/cli/interactionCandidates.js +4 -4
- package/dist/cli/interactionPolicy.js +7 -10
- package/dist/cli/invocationRouter.js +1 -1
- package/dist/cli/updateCommand.js +6 -27
- package/dist/cli/updateOrchestrator.js +63 -484
- package/dist/cli/updatePorts.js +15 -333
- package/dist/cli/upgradeCommand.js +8 -65
- package/dist/cli.js +57 -242
- package/dist/commands/configCommands.js +11 -62
- package/dist/commands/executionAuditCommands.js +23 -23
- package/dist/commands/globalRoleCommands.js +2 -7
- package/dist/commands/jobCommands.js +1 -4
- package/dist/commands/projectCommands.js +5 -5
- package/dist/commands/releaseCommands.js +3 -10
- package/dist/commands/resourcesCommands.js +2 -2
- package/dist/commands/sessionCommands.js +2 -2
- package/dist/commands/taskActor.js +31 -39
- package/dist/commands/taskChangeSetCommands.js +5 -12
- package/dist/commands/taskCommands.js +464 -1249
- package/dist/commands/taskContextCommand.js +35 -36
- package/dist/commands/taskExecutionCommands.js +33 -46
- package/dist/commands/taskInputCommands.js +20 -42
- package/dist/commands/taskNextActionCommand.js +9 -9
- package/dist/commands/taskOverviewCommand.js +56 -95
- package/dist/commands/taskRoleRuntimeStatus.js +77 -107
- package/dist/commands/taskUpstreamCommands.js +3 -3
- package/dist/commands/taskWorkspaceCommands.js +7 -79
- package/dist/commands/telemetryCommands.js +32 -124
- package/dist/commands/workflowCommands.js +3 -3
- package/dist/completion/fileCompletionManager.js +1 -1
- package/dist/config/configCatalog.js +4 -6
- package/dist/config/yuiConfig.js +6 -43
- package/dist/context/dispatchContext.js +14 -30
- package/dist/context/roleSessionContext.js +2 -2
- package/dist/context/sessionBootstrapManifest.js +2 -2
- package/dist/context/{runContextPack.js → turnContextPack.js} +58 -73
- package/dist/context/turnInputContract.js +204 -0
- package/dist/context/wakeNotification.js +2 -2
- package/dist/controller/agentRuntimeObserver.js +18 -18
- package/dist/controller/clientRuntime.js +13 -20
- package/dist/controller/controller.js +89 -116
- package/dist/controller/fileSchedulerStoreAdapter.js +511 -742
- package/dist/controller/jobControl.js +17 -17
- package/dist/controller/resourceInventory.js +6 -6
- package/dist/controller/resourceInventoryLinux.js +38 -59
- package/dist/controller/resourceInventoryRpc.js +3 -3
- package/dist/controller/resourceInventoryWorker.js +1 -1
- package/dist/controller/runtime.js +46 -53
- package/dist/controller/runtimeEventInbox.js +23 -31
- package/dist/controller/runtimeEventProcessor.js +15 -15
- package/dist/controller/{runtimeHookRunFence.js → runtimeHookTurnFence.js} +87 -81
- package/dist/controller/runtimeLaunchCoordinator.js +3 -3
- package/dist/controller/runtimeObservationHook.js +11 -8
- package/dist/controller/sessionNotify.js +11 -11
- package/dist/controller/structuredProviderObservation.js +89 -16
- package/dist/coordination/workMailbox.js +309 -579
- package/dist/coordination/workMailboxQueue.js +5 -6
- package/dist/core/controllerClient.js +1 -91
- package/dist/core/controllerServer.js +3 -6
- package/dist/doctor/doctor.js +51 -314
- package/dist/execution/candidateConvergence.js +3 -3
- package/dist/execution/executionGroup.js +32 -33
- package/dist/execution/executionHealth.js +36 -38
- package/dist/execution/resourceBroker.js +12 -12
- package/dist/executor/agentExecutor.js +30 -265
- package/dist/executor/effectiveLaunch.js +9 -19
- package/dist/executor/executorRegistry.js +43 -17
- package/dist/executor/fileRoleLaunchPlanner.js +56 -56
- package/dist/executor/launchPlan.js +3 -3
- package/dist/executor/workspacePreflightClassification.js +16 -16
- package/dist/grant/capabilityGrant.js +20 -25
- package/dist/input/inputRequest.js +12 -12
- package/dist/integration/changeSet.js +9 -13
- package/dist/integration/changeSetManifest.js +1 -1
- package/dist/integration/gitIntegrationService.js +2 -2
- package/dist/integration/integrationQueueService.js +5 -21
- package/dist/integration/overlapDiagnostics.js +2 -2
- package/dist/interaction/operatorPresentation.js +1 -1
- package/dist/job/jobRunner.js +1 -1
- package/dist/lifecycle/canonicalLifecycleEvent.js +25 -25
- package/dist/lifecycle/{exactRunTerminalization.js → exactTurnTerminalization.js} +116 -232
- package/dist/message/message.js +6 -6
- package/dist/observability/executionAudit.js +74 -86
- package/dist/observability/faultClassification.js +7 -24
- package/dist/observability/orchestrationMetrics.js +5 -5
- package/dist/observability/runtimeIdentity.js +34 -101
- package/dist/profile/agentProfile.js +1 -1
- package/dist/release/cliHomeReleaseFence.js +3 -3
- package/dist/release/releaseWorkflowEngine.js +6 -10
- package/dist/release/releaseWorkflowPorts.js +2 -2
- package/dist/release/workflowFileLock.js +1 -1
- package/dist/repository/checkoutSwap.js +1 -1
- package/dist/repository/gitWorkspace.js +0 -13
- package/dist/repository/project.js +1 -1
- package/dist/repository/projectMaintenanceLock.js +1 -2
- package/dist/repository/taskBaseFreshness.js +13 -13
- package/dist/repository/taskWorkspaceCoordinator.js +21 -25
- package/dist/repository/taskWorkspaceIdentity.js +8 -21
- package/dist/repository/taskWorkspacePreparer.js +63 -620
- package/dist/resources/autoResourceGc.js +3 -3
- package/dist/resources/liveReferences.js +1 -1
- package/dist/resources/resourceGc.js +1 -1
- package/dist/resources/sqliteResourceRegistry.js +1 -1
- package/dist/review/reviewDecision.js +7 -7
- package/dist/review/reviewFindingLedger.js +1 -1
- package/dist/review/reviewOutcomeClassifier.js +35 -50
- package/dist/review/reviewRound.js +14 -25
- package/dist/review/reviewerAvailability.js +4 -4
- package/dist/review/taskFinalReviewContractResolution.js +41 -0
- package/dist/role/role.js +6 -3
- package/dist/runtime/agentDriver.js +4 -0
- package/dist/runtime/agentHost.js +151 -36
- package/dist/runtime/builtinAgentDrivers.js +79 -2
- package/dist/runtime/codexAppServerRuntime.js +122 -0
- package/dist/runtime/continuationManager.js +3 -5
- package/dist/runtime/exactControlPlane.js +17 -42
- package/dist/runtime/firstProgressAdvisory.js +1 -1
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/launchDiagnostics.js +2 -2
- package/dist/runtime/lifecycleReservation.js +4 -4
- package/dist/runtime/processExitObservation.js +1 -1
- package/dist/runtime/processExitOutbox.js +0 -32
- package/dist/runtime/promptEnvelope.js +9 -9
- package/dist/runtime/providerContinuation.js +2 -2
- package/dist/runtime/providerContinuationReconciliationService.js +2 -2
- package/dist/runtime/providerRuntimeIdentity.js +76 -24
- package/dist/runtime/recentTurnIds.js +38 -0
- package/dist/runtime/runtimeContinuationProjection.js +2 -2
- package/dist/runtime/runtimeHealthPolicy.js +1 -1
- package/dist/runtime/runtimeObservation.js +58 -21
- package/dist/runtime/runtimeProjection.js +19 -27
- package/dist/runtime/sessionLaunchRequest.js +2 -2
- package/dist/runtime/structuredProviderHost.js +177 -12
- package/dist/runtime/tmuxAdapters.js +46 -11
- package/dist/scheduler/activeRoleTurnDelivery.js +245 -0
- package/dist/scheduler/leaderWakeupProcessor.js +147 -445
- package/dist/scheduler/operatorEvent.js +4 -6
- package/dist/scheduler/resourceQueueProjection.js +71 -0
- package/dist/scheduler/{roleRunLiveness.js → roleTurnLiveness.js} +24 -28
- package/dist/scheduler/{roleRunStall.js → roleTurnStall.js} +162 -247
- package/dist/scheduler/taskExecutionProjection.js +99 -99
- package/dist/scheduler/taskObservabilityProjection.js +10 -10
- package/dist/scheduler/taskWake.js +4 -4
- package/dist/scheduler/wakeReason.js +6 -10
- package/dist/scheduler/wakeupQueue.js +0 -9
- package/dist/setup/setupCommand.js +2 -2
- package/dist/storage/currentTaskStore.js +46 -0
- package/dist/storage/persistenceWorker.js +1 -1
- package/dist/storage/sqliteSchema.js +81 -485
- package/dist/storage/sqliteStore.js +206 -365
- package/dist/storage/storageSchema.js +1 -15
- package/dist/storage/storageVersions.js +8 -9
- package/dist/storage/storeRpc.js +10 -34
- package/dist/storage/taskStore.js +63 -3415
- package/dist/storage/upgrade/recordVersions.js +55 -149
- package/dist/storage/upgrade/upgradeOrchestrator.js +89 -1752
- package/dist/task/completionReadiness.js +5 -5
- package/dist/task/deliveryGuard.js +10 -10
- package/dist/task/nextAction.js +74 -77
- package/dist/task/task.js +2 -4
- package/dist/task/taskRecordReference.js +3 -3
- package/dist/task/taskRecordRetirement.js +1 -1
- package/dist/telemetry/sqliteTelemetryStore.js +53 -53
- package/dist/telemetry/telemetryConfig.js +14 -14
- package/dist/telemetry/telemetryWiring.js +8 -14
- package/dist/turn/turn.js +356 -0
- package/dist/{run/runIdentity.js → turn/turnIdentity.js} +4 -4
- package/dist/verification/gateArtifactStore.js +2 -2
- package/dist/web/assets/client/app.js +1 -1
- package/dist/web/assets/client/components.js +29 -54
- package/dist/web/assets/client/i18n.js +17 -37
- package/dist/web/assets/client/view.js +37 -37
- package/dist/web/assets/shell.js +1 -1
- package/dist/web/assets/styles/cards.js +5 -5
- package/dist/web/assets/styles/widgets.js +1 -2
- package/dist/web/webSnapshot.js +65 -60
- package/dist/workItem/workItem.js +11 -11
- package/dist/workspace/workItemChangeSetManager.js +1 -1
- package/docs/task-local-identity.md +5 -5
- package/i18n/README.zh-CN.md +41 -54
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +85 -83
- package/skills/yui-operator/SKILL.md +16 -16
- package/skills/yui-reviewer/SKILL.md +10 -10
- package/skills/yui-runtime/SKILL.md +17 -18
- package/skills/yui-worker/SKILL.md +16 -18
- package/dist/context/runContextContract.js +0 -162
- package/dist/executor/turnCompletion.js +0 -126
- package/dist/review/taskFinalReviewContractEvent.js +0 -1
- package/dist/review/taskFinalReviewContractRebind.js +0 -367
- package/dist/run/agentRun.js +0 -356
- package/dist/run/rejectedYieldAttempt.js +0 -221
- package/dist/run/runControlRequest.js +0 -50
- package/dist/run/yieldReceipt.js +0 -65
- package/dist/runtime/turnCompletion.js +0 -3
- package/dist/scheduler/actionability.js +0 -323
- package/dist/scheduler/activeRoleRunDelivery.js +0 -868
- package/dist/scheduler/activeTaskProgress.js +0 -126
- package/dist/storage/compatibleTaskStore.js +0 -248
- package/dist/storage/migration/baseline.js +0 -78
- package/dist/storage/migration/classifier.js +0 -51
- package/dist/storage/migration/compatibleCodec.js +0 -53
- package/dist/storage/migration/engine.js +0 -147
- package/dist/storage/migration/index.js +0 -33
- package/dist/storage/migration/planner.js +0 -154
- package/dist/storage/migration/productionRegistry.js +0 -3931
- package/dist/storage/migration/registry.js +0 -169
- package/dist/storage/migration/report.js +0 -54
- package/dist/storage/migration/types.js +0 -31
- package/dist/storage/upgrade/homeClassification.js +0 -353
- package/dist/storage/upgrade/homeMigrationTarget.js +0 -595
- package/dist/storage/upgrade/migrationReceipt.js +0 -67
- package/dist/storage/upgrade/offlineUpgradeInventory.js +0 -453
- package/dist/storage/upgrade/productionMigrationRegistry.js +0 -6
- package/dist/storage/upgrade/pseudoLayoutRepair.js +0 -241
- package/dist/storage/upgrade/recordVersionScan.js +0 -176
- package/dist/storage/upgrade/sqliteFileSet.js +0 -50
- package/dist/storage/upgrade/sqliteMigrationTarget.js +0 -375
- package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +0 -305
- package/dist/storage/upgrade/sqliteStateMigration.js +0 -918
- package/dist/storage/upgrade/switchProgress.js +0 -80
- package/dist/storage/upgrade/upgradeReceipt.js +0 -161
- package/dist/storage/upgradeCoordination.js +0 -187
- package/dist/storage/upgradeFence.js +0 -366
- package/dist/telemetry/telemetryCompaction.js +0 -252
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { closeSync, constants, existsSync, fchmodSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { withUpgradeCoordinationLock } from "../storage/upgradeCoordination.js";
|
|
5
4
|
import { createRuntimeObservation, isRuntimeTokenEvidence } from "../runtime/runtimeObservation.js";
|
|
6
5
|
export const MAX_RUNTIME_TURN_SUMMARY_BYTES = 32 * 1024;
|
|
7
6
|
export const MAX_RUNTIME_EVENT_FILE_BYTES = 16 * 1024 * 1024;
|
|
@@ -10,7 +9,7 @@ const INVALID_RUNTIME_EVENT_DIRECTORY = join("runtime", "inbox-invalid");
|
|
|
10
9
|
const EVENT_ID_PATTERN = /^turn-[a-f0-9]{64}$/;
|
|
11
10
|
/**
|
|
12
11
|
* Durable ingress for facts emitted by native Agent hooks. It deliberately
|
|
13
|
-
* owns no
|
|
12
|
+
* owns no TaskStore lock: immutable files are acknowledged only after the
|
|
14
13
|
* Controller commits their authoritative aggregate effect.
|
|
15
14
|
*/
|
|
16
15
|
export class FileRuntimeEventInbox {
|
|
@@ -156,24 +155,17 @@ export class FileRuntimeEventInbox {
|
|
|
156
155
|
return acknowledged;
|
|
157
156
|
}
|
|
158
157
|
publish(event) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
&& isRuntimeTokenEvidence(event.observation)) {
|
|
168
|
-
const existing = this.list().find((candidate) => (candidate.type === "runtime-observation"
|
|
169
|
-
&& candidate.taskId === event.taskId
|
|
170
|
-
&& candidate.observation.eventId === event.observation.eventId));
|
|
171
|
-
if (existing !== undefined) {
|
|
172
|
-
return { event: existing, created: false };
|
|
173
|
-
}
|
|
158
|
+
this.hooks.afterAdmission?.();
|
|
159
|
+
if (event.type === "runtime-observation"
|
|
160
|
+
&& isRuntimeTokenEvidence(event.observation)) {
|
|
161
|
+
const existing = this.list().find((candidate) => (candidate.type === "runtime-observation"
|
|
162
|
+
&& candidate.taskId === event.taskId
|
|
163
|
+
&& candidate.observation.eventId === event.observation.eventId));
|
|
164
|
+
if (existing !== undefined) {
|
|
165
|
+
return { event: existing, created: false };
|
|
174
166
|
}
|
|
175
|
-
|
|
176
|
-
|
|
167
|
+
}
|
|
168
|
+
return this.publishUnlocked(event);
|
|
177
169
|
}
|
|
178
170
|
publishUnlocked(event) {
|
|
179
171
|
const content = `${JSON.stringify(event)}\n`;
|
|
@@ -285,8 +277,8 @@ function runtimeEventId(type, input) {
|
|
|
285
277
|
provider.adapterId,
|
|
286
278
|
provider.launchId ?? null,
|
|
287
279
|
provider.nativeSessionId,
|
|
288
|
-
|
|
289
|
-
provider.
|
|
280
|
+
provider.nativeTurnId,
|
|
281
|
+
provider.turnId ?? null
|
|
290
282
|
];
|
|
291
283
|
return `turn-${createHash("sha256").update(JSON.stringify(common)).digest("hex")}`;
|
|
292
284
|
}
|
|
@@ -305,10 +297,10 @@ function normalizeNativeTurnCompletedInput(input) {
|
|
|
305
297
|
? {}
|
|
306
298
|
: { launchId: requireIdentityText(input.launchId, "Launch id") }),
|
|
307
299
|
nativeSessionId: requireIdentityText(input.nativeSessionId, "Native session id"),
|
|
308
|
-
|
|
309
|
-
...(input.
|
|
300
|
+
nativeTurnId: requireIdentityText(input.nativeTurnId, "Provider native Turn id"),
|
|
301
|
+
...(input.turnId === undefined
|
|
310
302
|
? {}
|
|
311
|
-
: {
|
|
303
|
+
: { turnId: requireIdentityText(input.turnId, "Turn id") }),
|
|
312
304
|
...(input.title === undefined
|
|
313
305
|
? {}
|
|
314
306
|
: { title: requireIdentityText(input.title, "Session title") }),
|
|
@@ -393,16 +385,16 @@ function parseNativeTurnCompletedEvent(value) {
|
|
|
393
385
|
const expected = scope === "task"
|
|
394
386
|
? [
|
|
395
387
|
"schemaVersion", "id", "type", "receivedAt", "scope", "taskId",
|
|
396
|
-
"roleName", "agentId", "adapterId", "nativeSessionId", "
|
|
388
|
+
"roleName", "agentId", "adapterId", "nativeSessionId", "nativeTurnId", "summary",
|
|
397
389
|
...(value.launchId === undefined ? [] : ["launchId"]),
|
|
398
|
-
...(value.
|
|
390
|
+
...(value.turnId === undefined ? [] : ["turnId"]),
|
|
399
391
|
...(value.title === undefined ? [] : ["title"])
|
|
400
392
|
]
|
|
401
393
|
: [
|
|
402
394
|
"schemaVersion", "id", "type", "receivedAt", "scope",
|
|
403
|
-
"roleName", "agentId", "adapterId", "nativeSessionId", "
|
|
395
|
+
"roleName", "agentId", "adapterId", "nativeSessionId", "nativeTurnId", "summary",
|
|
404
396
|
...(value.launchId === undefined ? [] : ["launchId"]),
|
|
405
|
-
...(value.
|
|
397
|
+
...(value.turnId === undefined ? [] : ["turnId"]),
|
|
406
398
|
...(value.title === undefined ? [] : ["title"])
|
|
407
399
|
];
|
|
408
400
|
if ((scope !== "task" && scope !== "global")
|
|
@@ -418,8 +410,8 @@ function parseNativeTurnCompletedEvent(value) {
|
|
|
418
410
|
adapterId: value.adapterId,
|
|
419
411
|
...(value.launchId === undefined ? {} : { launchId: value.launchId }),
|
|
420
412
|
nativeSessionId: value.nativeSessionId,
|
|
421
|
-
|
|
422
|
-
...(value.
|
|
413
|
+
nativeTurnId: value.nativeTurnId,
|
|
414
|
+
...(value.turnId === undefined ? {} : { turnId: value.turnId }),
|
|
423
415
|
...(value.title === undefined ? {} : { title: value.title }),
|
|
424
416
|
summary: value.summary
|
|
425
417
|
});
|
|
@@ -483,7 +475,7 @@ function hasSameIdentity(left, right) {
|
|
|
483
475
|
&& (!("nativeSessionId" in left)
|
|
484
476
|
|| !("nativeSessionId" in right)
|
|
485
477
|
|| left.nativeSessionId === right.nativeSessionId)
|
|
486
|
-
&& (!("
|
|
478
|
+
&& (!("turnId" in left) || !("turnId" in right) || left.turnId === right.turnId)
|
|
487
479
|
&& (!("turnId" in left) || !("turnId" in right) || left.turnId === right.turnId)
|
|
488
480
|
&& (!("jobId" in left) || !("jobId" in right) || left.jobId === right.jobId);
|
|
489
481
|
}
|
|
@@ -167,7 +167,7 @@ export class FileRuntimeEventProcessor {
|
|
|
167
167
|
adapterId: this.drivers.require(fence.driverId).adapterId,
|
|
168
168
|
launchId: fence.launchId,
|
|
169
169
|
nativeSessionId: fence.nativeSessionId,
|
|
170
|
-
...(fence.
|
|
170
|
+
...(fence.turnId === undefined ? {} : { turnId: fence.turnId })
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
}
|
|
@@ -179,7 +179,7 @@ export class FileRuntimeEventProcessor {
|
|
|
179
179
|
adapterId: event.adapterId,
|
|
180
180
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
181
181
|
nativeSessionId: event.nativeSessionId,
|
|
182
|
-
...(event.
|
|
182
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId })
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -213,8 +213,8 @@ export class FileRuntimeEventProcessor {
|
|
|
213
213
|
adapterId: event.adapterId,
|
|
214
214
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
215
215
|
nativeSessionId: event.nativeSessionId,
|
|
216
|
-
|
|
217
|
-
...(event.
|
|
216
|
+
nativeTurnId: event.nativeTurnId,
|
|
217
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
218
218
|
summary: event.summary
|
|
219
219
|
};
|
|
220
220
|
if (task === null)
|
|
@@ -244,7 +244,7 @@ export class FileRuntimeEventProcessor {
|
|
|
244
244
|
adapterId: event.adapterId,
|
|
245
245
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
246
246
|
nativeSessionId: event.nativeSessionId,
|
|
247
|
-
|
|
247
|
+
nativeTurnId: event.nativeTurnId,
|
|
248
248
|
...(event.title === undefined ? {} : { title: event.title }),
|
|
249
249
|
summary: event.summary
|
|
250
250
|
};
|
|
@@ -267,7 +267,7 @@ export class FileRuntimeEventProcessor {
|
|
|
267
267
|
taskId: event.taskId,
|
|
268
268
|
roleName: fence.roleName,
|
|
269
269
|
agentId: fence.agentId,
|
|
270
|
-
...(fence.
|
|
270
|
+
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
271
271
|
launchId: fence.launchId,
|
|
272
272
|
nativeSessionId: fence.nativeSessionId,
|
|
273
273
|
reason
|
|
@@ -284,7 +284,7 @@ export class FileRuntimeEventProcessor {
|
|
|
284
284
|
taskId: event.taskId,
|
|
285
285
|
roleName: event.roleName,
|
|
286
286
|
agentId: event.agentId,
|
|
287
|
-
...(event.
|
|
287
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
288
288
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
289
289
|
nativeSessionId: event.nativeSessionId,
|
|
290
290
|
reason
|
|
@@ -418,7 +418,7 @@ function progressStreamKey(event) {
|
|
|
418
418
|
fence.driverId,
|
|
419
419
|
fence.launchId,
|
|
420
420
|
fence.nativeSessionId ?? null,
|
|
421
|
-
fence.
|
|
421
|
+
fence.turnId ?? null,
|
|
422
422
|
payload.activity,
|
|
423
423
|
isRuntimeTokenEvidence(event.observation) ? "usage" : "signal"
|
|
424
424
|
]);
|
|
@@ -644,7 +644,7 @@ export class AsyncRuntimeEventProcessor {
|
|
|
644
644
|
adapterId: this.drivers.require(fence.driverId).adapterId,
|
|
645
645
|
launchId: fence.launchId,
|
|
646
646
|
nativeSessionId: fence.nativeSessionId,
|
|
647
|
-
...(fence.
|
|
647
|
+
...(fence.turnId === undefined ? {} : { turnId: fence.turnId })
|
|
648
648
|
});
|
|
649
649
|
}
|
|
650
650
|
return outcome;
|
|
@@ -660,8 +660,8 @@ export class AsyncRuntimeEventProcessor {
|
|
|
660
660
|
adapterId: event.adapterId,
|
|
661
661
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
662
662
|
nativeSessionId: event.nativeSessionId,
|
|
663
|
-
|
|
664
|
-
...(event.
|
|
663
|
+
nativeTurnId: event.nativeTurnId,
|
|
664
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
665
665
|
summary: event.summary
|
|
666
666
|
};
|
|
667
667
|
if (task === null)
|
|
@@ -689,7 +689,7 @@ export class AsyncRuntimeEventProcessor {
|
|
|
689
689
|
adapterId: event.adapterId,
|
|
690
690
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
691
691
|
nativeSessionId: event.nativeSessionId,
|
|
692
|
-
...(event.
|
|
692
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId })
|
|
693
693
|
});
|
|
694
694
|
return "applied";
|
|
695
695
|
}
|
|
@@ -700,7 +700,7 @@ export class AsyncRuntimeEventProcessor {
|
|
|
700
700
|
adapterId: event.adapterId,
|
|
701
701
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
702
702
|
nativeSessionId: event.nativeSessionId,
|
|
703
|
-
|
|
703
|
+
nativeTurnId: event.nativeTurnId,
|
|
704
704
|
...(event.title === undefined ? {} : { title: event.title }),
|
|
705
705
|
summary: event.summary
|
|
706
706
|
};
|
|
@@ -723,7 +723,7 @@ export class AsyncRuntimeEventProcessor {
|
|
|
723
723
|
taskId: event.taskId,
|
|
724
724
|
roleName: fence.roleName,
|
|
725
725
|
agentId: fence.agentId,
|
|
726
|
-
...(fence.
|
|
726
|
+
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
727
727
|
launchId: fence.launchId,
|
|
728
728
|
nativeSessionId: fence.nativeSessionId,
|
|
729
729
|
reason
|
|
@@ -736,7 +736,7 @@ export class AsyncRuntimeEventProcessor {
|
|
|
736
736
|
taskId: event.taskId,
|
|
737
737
|
roleName: event.roleName,
|
|
738
738
|
agentId: event.agentId,
|
|
739
|
-
...(event.
|
|
739
|
+
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
740
740
|
...(event.launchId === undefined ? {} : { launchId: event.launchId }),
|
|
741
741
|
nativeSessionId: event.nativeSessionId,
|
|
742
742
|
reason
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { openCurrentTaskStore } from "../storage/currentTaskStore.js";
|
|
2
2
|
import { hasRuntimeCleanupObligation, isRuntimeLaunchReservation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
|
|
3
3
|
import { nativeSessionIdForLaunch } from "../runtime/preallocatedNativeSession.js";
|
|
4
4
|
import { runtimeObservationFromTaskEvent } from "../runtime/runtimeObservation.js";
|
|
5
5
|
import { YUI_CONTROL_PLANE_DESCRIPTOR, YUI_TASK_RUNTIME_DESCRIPTOR, assertExactTaskRuntimeEnvironment, exactControlPlaneDigest, parseExactControlPlaneDescriptor, refreshReusedTaskRuntimeDescriptorSource } from "../runtime/exactControlPlane.js";
|
|
6
|
-
import {
|
|
6
|
+
import { formatTurnReceiptId } from "../task/taskRecordReference.js";
|
|
7
|
+
import { managedProviderTurnId } from "../runtime/providerRuntimeIdentity.js";
|
|
7
8
|
/**
|
|
8
9
|
* Resolves turn identity from the current durable in-flight fence. The one
|
|
9
10
|
* exception is a Driver-declared startup Session Hook, which can arrive before
|
|
10
|
-
* Session projection and is fenced by the exact
|
|
11
|
+
* Session projection and is fenced by the exact Turn-bound launch reservation.
|
|
11
12
|
* Preallocated identities are additionally checked against Yui's deterministic
|
|
12
13
|
* launch identity. The immutable event is revalidated by the inbox fold.
|
|
13
14
|
*/
|
|
14
|
-
export function
|
|
15
|
+
export function resolveRuntimeHookTurnFence(environment, adapterId, payloadNativeSessionId, options = {}) {
|
|
15
16
|
if (environment.YUI_SESSION_SCOPE !== "task") {
|
|
16
17
|
throw new Error("Runtime observation Hook requires a Task session scope.");
|
|
17
18
|
}
|
|
@@ -34,12 +35,12 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
34
35
|
&& nativeSessionId !== requireIdentity(expectedNativeSessionId, "YUI native session id")) {
|
|
35
36
|
throw new Error("Runtime observation Hook native Session does not match its launch envelope.");
|
|
36
37
|
}
|
|
37
|
-
const store =
|
|
38
|
+
const store = openCurrentTaskStore(home);
|
|
38
39
|
const task = store.getTask(taskId);
|
|
39
40
|
if (task === null
|
|
40
|
-
|| task.status
|
|
41
|
-
|
|
42
|
-
throw new Error("Runtime observation Hook Task
|
|
41
|
+
|| (!(task.status === "active" && task.executionGate.state === "enabled")
|
|
42
|
+
&& !(task.status === "completed" && (options.terminal === true || options.sessionOnly === true)))) {
|
|
43
|
+
throw new Error("Runtime observation Hook Task does not accept this lifecycle boundary.");
|
|
43
44
|
}
|
|
44
45
|
const role = store.getRole(taskId, roleName);
|
|
45
46
|
if (role === null || role.activeAgentId !== agentId) {
|
|
@@ -49,20 +50,38 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
49
50
|
if (sessions !== null && sessions.activeAgentId !== agentId) {
|
|
50
51
|
throw new Error("Runtime observation Hook Session Agent is not current.");
|
|
51
52
|
}
|
|
52
|
-
const inFlight = sessions?.inFlight;
|
|
53
53
|
const session = sessions?.sessions[agentId];
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
&&
|
|
59
|
-
&&
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
const activeTurn = store.getActiveTurn(taskId, roleName);
|
|
55
|
+
const providerTurn = sessions?.providerBinding?.turn;
|
|
56
|
+
const directProviderTurn = providerTurn !== null
|
|
57
|
+
&& providerTurn !== undefined
|
|
58
|
+
&& providerTurn.turnId === undefined
|
|
59
|
+
&& ((options.attemptId !== undefined && providerTurn.attemptId === options.attemptId)
|
|
60
|
+
|| (options.nativeTurnId !== undefined && providerTurn.nativeTurnId === options.nativeTurnId));
|
|
61
|
+
const sessionOnlyObservation = options.sessionOnly === true && activeTurn === null;
|
|
62
|
+
if (directProviderTurn || sessionOnlyObservation) {
|
|
63
|
+
if (session === undefined
|
|
64
|
+
|| session.adapterId !== adapterId
|
|
65
|
+
|| session.launchId !== launchId
|
|
66
|
+
|| session.nativeSessionId !== nativeSessionId
|
|
67
|
+
|| session.effective.workspace.root !== workspace) {
|
|
68
|
+
throw new Error("Runtime observation Hook Session does not match durable state.");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
taskId,
|
|
72
|
+
roleName,
|
|
73
|
+
agentId,
|
|
74
|
+
launchId,
|
|
75
|
+
...(directProviderTurn ? { receiptId: providerTurn.attemptId } : {}),
|
|
76
|
+
nativeSessionId,
|
|
77
|
+
workspace
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const activationReceiptId = providerTurn !== null
|
|
81
|
+
&& providerTurn !== undefined
|
|
82
|
+
&& managedProviderTurnId(providerTurn) === activeTurn?.id
|
|
83
|
+
? providerTurn.attemptId
|
|
84
|
+
: activeTurn === null ? undefined : formatTurnReceiptId(taskId, activeTurn.id);
|
|
66
85
|
const acceptedTurn = options.nativeTurnId === undefined
|
|
67
86
|
? null
|
|
68
87
|
: acceptedTurnBinding(store.listEvents(taskId), {
|
|
@@ -87,21 +106,21 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
87
106
|
}));
|
|
88
107
|
const exactReservation = isRuntimeLaunchReservation(mailbox?.processing, launchId)
|
|
89
108
|
&& !hasRuntimeCleanupObligation(mailbox);
|
|
90
|
-
const
|
|
109
|
+
const startupTurnId = options.startupSession === undefined
|
|
91
110
|
? undefined
|
|
92
|
-
: requireIdentity(runtime?.
|
|
93
|
-
?? environment.
|
|
94
|
-
const startupReservation =
|
|
111
|
+
: requireIdentity(runtime?.turnId
|
|
112
|
+
?? environment.YUI_TURN_ID, "Turn id");
|
|
113
|
+
const startupReservation = startupTurnId !== undefined
|
|
95
114
|
&& exactReservation
|
|
96
115
|
&& !hasRuntimeCleanupObligation(mailbox);
|
|
97
|
-
const
|
|
116
|
+
const startupTurn = startupTurnId === undefined
|
|
98
117
|
? null
|
|
99
|
-
: store.
|
|
118
|
+
: store.getTurn(taskId, startupTurnId);
|
|
100
119
|
const replacementStartup = options.startupSession !== undefined
|
|
101
120
|
&& session !== undefined
|
|
102
121
|
&& sessions !== null
|
|
103
122
|
&& startupReservation
|
|
104
|
-
&&
|
|
123
|
+
&& startupTurn?.mode === "new"
|
|
105
124
|
&& session.status === "ended";
|
|
106
125
|
const preallocatedStartup = options.startupSession === "preallocated"
|
|
107
126
|
&& expectedNativeSessionId !== undefined
|
|
@@ -112,44 +131,31 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
112
131
|
&& expectedNativeSessionId === undefined
|
|
113
132
|
&& (session === undefined || replacementStartup)
|
|
114
133
|
&& startupReservation;
|
|
115
|
-
const
|
|
116
|
-
? requireIdentity(environment.
|
|
134
|
+
const terminalTurnId = options.terminal === true && acceptedBinding === null
|
|
135
|
+
? requireIdentity(environment.YUI_TURN_ID ?? runtime?.turnId, "Turn id")
|
|
117
136
|
: undefined;
|
|
118
|
-
const
|
|
119
|
-
? store.
|
|
120
|
-
:
|
|
137
|
+
const terminalTurn = acceptedBinding !== null
|
|
138
|
+
? store.getTurn(taskId, acceptedBinding.fence.turnId)
|
|
139
|
+
: terminalTurnId === undefined
|
|
121
140
|
? null
|
|
122
|
-
: store.
|
|
123
|
-
const exactTerminal =
|
|
124
|
-
&&
|
|
125
|
-
&&
|
|
126
|
-
&&
|
|
127
|
-
&&
|
|
128
|
-
&& session !== undefined
|
|
129
|
-
|
|
130
|
-
if ((inFlight === null || inFlight === undefined)
|
|
141
|
+
: store.getTurn(taskId, terminalTurnId);
|
|
142
|
+
const exactTerminal = terminalTurn !== null
|
|
143
|
+
&& terminalTurn.status !== "active"
|
|
144
|
+
&& terminalTurn.roleName === roleName
|
|
145
|
+
&& terminalTurn.effective.agentId === agentId
|
|
146
|
+
&& terminalTurn.effective.adapterId === adapterId
|
|
147
|
+
&& session !== undefined;
|
|
148
|
+
if (activeTurn === null
|
|
131
149
|
&& !preallocatedStartup
|
|
132
150
|
&& !discoveredStartup
|
|
133
151
|
&& !exactTerminal
|
|
134
152
|
&& acceptedBinding === null) {
|
|
135
|
-
throw new Error("Runtime observation Hook has no matching durable in-flight
|
|
136
|
-
}
|
|
137
|
-
if (acceptedBinding === null
|
|
138
|
-
&& inFlight !== null && inFlight !== undefined && inFlight.agentId !== agentId) {
|
|
139
|
-
throw new Error("Runtime observation Hook has no matching durable in-flight Run.");
|
|
140
|
-
}
|
|
141
|
-
if ((preallocatedStartup || discoveredStartup)
|
|
142
|
-
&& inFlight !== null
|
|
143
|
-
&& inFlight !== undefined
|
|
144
|
-
&& (inFlight.runId !== startupRunId
|
|
145
|
-
|| startupRun === null
|
|
146
|
-
|| inFlight.receiptId !== agentRunDeliveryReceiptId(startupRun))) {
|
|
147
|
-
throw new Error("Runtime observation Hook has no matching durable in-flight Run.");
|
|
153
|
+
throw new Error("Runtime observation Hook has no matching durable in-flight Turn.");
|
|
148
154
|
}
|
|
149
|
-
const
|
|
150
|
-
??
|
|
151
|
-
??
|
|
152
|
-
??
|
|
155
|
+
const turnId = acceptedBinding?.fence.turnId
|
|
156
|
+
?? activeTurn?.id
|
|
157
|
+
?? startupTurnId
|
|
158
|
+
?? terminalTurnId;
|
|
153
159
|
let effectiveRuntime = runtime;
|
|
154
160
|
let effectiveLaunchId = acceptedBinding?.fence.launchId ?? launchId;
|
|
155
161
|
const sessionLaunchId = session?.launchId;
|
|
@@ -160,35 +166,35 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
160
166
|
&& sessionLaunchId !== undefined
|
|
161
167
|
&& typeof runtimeSource === "string"
|
|
162
168
|
&& !runtimeSource.trimStart().startsWith("{")
|
|
163
|
-
&& (runtime.
|
|
169
|
+
&& (runtime.turnId !== turnId
|
|
164
170
|
|| runtime.launchId !== sessionLaunchId
|
|
165
171
|
|| runtime.nativeSessionId !== session.nativeSessionId)) {
|
|
166
172
|
// A reused native pane keeps its original descriptor source. Advance only
|
|
167
173
|
// that Hook-owned source to the current durable generation before the
|
|
168
174
|
// volatile fence; the Controller no longer scans history to keep it fresh.
|
|
169
175
|
effectiveRuntime = refreshReusedTaskRuntimeDescriptorSource(runtimeSource, home, store, {
|
|
170
|
-
|
|
176
|
+
turnId,
|
|
171
177
|
launchId: sessionLaunchId,
|
|
172
178
|
nativeSessionId: session.nativeSessionId
|
|
173
179
|
});
|
|
174
180
|
effectiveLaunchId = effectiveRuntime.launchId;
|
|
175
181
|
}
|
|
176
182
|
if (acceptedBinding === null
|
|
177
|
-
&& effectiveRuntime?.
|
|
178
|
-
throw new Error("Runtime observation Hook
|
|
183
|
+
&& effectiveRuntime?.turnId !== undefined && effectiveRuntime.turnId !== turnId) {
|
|
184
|
+
throw new Error("Runtime observation Hook Turn does not match its current descriptor.");
|
|
179
185
|
}
|
|
180
|
-
const
|
|
181
|
-
?
|
|
182
|
-
: store.
|
|
183
|
-
if (
|
|
184
|
-
||
|
|
185
|
-
|| (acceptedBinding === null && !exactTerminal &&
|
|
186
|
-
||
|
|
187
|
-
||
|
|
188
|
-
throw new Error("Runtime observation Hook
|
|
186
|
+
const turn = acceptedBinding !== null || exactTerminal
|
|
187
|
+
? terminalTurn
|
|
188
|
+
: store.getActiveTurn(taskId, roleName);
|
|
189
|
+
if (turn === null
|
|
190
|
+
|| turn.id !== turnId
|
|
191
|
+
|| (acceptedBinding === null && !exactTerminal && turn.status !== "active")
|
|
192
|
+
|| turn.effective.agentId !== agentId
|
|
193
|
+
|| turn.effective.adapterId !== adapterId) {
|
|
194
|
+
throw new Error("Runtime observation Hook Turn does not match durable active state.");
|
|
189
195
|
}
|
|
190
|
-
if (
|
|
191
|
-
throw new Error("Runtime observation Hook workspace does not match the durable
|
|
196
|
+
if (turn.effective.workspace.root !== workspace) {
|
|
197
|
+
throw new Error("Runtime observation Hook workspace does not match the durable Turn snapshot.");
|
|
192
198
|
}
|
|
193
199
|
if (session !== undefined && acceptedBinding === null && !replacementStartup) {
|
|
194
200
|
if (session.adapterId !== adapterId
|
|
@@ -208,7 +214,7 @@ export function resolveRuntimeHookRunFence(environment, adapterId, payloadNative
|
|
|
208
214
|
roleName,
|
|
209
215
|
agentId,
|
|
210
216
|
launchId: effectiveLaunchId,
|
|
211
|
-
|
|
217
|
+
turnId,
|
|
212
218
|
...(acceptedBinding?.fence.receiptId === undefined
|
|
213
219
|
? activationReceiptId === undefined ? {} : { receiptId: activationReceiptId }
|
|
214
220
|
: { receiptId: acceptedBinding.fence.receiptId }),
|
|
@@ -227,7 +233,7 @@ function knownContinuationBinding(events, expected) {
|
|
|
227
233
|
&& observation.fence.nativeSessionId === expected.nativeSessionId
|
|
228
234
|
&& observation.fence.continuationId === expected.continuationId
|
|
229
235
|
&& observation.fence.continuationGeneration === expected.continuationGeneration
|
|
230
|
-
&& observation.fence.
|
|
236
|
+
&& observation.fence.turnId !== undefined)
|
|
231
237
|
.sort((left, right) => (left.receivedAt.localeCompare(right.receivedAt)
|
|
232
238
|
|| (left.sequence ?? -1) - (right.sequence ?? -1)
|
|
233
239
|
|| (left.ordinal ?? -1) - (right.ordinal ?? -1)
|
|
@@ -235,10 +241,10 @@ function knownContinuationBinding(events, expected) {
|
|
|
235
241
|
const binding = matches.at(-1) ?? null;
|
|
236
242
|
if (binding === null)
|
|
237
243
|
return null;
|
|
238
|
-
if (matches.some((candidate) => candidate.fence.
|
|
244
|
+
if (matches.some((candidate) => candidate.fence.turnId !== binding.fence.turnId
|
|
239
245
|
|| candidate.fence.launchId !== binding.fence.launchId
|
|
240
246
|
|| candidate.fence.receiptId !== binding.fence.receiptId)) {
|
|
241
|
-
throw new Error("Runtime observation Hook continuation has conflicting durable
|
|
247
|
+
throw new Error("Runtime observation Hook continuation has conflicting durable Turn bindings.");
|
|
242
248
|
}
|
|
243
249
|
return binding;
|
|
244
250
|
}
|
|
@@ -252,7 +258,7 @@ function acceptedTurnBinding(events, expected) {
|
|
|
252
258
|
&& observation.fence.agentId === expected.agentId
|
|
253
259
|
&& observation.fence.nativeSessionId === expected.nativeSessionId
|
|
254
260
|
&& observation.fence.nativeTurnId === expected.nativeTurnId
|
|
255
|
-
&& observation.fence.
|
|
261
|
+
&& observation.fence.turnId !== undefined)
|
|
256
262
|
.sort((left, right) => (left.receivedAt.localeCompare(right.receivedAt)
|
|
257
263
|
|| (left.sequence ?? -1) - (right.sequence ?? -1)
|
|
258
264
|
|| (left.ordinal ?? -1) - (right.ordinal ?? -1)
|
|
@@ -260,10 +266,10 @@ function acceptedTurnBinding(events, expected) {
|
|
|
260
266
|
const binding = matches.at(-1) ?? null;
|
|
261
267
|
if (binding === null)
|
|
262
268
|
return null;
|
|
263
|
-
if (matches.some((candidate) => candidate.fence.
|
|
269
|
+
if (matches.some((candidate) => candidate.fence.turnId !== binding.fence.turnId
|
|
264
270
|
|| candidate.fence.launchId !== binding.fence.launchId
|
|
265
271
|
|| candidate.fence.receiptId !== binding.fence.receiptId)) {
|
|
266
|
-
throw new Error("Runtime observation Hook native Turn has conflicting durable
|
|
272
|
+
throw new Error("Runtime observation Hook native Turn has conflicting durable Turn bindings.");
|
|
267
273
|
}
|
|
268
274
|
return binding;
|
|
269
275
|
}
|
|
@@ -188,7 +188,7 @@ export class RuntimeLaunchCoordinator {
|
|
|
188
188
|
...(runtimeIsolation === undefined
|
|
189
189
|
? {}
|
|
190
190
|
: { runtimeIsolation: runtimeIsolation.descriptor }),
|
|
191
|
-
...(request.
|
|
191
|
+
...(request.turnId === undefined ? {} : { turnId: request.turnId }),
|
|
192
192
|
...(request.environment === undefined
|
|
193
193
|
? {}
|
|
194
194
|
: { environment: request.environment })
|
|
@@ -204,7 +204,7 @@ export class RuntimeLaunchCoordinator {
|
|
|
204
204
|
...(runtimeIsolation === undefined
|
|
205
205
|
? {}
|
|
206
206
|
: { runtimeIsolation: runtimeIsolation.descriptor }),
|
|
207
|
-
...(request.
|
|
207
|
+
...(request.turnId === undefined ? {} : { turnId: request.turnId }),
|
|
208
208
|
...(request.environment === undefined
|
|
209
209
|
? {}
|
|
210
210
|
: { environment: request.environment }),
|
|
@@ -409,7 +409,7 @@ function validateRuntimeLaunchPreflight(preflight, request, launchId) {
|
|
|
409
409
|
&& preflight.owner.taskId === request.owner.taskId));
|
|
410
410
|
if (preflight.launchId !== launchId
|
|
411
411
|
|| !ownerMatches
|
|
412
|
-
|| preflight.
|
|
412
|
+
|| preflight.turnId !== request.turnId
|
|
413
413
|
|| preflight.agentId !== request.agentId
|
|
414
414
|
|| preflight.adapterId !== request.adapterId
|
|
415
415
|
|| !effectiveLaunchSnapshotsCompatible(preflight.effective, request.effective)
|
|
@@ -3,13 +3,13 @@ import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
|
|
|
3
3
|
import { normalizeAgentDriverHookClassification } from "../runtime/agentDriver.js";
|
|
4
4
|
import { mapAgentDriverHooks } from "../runtime/agentDriverObservation.js";
|
|
5
5
|
import { runtimeLifecycleSignalKey } from "../runtime/lifecycleReservation.js";
|
|
6
|
-
import {
|
|
6
|
+
import { formatTurnReceiptId } from "../task/taskRecordReference.js";
|
|
7
7
|
import { FileRuntimeEventInbox, MAX_RUNTIME_EVENT_FILE_BYTES } from "./runtimeEventInbox.js";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveRuntimeHookTurnFence } from "./runtimeHookTurnFence.js";
|
|
9
9
|
/**
|
|
10
10
|
* Single hidden ingress for every structured CLI Driver Hook. Native event
|
|
11
11
|
* names and payload shapes terminate here; the durable inbox contains only a
|
|
12
|
-
* provider-independent RuntimeObservation with an exact generation/
|
|
12
|
+
* provider-independent RuntimeObservation with an exact generation/Turn fence.
|
|
13
13
|
*/
|
|
14
14
|
export async function runRuntimeObservationHookCommand(stdinJson, environment = process.env, call = callController, now = new Date(), dependencies = {}) {
|
|
15
15
|
if (environment.YUI_SESSION_SCOPE === "global") {
|
|
@@ -55,7 +55,7 @@ async function runGlobalRuntimeTurnHook(stdinJson, environment, call, now, depen
|
|
|
55
55
|
adapterId: "claude",
|
|
56
56
|
launchId: requireIdentity(environment.YUI_LAUNCH_ID, "Launch id"),
|
|
57
57
|
nativeSessionId,
|
|
58
|
-
|
|
58
|
+
nativeTurnId: optionalIdentity(driver.runtime.nativeTurnId(nativeHook)) ?? occurrenceId,
|
|
59
59
|
...(environment.YUI_SESSION_TITLE === undefined
|
|
60
60
|
? {}
|
|
61
61
|
: { title: requireIdentity(environment.YUI_SESSION_TITLE, "Session title") }),
|
|
@@ -84,7 +84,7 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
|
|
|
84
84
|
const nativeSessionId = requireIdentity(driver.runtime.nativeSessionId(nativeHook), "Agent Driver native Session id");
|
|
85
85
|
const nativeTurnId = optionalIdentity(driver.runtime.nativeTurnId(nativeHook));
|
|
86
86
|
const classification = normalizeAgentDriverHookClassification(driver.runtime.classifyHook(nativeHook));
|
|
87
|
-
const fence = (dependencies.
|
|
87
|
+
const fence = (dependencies.resolveTurnFence ?? resolveRuntimeHookTurnFence)(environment, driver.adapterId, nativeSessionId, {
|
|
88
88
|
...(classification.startupSession === undefined
|
|
89
89
|
? {}
|
|
90
90
|
: { startupSession: classification.startupSession }),
|
|
@@ -95,6 +95,9 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
|
|
|
95
95
|
}),
|
|
96
96
|
...(nativeTurnId === undefined ? {} : { nativeTurnId })
|
|
97
97
|
});
|
|
98
|
+
if (fence.turnId === undefined) {
|
|
99
|
+
throw new Error("Agent Driver Hook requires a managed Turn.");
|
|
100
|
+
}
|
|
98
101
|
const driverInput = {
|
|
99
102
|
driver,
|
|
100
103
|
hookEventName,
|
|
@@ -107,7 +110,7 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
|
|
|
107
110
|
fence: {
|
|
108
111
|
taskId: fence.taskId,
|
|
109
112
|
roleName: fence.roleName,
|
|
110
|
-
|
|
113
|
+
turnId: fence.turnId,
|
|
111
114
|
agentId: fence.agentId,
|
|
112
115
|
driverId,
|
|
113
116
|
launchId: fence.launchId,
|
|
@@ -115,8 +118,8 @@ export function parseRuntimeObservationHook(stdinJson, environment, now = new Da
|
|
|
115
118
|
conversationId: fence.nativeSessionId,
|
|
116
119
|
activationId: fence.launchId,
|
|
117
120
|
nativeSessionId: fence.nativeSessionId,
|
|
118
|
-
nativeTurnId: nativeTurnId ?? fence.
|
|
119
|
-
receiptId: fence.receiptId ??
|
|
121
|
+
nativeTurnId: nativeTurnId ?? fence.turnId,
|
|
122
|
+
receiptId: fence.receiptId ?? formatTurnReceiptId(fence.taskId, fence.turnId)
|
|
120
123
|
},
|
|
121
124
|
payload
|
|
122
125
|
};
|