@zq-silk/yui 0.13.10 → 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 -926
- 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
|
@@ -25,6 +25,8 @@ const KINDS = [
|
|
|
25
25
|
"activation.started",
|
|
26
26
|
"activation.ended",
|
|
27
27
|
"activation.failed",
|
|
28
|
+
"goal.updated",
|
|
29
|
+
"goal.cleared",
|
|
28
30
|
"turn.accepted",
|
|
29
31
|
"turn.waiting",
|
|
30
32
|
"turn.completed",
|
|
@@ -50,7 +52,9 @@ const AUTHORITIES = [
|
|
|
50
52
|
"host",
|
|
51
53
|
"diagnostic"
|
|
52
54
|
];
|
|
53
|
-
|
|
55
|
+
/** Provider Turn facts always carry native Turn identity. `turnId` is only an
|
|
56
|
+
* optional correlation when that Turn was started for a Yui Turn. */
|
|
57
|
+
const TURN_SCOPED = new Set([
|
|
54
58
|
"turn.accepted",
|
|
55
59
|
"turn.waiting",
|
|
56
60
|
"turn.completed",
|
|
@@ -97,13 +101,10 @@ export function createRuntimeObservation(input) {
|
|
|
97
101
|
throw new Error(`${input.kind} requires provider-structured or controller authority.`);
|
|
98
102
|
}
|
|
99
103
|
const fence = normalizeFence(input.fence);
|
|
100
|
-
if (
|
|
101
|
-
throw new Error(`${input.kind} requires runId.`);
|
|
102
|
-
}
|
|
103
|
-
if (RUN_SCOPED.has(input.kind) && fence.nativeSessionId === undefined) {
|
|
104
|
+
if (TURN_SCOPED.has(input.kind) && fence.nativeSessionId === undefined) {
|
|
104
105
|
throw new Error(`${input.kind} requires nativeSessionId.`);
|
|
105
106
|
}
|
|
106
|
-
if (
|
|
107
|
+
if (TURN_SCOPED.has(input.kind) && fence.nativeTurnId === undefined) {
|
|
107
108
|
throw new Error(`${input.kind} requires nativeTurnId.`);
|
|
108
109
|
}
|
|
109
110
|
if ((input.kind.startsWith("activation.") || CONTINUATION_SCOPED.has(input.kind)
|
|
@@ -151,7 +152,7 @@ export function runtimeObservationFenceMatches(expected, actual) {
|
|
|
151
152
|
for (const field of [
|
|
152
153
|
"taskId",
|
|
153
154
|
"roleName",
|
|
154
|
-
"
|
|
155
|
+
"turnId",
|
|
155
156
|
"agentId",
|
|
156
157
|
"driverId",
|
|
157
158
|
"launchId",
|
|
@@ -171,17 +172,17 @@ export function runtimeObservationFenceMatches(expected, actual) {
|
|
|
171
172
|
return true;
|
|
172
173
|
}
|
|
173
174
|
/**
|
|
174
|
-
* Matches observations that belong to one durable
|
|
175
|
+
* Matches observations that belong to one durable Turn/Session generation.
|
|
175
176
|
* A provider may advance its native Turn while background subagents from an
|
|
176
177
|
* earlier Turn are still active and later mailbox activations use their own
|
|
177
178
|
* exactly-once receipt, so nativeTurnId and receiptId are intentionally
|
|
178
179
|
* excluded. Exact acceptance still validates both fields before persistence.
|
|
179
180
|
*/
|
|
180
|
-
export function
|
|
181
|
+
export function runtimeObservationTurnFenceMatches(expected, actual) {
|
|
181
182
|
for (const field of [
|
|
182
183
|
"taskId",
|
|
183
184
|
"roleName",
|
|
184
|
-
"
|
|
185
|
+
"turnId",
|
|
185
186
|
"agentId",
|
|
186
187
|
"driverId",
|
|
187
188
|
"launchId",
|
|
@@ -204,7 +205,7 @@ export function runtimeObservationTaskEventPayload(input) {
|
|
|
204
205
|
driverId: observation.fence.driverId,
|
|
205
206
|
launchId: observation.fence.launchId,
|
|
206
207
|
...(observation.fence.taskId === undefined ? {} : { taskId: observation.fence.taskId }),
|
|
207
|
-
...(observation.fence.
|
|
208
|
+
...(observation.fence.turnId === undefined ? {} : { turnId: observation.fence.turnId }),
|
|
208
209
|
...(observation.fence.nativeSessionId === undefined
|
|
209
210
|
? {}
|
|
210
211
|
: { nativeSessionId: observation.fence.nativeSessionId }),
|
|
@@ -227,15 +228,15 @@ export function runtimeObservationFromTaskEvent(event) {
|
|
|
227
228
|
/**
|
|
228
229
|
* Runtime observation events are compacted by operation identity: a terminal
|
|
229
230
|
* operation replaces its matching start. Any retained exact start therefore
|
|
230
|
-
* represents Provider-owned work that is still active for this
|
|
231
|
+
* represents Provider-owned work that is still active for this Turn.
|
|
231
232
|
*/
|
|
232
|
-
export function
|
|
233
|
+
export function turnHasActiveRuntimeOperations(events, owner) {
|
|
233
234
|
return events.some((event) => {
|
|
234
235
|
const observation = runtimeObservationFromTaskEvent(event);
|
|
235
236
|
return observation?.kind === "operation.started"
|
|
236
237
|
&& observation.fence.taskId === owner.taskId
|
|
237
238
|
&& observation.fence.roleName === owner.roleName
|
|
238
|
-
&& observation.fence.
|
|
239
|
+
&& observation.fence.turnId === owner.turnId
|
|
239
240
|
&& observation.fence.agentId === owner.agentId;
|
|
240
241
|
});
|
|
241
242
|
}
|
|
@@ -243,7 +244,7 @@ function normalizeFence(input) {
|
|
|
243
244
|
return Object.freeze({
|
|
244
245
|
...(input.taskId === undefined ? {} : { taskId: requireIdentity(input.taskId, "Task id") }),
|
|
245
246
|
roleName: requireIdentity(input.roleName, "Role name"),
|
|
246
|
-
...(input.
|
|
247
|
+
...(input.turnId === undefined ? {} : { turnId: requireIdentity(input.turnId, "Turn id") }),
|
|
247
248
|
agentId: requireIdentity(input.agentId, "Agent id"),
|
|
248
249
|
driverId: requireDriverId(input.driverId),
|
|
249
250
|
launchId: requireIdentity(input.launchId, "Launch id"),
|
|
@@ -326,6 +327,21 @@ function normalizePayload(kind, input) {
|
|
|
326
327
|
&& !["unknown", "recoverable", "unrecoverable"].includes(input.recoverability ?? "")) {
|
|
327
328
|
throw new Error("conversation.observed requires recoverability.");
|
|
328
329
|
}
|
|
330
|
+
if (kind === "goal.updated") {
|
|
331
|
+
if (!["active", "paused", "blocked", "usage-limited", "budget-limited", "complete"]
|
|
332
|
+
.includes(input.goalStatus ?? "")) {
|
|
333
|
+
throw new Error("goal.updated requires a supported status.");
|
|
334
|
+
}
|
|
335
|
+
if (input.goalObjective === undefined || input.goalUpdatedAt === undefined) {
|
|
336
|
+
throw new Error("goal.updated requires objective and updatedAt.");
|
|
337
|
+
}
|
|
338
|
+
requireText(input.goalObjective, "Provider Goal objective");
|
|
339
|
+
requireTimestamp(input.goalUpdatedAt, "Provider Goal updatedAt");
|
|
340
|
+
if (input.goalTokenBudget !== undefined
|
|
341
|
+
&& (!Number.isSafeInteger(input.goalTokenBudget) || input.goalTokenBudget < 1)) {
|
|
342
|
+
throw new Error("Provider Goal token budget is invalid.");
|
|
343
|
+
}
|
|
344
|
+
}
|
|
329
345
|
if (kind === "native-work.snapshot") {
|
|
330
346
|
if (typeof input.snapshotComplete !== "boolean"
|
|
331
347
|
|| !["exact", "partial", "unavailable"].includes(input.observationQuality ?? "")) {
|
|
@@ -387,6 +403,7 @@ function normalizePayload(kind, input) {
|
|
|
387
403
|
? {}
|
|
388
404
|
: { observerDetail: requireText(input.observerDetail, "Runtime observer detail") }),
|
|
389
405
|
...(failure === undefined ? {} : { failure }),
|
|
406
|
+
...(input.input === undefined ? {} : { input: requireText(input.input, "Provider-visible input") }),
|
|
390
407
|
...(input.summary === undefined ? {} : { summary: requireText(input.summary, "Runtime summary") }),
|
|
391
408
|
...(input.execution === undefined ? {} : { execution: input.execution }),
|
|
392
409
|
...(input.outcome === undefined ? {} : { outcome: input.outcome }),
|
|
@@ -413,7 +430,18 @@ function normalizePayload(kind, input) {
|
|
|
413
430
|
: { snapshotComplete: input.snapshotComplete }),
|
|
414
431
|
...(input.recoverability === undefined
|
|
415
432
|
? {}
|
|
416
|
-
: { recoverability: input.recoverability })
|
|
433
|
+
: { recoverability: input.recoverability }),
|
|
434
|
+
...(input.goalStatus === undefined ? {} : { goalStatus: input.goalStatus }),
|
|
435
|
+
...(input.goalObjective === undefined
|
|
436
|
+
? {}
|
|
437
|
+
: { goalObjective: requireText(input.goalObjective, "Provider Goal objective") }),
|
|
438
|
+
...(input.goalUpdatedAt === undefined
|
|
439
|
+
? {}
|
|
440
|
+
: { goalUpdatedAt: requireTimestamp(input.goalUpdatedAt, "Provider Goal updatedAt") }),
|
|
441
|
+
...(input.goalNativeTurnId === undefined
|
|
442
|
+
? {}
|
|
443
|
+
: { goalNativeTurnId: requireIdentity(input.goalNativeTurnId, "Provider Goal native Turn id") }),
|
|
444
|
+
...(input.goalTokenBudget === undefined ? {} : { goalTokenBudget: input.goalTokenBudget })
|
|
417
445
|
});
|
|
418
446
|
}
|
|
419
447
|
export function runtimeObservationSemanticKey(input) {
|
|
@@ -430,7 +458,7 @@ export function runtimeObservationSemanticKey(input) {
|
|
|
430
458
|
// fresh transport sequence after reconnect, so terminal identity must win
|
|
431
459
|
// over occurrence ordering or one SessionEnd storm becomes many facts.
|
|
432
460
|
if (["session.ended", "session.failed", "activation.ended", "activation.failed",
|
|
433
|
-
"turn.completed", "turn.failed", "turn.cancelled", "continuation.settled"].includes(input.kind)) {
|
|
461
|
+
"goal.cleared", "turn.completed", "turn.failed", "turn.cancelled", "continuation.settled"].includes(input.kind)) {
|
|
434
462
|
return [
|
|
435
463
|
"terminal",
|
|
436
464
|
...continuationIdentity,
|
|
@@ -438,11 +466,20 @@ export function runtimeObservationSemanticKey(input) {
|
|
|
438
466
|
input.kind,
|
|
439
467
|
input.payload?.outcome ?? input.payload?.failure?.error.code ?? "terminal",
|
|
440
468
|
input.kind === "continuation.settled" ? input.payload?.resultRef ?? "none" : "none",
|
|
441
|
-
input.kind === "turn.failed" && input.payload?.failure?.
|
|
442
|
-
? "
|
|
469
|
+
input.kind === "turn.failed" && input.payload?.failure?.turnTerminal === true
|
|
470
|
+
? "turn-terminal-failure"
|
|
443
471
|
: "turn-terminal"
|
|
444
472
|
].join(":");
|
|
445
473
|
}
|
|
474
|
+
if (input.kind === "goal.updated") {
|
|
475
|
+
return [
|
|
476
|
+
"goal-state",
|
|
477
|
+
fence.driverId,
|
|
478
|
+
fence.conversationId ?? fence.nativeSessionId ?? fence.launchId,
|
|
479
|
+
input.payload?.goalStatus ?? "unknown",
|
|
480
|
+
input.payload?.goalUpdatedAt ?? "unknown"
|
|
481
|
+
].join(":");
|
|
482
|
+
}
|
|
446
483
|
if (input.kind === "continuation.reported") {
|
|
447
484
|
const summary = input.payload?.summary?.trim();
|
|
448
485
|
const resultIdentity = summary === undefined || summary.length === 0
|
|
@@ -503,9 +540,9 @@ function normalizeFailure(input) {
|
|
|
503
540
|
...(input.lastOutput === undefined
|
|
504
541
|
? {}
|
|
505
542
|
: { lastOutput: requireText(input.lastOutput, "Runtime failure last output") }),
|
|
506
|
-
...(input.
|
|
543
|
+
...(input.turnTerminal === undefined
|
|
507
544
|
? {}
|
|
508
|
-
: {
|
|
545
|
+
: { turnTerminal: requireBoolean(input.turnTerminal, "Runtime failure turnTerminal") })
|
|
509
546
|
});
|
|
510
547
|
}
|
|
511
548
|
function requireBoolean(value, label) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRuntimeObservation, runtimeObservationFromTaskEvent,
|
|
1
|
+
import { createRuntimeObservation, runtimeObservationFromTaskEvent, runtimeObservationTurnFenceMatches } from "./runtimeObservation.js";
|
|
2
2
|
import { DEFAULT_RUNTIME_HEALTH_POLICY } from "./runtimeHealthPolicy.js";
|
|
3
3
|
export function createRuntimeProjection(fence, createdAt) {
|
|
4
4
|
const timestamp = requireTimestamp(createdAt);
|
|
@@ -9,8 +9,8 @@ export function createRuntimeProjection(fence, createdAt) {
|
|
|
9
9
|
turn: "none",
|
|
10
10
|
conversation: "unknown",
|
|
11
11
|
activation: "none",
|
|
12
|
+
goal: "none",
|
|
12
13
|
continuations: Object.freeze({}),
|
|
13
|
-
inputDelivery: "none",
|
|
14
14
|
runActivity: "starting",
|
|
15
15
|
health: "reconciling",
|
|
16
16
|
waitingOn: Object.freeze([]),
|
|
@@ -29,7 +29,7 @@ export function createRuntimeProjection(fence, createdAt) {
|
|
|
29
29
|
export function projectRuntimeTaskEvents(fence, createdAt, events) {
|
|
30
30
|
const observations = events
|
|
31
31
|
.map(runtimeObservationFromTaskEvent)
|
|
32
|
-
.filter((event) => (event !== null &&
|
|
32
|
+
.filter((event) => (event !== null && runtimeObservationTurnFenceMatches(fence, event.fence)))
|
|
33
33
|
.sort((left, right) => (left.receivedAt.localeCompare(right.receivedAt)
|
|
34
34
|
|| (left.sequence ?? -1) - (right.sequence ?? -1)
|
|
35
35
|
|| (left.ordinal ?? -1) - (right.ordinal ?? -1)
|
|
@@ -38,7 +38,7 @@ export function projectRuntimeTaskEvents(fence, createdAt, events) {
|
|
|
38
38
|
}
|
|
39
39
|
export function projectRuntimeObservation(current, raw) {
|
|
40
40
|
const event = createRuntimeObservation(raw);
|
|
41
|
-
if (!
|
|
41
|
+
if (!runtimeObservationTurnFenceMatches(current.fence, event.fence)) {
|
|
42
42
|
throw new Error("Runtime observation fence does not match the projection.");
|
|
43
43
|
}
|
|
44
44
|
const at = event.receivedAt;
|
|
@@ -63,9 +63,9 @@ export function projectRuntimeObservation(current, raw) {
|
|
|
63
63
|
activation: "ended",
|
|
64
64
|
turn: terminalTurn(current.turn),
|
|
65
65
|
// A parent provider Session ending is independent from native child
|
|
66
|
-
// operations already observed under the
|
|
66
|
+
// operations already observed under the Turn. Keep those children
|
|
67
67
|
// visible until their own terminal facts arrive; host/session loss is
|
|
68
|
-
// health evidence, not proof that child work or the Yui
|
|
68
|
+
// health evidence, not proof that child work or the Yui Turn ended.
|
|
69
69
|
operations: activeSubagentOperations(current.operations),
|
|
70
70
|
stateSince: at
|
|
71
71
|
});
|
|
@@ -102,7 +102,7 @@ export function projectRuntimeObservation(current, raw) {
|
|
|
102
102
|
waitId: undefined,
|
|
103
103
|
// Tool operations belong to the completed native Turn. Provider-owned
|
|
104
104
|
// background subagents may legitimately outlive it and wake later
|
|
105
|
-
// native
|
|
105
|
+
// native Provider activity inside the same durable Yui Turn.
|
|
106
106
|
operations: activeSubagentOperations(current.operations),
|
|
107
107
|
stateSince: at
|
|
108
108
|
}), "provider", at);
|
|
@@ -198,6 +198,10 @@ export function projectRuntimeObservation(current, raw) {
|
|
|
198
198
|
return next(current, { activation: "ended", stateSince: at });
|
|
199
199
|
case "activation.failed":
|
|
200
200
|
return next(current, { activation: "failed", stateSince: at });
|
|
201
|
+
case "goal.updated":
|
|
202
|
+
return next(current, { goal: event.payload.goalStatus, stateSince: at });
|
|
203
|
+
case "goal.cleared":
|
|
204
|
+
return next(current, { goal: "none", stateSince: at });
|
|
201
205
|
case "continuation.started":
|
|
202
206
|
case "continuation.reported":
|
|
203
207
|
case "continuation.settled": {
|
|
@@ -259,7 +263,7 @@ export function projectRuntimeObservation(current, raw) {
|
|
|
259
263
|
});
|
|
260
264
|
}
|
|
261
265
|
case "input.delivery-unknown":
|
|
262
|
-
return next(current, {
|
|
266
|
+
return next(current, { turn: "delivery-unknown", stateSince: at });
|
|
263
267
|
case "native-work.snapshot":
|
|
264
268
|
return next(current, {});
|
|
265
269
|
default:
|
|
@@ -284,16 +288,6 @@ export function completeRuntimeWorkflow(current, completedAt) {
|
|
|
284
288
|
})
|
|
285
289
|
});
|
|
286
290
|
}
|
|
287
|
-
export function projectRuntimeMailbox(current, mailbox) {
|
|
288
|
-
if (mailbox?.inputDelivery === undefined || mailbox.inputDelivery === null) {
|
|
289
|
-
return next(current, { inputDelivery: "none" });
|
|
290
|
-
}
|
|
291
|
-
return next(current, {
|
|
292
|
-
inputDelivery: mailbox.inputDelivery.status === "delivery-unknown"
|
|
293
|
-
? "delivery-unknown"
|
|
294
|
-
: "dispatching"
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
291
|
export function runtimeDisplayStatus(current) {
|
|
298
292
|
if (current.session === "failed")
|
|
299
293
|
return "broken";
|
|
@@ -324,7 +318,7 @@ export function runtimeDisplayStatus(current) {
|
|
|
324
318
|
/**
|
|
325
319
|
* Classify one RuntimeProjection into the layered health state shared by CLI,
|
|
326
320
|
* Web, and scheduler. The semantic progress timestamp is the same durable
|
|
327
|
-
* fence the scheduler stall pass consumes (
|
|
321
|
+
* fence the scheduler stall pass consumes (Turn creation plus Work/Review/
|
|
328
322
|
* Integration checkpoints), so token/tool/CPU activity can never masquerade
|
|
329
323
|
* as business progress.
|
|
330
324
|
*
|
|
@@ -410,7 +404,7 @@ function runtimeHealthReason(layer, current) {
|
|
|
410
404
|
case "broken":
|
|
411
405
|
return "the Agent Driver runtime is broken";
|
|
412
406
|
case "stopped":
|
|
413
|
-
return "the Provider Activation ended while the Yui
|
|
407
|
+
return "the Provider Activation ended while the Yui Turn remains active";
|
|
414
408
|
case "subagent-active":
|
|
415
409
|
case "tool-active":
|
|
416
410
|
case "model-active":
|
|
@@ -429,9 +423,9 @@ function runtimeHealthReason(layer, current) {
|
|
|
429
423
|
case "waiting-external":
|
|
430
424
|
return `the Agent Driver is ${layer.replaceAll("-", " ")}`;
|
|
431
425
|
case "ready":
|
|
432
|
-
return "the
|
|
426
|
+
return "the Provider turn ended while the Yui Turn is still active";
|
|
433
427
|
case "awaiting-provider-acceptance":
|
|
434
|
-
return "the
|
|
428
|
+
return "the submitted active Turn is awaiting Provider acceptance";
|
|
435
429
|
case "runtime-unobservable":
|
|
436
430
|
return "the host is present but the Agent Driver exposes no current runtime state";
|
|
437
431
|
case "starting":
|
|
@@ -460,7 +454,7 @@ function next(current, patch) {
|
|
|
460
454
|
...activeNativeOperations.map(([id]) => `native-operation:${id}`)
|
|
461
455
|
];
|
|
462
456
|
const attention = [
|
|
463
|
-
...(copy.
|
|
457
|
+
...(copy.turn === "delivery-unknown" ? ["delivery-unknown"] : []),
|
|
464
458
|
...continuations.flatMap(([id, continuation]) => (continuation.identityConflict ? [`identity-conflict:${id}`]
|
|
465
459
|
: continuation.observation === "unavailable" ? [`continuation-unresolved:${id}`]
|
|
466
460
|
: [])),
|
|
@@ -475,12 +469,10 @@ function next(current, patch) {
|
|
|
475
469
|
|| copy.session === "ended"
|
|
476
470
|
|| copy.session === "failed"
|
|
477
471
|
? "unobservable"
|
|
478
|
-
: copy.
|
|
479
|
-
|| (copy.activation !== "active" && waitingNative.length > 0)
|
|
472
|
+
: (copy.activation !== "active" && waitingNative.length > 0)
|
|
480
473
|
? "reconciling"
|
|
481
474
|
: "healthy";
|
|
482
|
-
const runActivity = copy.
|
|
483
|
-
|| copy.turn === "accepted"
|
|
475
|
+
const runActivity = copy.turn === "accepted"
|
|
484
476
|
|| copy.session === "active"
|
|
485
477
|
? "running"
|
|
486
478
|
: waitingNative.length > 0 || activeNativeOperations.length > 0 ? "waiting"
|
|
@@ -29,9 +29,9 @@ export function createSessionLaunchRequest(input) {
|
|
|
29
29
|
effective,
|
|
30
30
|
workspace,
|
|
31
31
|
...(runtimeIsolation === undefined ? {} : { runtimeIsolation }),
|
|
32
|
-
...(input.
|
|
32
|
+
...(input.turnId === undefined
|
|
33
33
|
? {}
|
|
34
|
-
: {
|
|
34
|
+
: { turnId: requireSafeIdentity(input.turnId, "Turn id") }),
|
|
35
35
|
...(input.environment === undefined
|
|
36
36
|
? {}
|
|
37
37
|
: { environment: copyEnvironment(input.environment) })
|