@zq-silk/yui 0.15.7 → 0.15.8
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 +192 -399
- package/README.md +127 -1149
- package/dist/agent/adapterCatalog.js +15 -2
- package/dist/agent/agent.js +23 -3
- package/dist/agent/argumentPolicy.js +7 -1
- package/dist/agent/connectionPlan.js +62 -0
- package/dist/agent/executionComponents.js +158 -0
- package/dist/agent/launchEnvironment.js +31 -3
- package/dist/agent/managedRuntimeEnvironment.js +3 -5
- package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
- package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
- package/dist/brief/taskBrief.js +12 -0
- package/dist/cli/agentConfigurationPicker.js +13 -0
- package/dist/cli/commandCatalog.js +157 -70
- package/dist/cli/interactionCandidates.js +5 -5
- package/dist/cli/interactionPolicy.js +38 -8
- package/dist/cli/invocationRouter.js +1 -1
- package/dist/cli/managedDiagnostics.js +28 -0
- package/dist/cli/operatorWizard.js +1 -7
- package/dist/cli/roleOptionOrder.js +27 -0
- package/dist/cli/roleWizard.js +50 -14
- package/dist/cli/updateOrchestrator.js +1 -1
- package/dist/cli/updatePorts.js +3 -4
- package/dist/cli.js +178 -95
- package/dist/commands/agentCommands.js +72 -14
- package/dist/commands/capabilityCommands.js +9 -6
- package/dist/commands/configCommands.js +20 -20
- package/dist/commands/deliveryGuardPreflight.js +2 -2
- package/dist/commands/executionAuditCommands.js +24 -24
- package/dist/commands/globalRoleCommands.js +1 -1
- package/dist/commands/grantCommands.js +4 -4
- package/dist/commands/operatorCommands.js +1 -7
- package/dist/commands/projectCommands.js +4 -4
- package/dist/commands/resourcesCommands.js +2 -2
- package/dist/commands/roleConfiguration.js +25 -5
- package/dist/commands/roleRuntimeGuard.js +4 -5
- package/dist/commands/sessionCommands.js +3 -7
- package/dist/commands/taskActivationCommands.js +259 -0
- package/dist/commands/taskActor.js +28 -49
- package/dist/commands/taskCommands.js +1188 -710
- package/dist/commands/taskContextCommand.js +39 -583
- package/dist/commands/taskExecutionCommands.js +32 -32
- package/dist/commands/taskInputCommands.js +40 -104
- package/dist/commands/taskIntegrationCommands.js +3 -2
- package/dist/commands/taskIntegrationQueueCommands.js +1 -1
- package/dist/commands/taskNextActionCommand.js +8 -8
- package/dist/commands/taskOverviewCommand.js +33 -45
- package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
- package/dist/commands/taskRoleRuntimeStatus.js +133 -102
- package/dist/commands/telemetryCommands.js +36 -38
- package/dist/config/configCatalog.js +4 -4
- package/dist/config/yuiConfig.js +8 -8
- package/dist/context/contextSnapshot.js +10 -10
- package/dist/context/dispatchContext.js +11 -11
- package/dist/context/roleSessionContext.js +6 -3
- package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
- package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
- package/dist/context/sessionBootstrapManifest.js +21 -2
- package/dist/context/sourceRunContext.js +30 -0
- package/dist/context/taskContext.js +458 -0
- package/dist/context/wakeNotification.js +27 -27
- package/dist/controller/agentRuntimeObserver.js +21 -24
- package/dist/controller/capabilityBridge.js +17 -6
- package/dist/controller/clientRuntime.js +65 -92
- package/dist/controller/controller.js +114 -188
- package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
- package/dist/controller/jobControl.js +54 -85
- package/dist/controller/resourceInventory.js +8 -27
- package/dist/controller/resourceInventoryLinux.js +12 -13
- package/dist/controller/runtime.js +529 -479
- package/dist/controller/runtimeEventInbox.js +55 -25
- package/dist/controller/runtimeEventProcessor.js +22 -31
- package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
- package/dist/controller/runtimeLaunchCoordinator.js +80 -426
- package/dist/controller/runtimeObservationHook.js +14 -18
- package/dist/controller/sessionNotify.js +16 -24
- package/dist/controller/sessionOwnerReconciliation.js +168 -50
- package/dist/controller/structuredProviderObservation.js +138 -99
- package/dist/coordination/workMailbox.js +3 -3
- package/dist/coordination/workMailboxQueue.js +36 -33
- package/dist/core/boundedRpc.js +8 -1
- package/dist/core/controllerClient.js +20 -1
- package/dist/core/controllerServer.js +4 -4
- package/dist/doctor/doctor.js +13 -2
- package/dist/domain/agentResultTransport.js +9 -9
- package/dist/execution/codexThreadNaming.js +2 -8
- package/dist/execution/executionHealth.js +51 -63
- package/dist/execution/reviewMainRun.js +137 -0
- package/dist/execution/workItemExecution.js +28 -29
- package/dist/execution/workItemExecutionProjection.js +99 -107
- package/dist/execution/workItemMainRun.js +141 -0
- package/dist/executor/agentAdapter.js +227 -20
- package/dist/executor/agentConfigurationCatalog.js +126 -4
- package/dist/executor/agentConfigurationProbe.js +162 -4
- package/dist/executor/agentExecutor.js +79 -78
- package/dist/executor/effectiveLaunch.js +105 -18
- package/dist/executor/executorRegistry.js +29 -44
- package/dist/executor/fileRoleLaunchPlanner.js +229 -154
- package/dist/executor/workspacePreflightClassification.js +16 -16
- package/dist/grant/capabilityGrant.js +6 -3
- package/dist/input/inputRequest.js +12 -10
- package/dist/integration/gitIntegrationService.js +4 -11
- package/dist/integration/integrationQueueService.js +4 -4
- package/dist/interaction/operatorPresentation.js +1 -1
- package/dist/kernel/builtinCapabilities.js +247 -12
- package/dist/kernel/capabilityRegistry.js +64 -18
- package/dist/kernel/instanceHost.js +12 -1
- package/dist/kernel/kernelPorts.js +2 -2
- package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
- package/dist/lifecycle/exactRunTerminalization.js +449 -0
- package/dist/message/message.js +62 -6
- package/dist/message/messageContinuation.js +204 -0
- package/dist/observability/executionAudit.js +70 -72
- package/dist/observability/faultClassification.js +2 -2
- package/dist/observability/orchestrationMetrics.js +8 -8
- package/dist/operator/operatorSessionHistory.js +1 -7
- package/dist/output/agentConfigurationPresentation.js +8 -3
- package/dist/output/agentRunConfigurationPresentation.js +128 -0
- package/dist/output/rolePresentation.js +54 -3
- package/dist/plugins/pluginChild.js +104 -0
- package/dist/plugins/pluginIntent.js +26 -0
- package/dist/plugins/pluginInterpreter.js +43 -0
- package/dist/plugins/pluginPackage.js +101 -0
- package/dist/plugins/pluginProcess.js +112 -0
- package/dist/plugins/pluginService.js +380 -0
- package/dist/profile/agentProfile.js +1 -1
- package/dist/repository/gitWorkspace.js +26 -4
- package/dist/repository/project.js +19 -4
- package/dist/repository/taskBaseFreshness.js +13 -13
- package/dist/repository/taskWorkspaceCoordinator.js +20 -27
- package/dist/repository/taskWorkspacePreparer.js +344 -83
- package/dist/resources/autoResourceGc.js +3 -3
- package/dist/resources/liveReferences.js +3 -3
- package/dist/resources/projectResource.js +123 -0
- package/dist/resources/projectResourceService.js +421 -0
- package/dist/resources/resourceDiscovery.js +6 -6
- package/dist/resources/resourceGc.js +1 -1
- package/dist/resources/resourceRegistrar.js +1 -1
- package/dist/resources/resourceTypes.js +1 -1
- package/dist/review/deltaRecheck.js +3 -3
- package/dist/review/reviewAcceptance.js +16 -16
- package/dist/review/reviewDecision.js +7 -7
- package/dist/review/reviewRound.js +21 -20
- package/dist/review/reviewerAvailability.js +2 -2
- package/dist/role/role.js +51 -7
- package/dist/role/taskRoleUpdate.js +30 -0
- package/dist/runtime/acpProtocol.js +425 -0
- package/dist/runtime/acpSession.js +731 -0
- package/dist/runtime/acpSessionConfiguration.js +260 -0
- package/dist/runtime/agentDriver.js +30 -11
- package/dist/runtime/agentEndpoint.js +278 -0
- package/dist/runtime/agentEndpointIdentity.js +86 -0
- package/dist/runtime/agentEndpointOwnership.js +239 -0
- package/dist/runtime/agentError.js +2 -10
- package/dist/runtime/agentHost.js +565 -314
- package/dist/runtime/agentRunConfiguration.js +258 -0
- package/dist/runtime/builtinAgentDrivers.js +134 -18
- package/dist/runtime/builtinAgentErrorMappers.js +55 -3
- package/dist/runtime/builtinTranscriptUsage.js +1 -1
- package/dist/runtime/claude-process-owner +0 -0
- package/dist/runtime/codexAppServerRuntime.js +38 -30
- package/dist/runtime/codexInteractiveHost.js +41 -6
- package/dist/runtime/continuationManager.js +2 -6
- package/dist/runtime/executionEnvironment.js +30 -0
- package/dist/runtime/firstProgressAdvisory.js +11 -11
- package/dist/runtime/index.js +4 -3
- package/dist/runtime/jsonLineChannel.js +109 -0
- package/dist/runtime/launchBroker.js +91 -16
- package/dist/runtime/launchDiagnostics.js +2 -2
- package/dist/runtime/lifecycleReservation.js +10 -18
- package/dist/runtime/managedCaller.js +61 -17
- package/dist/runtime/nativeSessionControl.js +102 -0
- package/dist/runtime/ports.js +6 -21
- package/dist/runtime/processExitObservation.js +8 -7
- package/dist/runtime/promptEnvelope.js +17 -6
- package/dist/runtime/providerContinuation.js +3 -9
- package/dist/runtime/providerContinuationReconciliationService.js +4 -13
- package/dist/runtime/providerControl.js +2 -7
- package/dist/runtime/providerRuntimeIdentity.js +110 -222
- package/dist/runtime/providerRuntimeReconciler.js +5 -9
- package/dist/runtime/runtimeBinding.js +0 -1
- package/dist/runtime/runtimeContinuationProjection.js +4 -7
- package/dist/runtime/runtimeDeadlines.js +9 -0
- package/dist/runtime/runtimeHealthPolicy.js +1 -1
- package/dist/runtime/runtimeObservation.js +29 -65
- package/dist/runtime/runtimeProjection.js +43 -51
- package/dist/runtime/runtimeSessionCandidate.js +1 -3
- package/dist/runtime/sessionLaunchRequest.js +3 -7
- package/dist/runtime/sessionOwnerIdentity.js +7 -54
- package/dist/runtime/sessionOwnerRegistry.js +22 -17
- package/dist/runtime/sessionReconciliation.js +4 -8
- package/dist/runtime/sessionTerminationGuard.js +70 -259
- package/dist/runtime/sessionTokenMetrics.js +5 -16
- package/dist/runtime/structuredProviderHost.js +237 -117
- package/dist/runtime/taskRuntimeIsolation.js +39 -122
- package/dist/runtime/tmuxAdapters.js +39 -86
- package/dist/scheduler/activeRoleRunDelivery.js +354 -0
- package/dist/scheduler/leaderWakeupProcessor.js +75 -266
- package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
- package/dist/scheduler/ports.js +80 -9
- package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
- package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
- package/dist/scheduler/taskExecutionProjection.js +120 -124
- package/dist/scheduler/taskObservabilityProjection.js +29 -29
- package/dist/scheduler/taskWake.js +11 -4
- package/dist/scheduler/wakeReason.js +9 -1
- package/dist/setup/setupCommand.js +1 -0
- package/dist/storage/migrations/agentRunContract.js +159 -0
- package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
- package/dist/storage/sqliteSchema.js +431 -5
- package/dist/storage/sqliteStore.js +375 -220
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +10 -5
- package/dist/storage/taskStore.js +13 -11
- package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
- package/dist/surface/surfaceContributions.js +102 -0
- package/dist/task/completionReadiness.js +32 -6
- package/dist/task/deliveryGuard.js +16 -16
- package/dist/task/draftPlan.js +72 -12
- package/dist/task/nextAction.js +144 -128
- package/dist/task/remoteDelivery.js +6 -6
- package/dist/task/task.js +184 -18
- package/dist/task/taskActivation.js +301 -0
- package/dist/task/taskActivationService.js +392 -0
- package/dist/task/taskRecordReference.js +5 -4
- package/dist/task/taskRecordRetirement.js +1 -1
- package/dist/telemetry/sqliteTelemetryStore.js +55 -68
- package/dist/telemetry/telemetryConfig.js +14 -14
- package/dist/telemetry/telemetryWiring.js +2 -2
- package/dist/web/assets/assetManifest.js +2 -0
- package/dist/web/assets/client/app.js +120 -20
- package/dist/web/assets/client/components.js +87 -54
- package/dist/web/assets/client/i18n.js +83 -41
- package/dist/web/assets/client/markdown.js +1 -1
- package/dist/web/assets/client/taskSurface.js +353 -0
- package/dist/web/assets/client/view.js +49 -44
- package/dist/web/assets/shell.js +1 -1
- package/dist/web/assets/styles/cards.js +22 -4
- package/dist/web/controllerWeb.js +60 -0
- package/dist/web/webMutation.js +28 -0
- package/dist/web/webServer.js +118 -8
- package/dist/web/webSnapshot.js +81 -74
- package/dist/web/webTaskSurface.js +64 -0
- package/dist/workItem/dependencyGate.js +1 -1
- package/dist/workItem/workItem.js +80 -48
- package/dist/workspace/workItemChangeSetManager.js +16 -9
- package/docs/agent-result-consumption.md +94 -0
- package/docs/agent-runtime-drivers.md +91 -0
- package/docs/architecture/README.md +38 -0
- package/docs/architecture/capabilities-and-resources.md +79 -0
- package/docs/managed-turn-and-session-runtime.md +222 -0
- package/docs/observability/README.md +81 -0
- package/docs/plugin-sdk.md +290 -0
- package/docs/provider-runtime.md +163 -0
- package/docs/release-workflow.md +303 -0
- package/docs/roles-and-configuration.md +113 -0
- package/docs/sqlite-control-plane-design.md +76 -0
- package/docs/task-dag-semantics.md +57 -0
- package/docs/task-delivery.md +103 -0
- package/docs/task-local-identity.md +6 -6
- package/docs/testing/verification-levels.md +86 -0
- package/i18n/README.zh-CN.md +98 -739
- package/package.json +2 -2
- package/skills/yui-leader/SKILL.md +130 -103
- package/skills/yui-leader/references/integration.md +39 -0
- package/skills/yui-leader/references/replicated-execution.md +42 -0
- package/skills/yui-leader/references/task-plugins.md +33 -0
- package/skills/yui-operator/SKILL.md +30 -59
- package/skills/yui-reviewer/SKILL.md +35 -36
- package/skills/yui-runtime/SKILL.md +88 -24
- package/skills/yui-runtime/references/publication.md +22 -0
- package/skills/yui-runtime/references/recovery.md +64 -0
- package/skills/yui-worker/SKILL.md +37 -39
- package/dist/cli/roleOptionCatalog.js +0 -68
- package/dist/context/sourceTurnContext.js +0 -30
- package/dist/execution/reviewMainTurn.js +0 -161
- package/dist/execution/workItemMainTurn.js +0 -164
- package/dist/lifecycle/exactTurnTerminalization.js +0 -407
- package/dist/runtime/preallocatedNativeSession.js +0 -13
- package/dist/runtime/runtimeStopReceipt.js +0 -42
- package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { validateExecutionEnvironmentSnapshot } from "../resources/projectResource.js";
|
|
2
3
|
import { validateManagedWorkspace } from "../worktree/managedWorkspace.js";
|
|
3
4
|
import { resolveAgentAdapter } from "./agentAdapter.js";
|
|
4
5
|
import { roleSessionKind } from "../context/roleSessionContext.js";
|
|
6
|
+
import { isAgentAdapterId } from "../agent/adapterCatalog.js";
|
|
7
|
+
import { adapterIdForExecutionComponent, isAgentExecutionComponentId, resolveAgentExecutionComponent } from "../agent/executionComponents.js";
|
|
5
8
|
import { SESSION_BOOTSTRAP_MANIFEST_SCHEMA_VERSION, sessionManifestCompatibilityDigest } from "../context/sessionProtocolIdentity.js";
|
|
6
9
|
export function resolveEffectiveLaunch(input) {
|
|
10
|
+
if (input.purpose === "planning" && input.executionAuthority === "delivery") {
|
|
11
|
+
throw new Error("Planning cannot request delivery authority.");
|
|
12
|
+
}
|
|
7
13
|
validateDesiredRole(input.role);
|
|
8
14
|
const binding = input.role.agentBindings[input.role.activeAgentId];
|
|
9
15
|
const workspace = snapshotWorkspace(input.role.workspace, input.workspace);
|
|
10
16
|
const writeProjectIds = effectiveWriteProjects(input, workspace);
|
|
11
17
|
const config = resolveAgentAdapter(binding.adapterId).canonicalizeConfig(clone(binding.config));
|
|
12
18
|
return snapshotFromConfig({
|
|
19
|
+
executionAuthority: input.executionAuthority ?? (input.purpose === "planning" ? "planning" : "delivery"),
|
|
13
20
|
sourceDesiredRevision: input.role.launchRevision,
|
|
14
21
|
agentId: binding.agentId,
|
|
22
|
+
component: resolveAgentExecutionComponent(binding.adapterId, binding.component),
|
|
15
23
|
config,
|
|
16
24
|
profileAccess: input.role.defaultAccess,
|
|
17
25
|
writeProjectIds,
|
|
18
26
|
workspace,
|
|
27
|
+
...("taskId" in input.role && input.role.executionEnvironment !== undefined
|
|
28
|
+
? { executionEnvironment: input.role.executionEnvironment }
|
|
29
|
+
: {}),
|
|
19
30
|
context: snapshotContext(input.role),
|
|
20
31
|
contextProtocolVersion: SESSION_BOOTSTRAP_MANIFEST_SCHEMA_VERSION,
|
|
21
32
|
sessionManifestCompatibilityDigest: sessionManifestCompatibilityDigest(input.role.name, roleSessionKind(input.role, "taskId" in input.role
|
|
@@ -69,6 +80,24 @@ function claudeConfigFromSnapshot(snapshot) {
|
|
|
69
80
|
: { settingsSources: [...snapshot.settingsSources] })
|
|
70
81
|
};
|
|
71
82
|
}
|
|
83
|
+
function acpConfigFromSnapshot(snapshot) {
|
|
84
|
+
// Model and effort round-trip because they are ACP session config options
|
|
85
|
+
// that this launch pushes and confirms. Settings deliberately do not: the
|
|
86
|
+
// protocol defines no client-side settings file or settings source, so the
|
|
87
|
+
// snapshot type keeps those permanently absent.
|
|
88
|
+
return {
|
|
89
|
+
adapterId: "acp",
|
|
90
|
+
...(snapshot.model === undefined ? {} : { model: snapshot.model }),
|
|
91
|
+
...(snapshot.effort === undefined ? {} : { effort: snapshot.effort }),
|
|
92
|
+
permission: clone(snapshot.permission),
|
|
93
|
+
...(snapshot.additionalDirectories === undefined
|
|
94
|
+
? {}
|
|
95
|
+
: { additionalDirectories: [...snapshot.additionalDirectories] }),
|
|
96
|
+
...(snapshot.advanced === undefined
|
|
97
|
+
? {}
|
|
98
|
+
: { advanced: clone(snapshot.advanced) })
|
|
99
|
+
};
|
|
100
|
+
}
|
|
72
101
|
/**
|
|
73
102
|
* Exactness fence for one launch: the same resolved launch must be observed by
|
|
74
103
|
* every participant of that launch. Desired-revision bookkeeping is provenance
|
|
@@ -89,12 +118,12 @@ export function sameEffectiveLaunch(existing, desired) {
|
|
|
89
118
|
* Only facts that make continuation impossible participate: the Session
|
|
90
119
|
* protocol, the provider identity that owns the conversation, and the physical
|
|
91
120
|
* workspace the Session runs in. Launch configuration such as model, effort,
|
|
92
|
-
* permission, Role context, declared write scope, and
|
|
93
|
-
* ReviewRound identity or candidate commits shape the next Host
|
|
121
|
+
* permission, Role context, declared write scope, and AgentRun-scoped facts like
|
|
122
|
+
* ReviewRound identity or candidate commits shape the next Host process
|
|
94
123
|
* instead of ending the Session; that divergence is acknowledged where the
|
|
95
124
|
* configuration changes and stays visible as launch provenance.
|
|
96
125
|
*
|
|
97
|
-
* Session kind needs no separate check: a Role's review
|
|
126
|
+
* Session kind needs no separate check: a Role's review AgentRuns run in their own
|
|
98
127
|
* ReviewRound workspace, so the physical workspace already separates a review
|
|
99
128
|
* Session from an execution Session.
|
|
100
129
|
*/
|
|
@@ -108,7 +137,7 @@ export function effectiveLaunchWithTaskMainWorkspace(existing, workspace) {
|
|
|
108
137
|
validateEffectiveLaunchSnapshot(existing);
|
|
109
138
|
validateManagedWorkspace(workspace);
|
|
110
139
|
if (workspace.owner.type !== "task") {
|
|
111
|
-
throw new Error("Only a Task-owned main workspace may refresh fixed Session
|
|
140
|
+
throw new Error("Only a Task-owned main workspace may refresh fixed Session AgentRun evidence.");
|
|
112
141
|
}
|
|
113
142
|
return validateEffectiveLaunchSnapshot({
|
|
114
143
|
...existing,
|
|
@@ -121,9 +150,15 @@ export function effectiveLaunchWithTaskMainWorkspace(existing, workspace) {
|
|
|
121
150
|
function sessionContinuitySnapshot(snapshot) {
|
|
122
151
|
return {
|
|
123
152
|
schemaVersion: snapshot.schemaVersion,
|
|
153
|
+
executionAuthority: snapshot.executionAuthority,
|
|
124
154
|
contextProtocolVersion: snapshot.contextProtocolVersion,
|
|
125
155
|
agentId: snapshot.agentId,
|
|
156
|
+
// Two products on one connection plan are two different conversations. A
|
|
157
|
+
// Session that started against an unidentified ACP Agent must not silently
|
|
158
|
+
// continue against the Claude Agent SDK just because both speak ACP.
|
|
159
|
+
component: snapshot.component,
|
|
126
160
|
adapterId: snapshot.adapterId,
|
|
161
|
+
executionEnvironment: snapshot.executionEnvironment,
|
|
127
162
|
workspace: {
|
|
128
163
|
root: snapshot.workspace.root,
|
|
129
164
|
entries: snapshot.workspace.entries.map((entry) => ({
|
|
@@ -137,11 +172,18 @@ function sessionContinuitySnapshot(snapshot) {
|
|
|
137
172
|
};
|
|
138
173
|
}
|
|
139
174
|
export function validateEffectiveLaunchSnapshot(snapshot) {
|
|
140
|
-
if (snapshot.schemaVersion !==
|
|
141
|
-
throw new Error("Effective launch snapshot must use schemaVersion
|
|
175
|
+
if (snapshot.schemaVersion !== 4) {
|
|
176
|
+
throw new Error("Effective launch snapshot must use schemaVersion 4.");
|
|
177
|
+
}
|
|
178
|
+
if (snapshot.executionAuthority !== "planning" && snapshot.executionAuthority !== "delivery") {
|
|
179
|
+
throw new Error("Effective launch requires its captured execution authority.");
|
|
142
180
|
}
|
|
143
181
|
positiveInteger(snapshot.sourceDesiredRevision, "Source desired revision");
|
|
144
182
|
identity(snapshot.agentId, "Effective Agent id");
|
|
183
|
+
if (!isAgentExecutionComponentId(snapshot.component)
|
|
184
|
+
|| adapterIdForExecutionComponent(snapshot.component) !== snapshot.adapterId) {
|
|
185
|
+
throw new Error(`Effective launch execution component is invalid: ${String(snapshot.component)}.`);
|
|
186
|
+
}
|
|
145
187
|
if (snapshot.profileAccess !== "read" && snapshot.profileAccess !== "write") {
|
|
146
188
|
throw new Error(`Effective launch Profile access is invalid: ${String(snapshot.profileAccess)}.`);
|
|
147
189
|
}
|
|
@@ -172,6 +214,19 @@ export function validateEffectiveLaunchSnapshot(snapshot) {
|
|
|
172
214
|
throw new Error("Effective launch Session Manifest compatibility digest is invalid.");
|
|
173
215
|
}
|
|
174
216
|
validateWorkspace(snapshot.workspace);
|
|
217
|
+
if (snapshot.executionEnvironment !== undefined) {
|
|
218
|
+
validateExecutionEnvironmentSnapshot(snapshot.executionEnvironment);
|
|
219
|
+
if (snapshot.executionEnvironment.access === "read") {
|
|
220
|
+
if (snapshot.adapterId !== "codex") {
|
|
221
|
+
throw new Error("Read-only execution environments require a native filesystem sandbox; Claude is unsupported.");
|
|
222
|
+
}
|
|
223
|
+
if (snapshot.permission.strategy !== "configured"
|
|
224
|
+
|| snapshot.permission.sandbox !== "read-only"
|
|
225
|
+
|| snapshot.permission.approval !== "never") {
|
|
226
|
+
throw new Error("Read-only execution environments require Codex configured sandbox read-only and approval never.");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
175
230
|
cloneContext(snapshot.context);
|
|
176
231
|
const config = effectiveLaunchConfigUnchecked(snapshot);
|
|
177
232
|
resolveAgentAdapter(snapshot.adapterId).canonicalizeConfig(config);
|
|
@@ -182,6 +237,7 @@ export function effectiveRoleForLaunch(role, snapshot) {
|
|
|
182
237
|
const config = effectiveLaunchConfig(snapshot);
|
|
183
238
|
const binding = {
|
|
184
239
|
agentId: snapshot.agentId,
|
|
240
|
+
component: snapshot.component,
|
|
185
241
|
adapterId: snapshot.adapterId,
|
|
186
242
|
config
|
|
187
243
|
};
|
|
@@ -194,6 +250,19 @@ export function effectiveRoleForLaunch(role, snapshot) {
|
|
|
194
250
|
defaultAccess: snapshot.profileAccess,
|
|
195
251
|
workspace: snapshot.workspace.root
|
|
196
252
|
};
|
|
253
|
+
if ("taskId" in result) {
|
|
254
|
+
if (snapshot.executionEnvironment === undefined)
|
|
255
|
+
delete result.executionEnvironment;
|
|
256
|
+
else {
|
|
257
|
+
if (snapshot.executionEnvironment.taskId !== result.taskId) {
|
|
258
|
+
throw new Error("Effective execution environment belongs to another Task.");
|
|
259
|
+
}
|
|
260
|
+
result.executionEnvironment = clone(snapshot.executionEnvironment);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (snapshot.executionEnvironment !== undefined) {
|
|
264
|
+
throw new Error("Only a Task Role may use an execution environment.");
|
|
265
|
+
}
|
|
197
266
|
clearMissingContext(result, snapshot.context);
|
|
198
267
|
return result;
|
|
199
268
|
}
|
|
@@ -209,9 +278,11 @@ function snapshotFromConfig(input) {
|
|
|
209
278
|
reviewBaseCommit: commit(input.reviewBaseCommit ?? "", "Review base commit")
|
|
210
279
|
};
|
|
211
280
|
const common = {
|
|
212
|
-
schemaVersion:
|
|
281
|
+
schemaVersion: 4,
|
|
282
|
+
executionAuthority: input.executionAuthority,
|
|
213
283
|
sourceDesiredRevision: positiveInteger(input.sourceDesiredRevision, "Source desired revision"),
|
|
214
284
|
agentId: identity(input.agentId, "Effective Agent id"),
|
|
285
|
+
component: input.component,
|
|
215
286
|
profileAccess: input.profileAccess,
|
|
216
287
|
...(config.model === undefined ? {} : { model: config.model }),
|
|
217
288
|
...(config.effort === undefined ? {} : { effort: config.effort }),
|
|
@@ -222,6 +293,9 @@ function snapshotFromConfig(input) {
|
|
|
222
293
|
...(config.advanced === undefined ? {} : { advanced: clone(config.advanced) }),
|
|
223
294
|
writeProjectIds: [...input.writeProjectIds],
|
|
224
295
|
workspace: cloneWorkspace(input.workspace),
|
|
296
|
+
...(input.executionEnvironment === undefined
|
|
297
|
+
? {}
|
|
298
|
+
: { executionEnvironment: clone(input.executionEnvironment) }),
|
|
225
299
|
context: cloneContext(input.context),
|
|
226
300
|
contextProtocolVersion: input.contextProtocolVersion,
|
|
227
301
|
sessionManifestCompatibilityDigest: input.sessionManifestCompatibilityDigest,
|
|
@@ -234,21 +308,25 @@ function snapshotFromConfig(input) {
|
|
|
234
308
|
permission: clone(config.permission),
|
|
235
309
|
...(config.profile === undefined ? {} : { profile: config.profile })
|
|
236
310
|
}
|
|
237
|
-
:
|
|
238
|
-
...common,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
? {}
|
|
244
|
-
|
|
245
|
-
|
|
311
|
+
: config.adapterId === "acp"
|
|
312
|
+
? { ...common, adapterId: "acp", permission: clone(config.permission) }
|
|
313
|
+
: {
|
|
314
|
+
...common,
|
|
315
|
+
adapterId: "claude",
|
|
316
|
+
permission: clone(config.permission),
|
|
317
|
+
...(config.settingsFile === undefined ? {} : { settingsFile: config.settingsFile }),
|
|
318
|
+
...(config.settingsSources === undefined
|
|
319
|
+
? {}
|
|
320
|
+
: { settingsSources: [...config.settingsSources] })
|
|
321
|
+
};
|
|
246
322
|
return validateEffectiveLaunchSnapshot(snapshot);
|
|
247
323
|
}
|
|
248
324
|
function effectiveLaunchConfigUnchecked(snapshot) {
|
|
249
325
|
return snapshot.adapterId === "codex"
|
|
250
326
|
? codexConfigFromSnapshot(snapshot)
|
|
251
|
-
:
|
|
327
|
+
: snapshot.adapterId === "acp"
|
|
328
|
+
? acpConfigFromSnapshot(snapshot)
|
|
329
|
+
: claudeConfigFromSnapshot(snapshot);
|
|
252
330
|
}
|
|
253
331
|
function effectiveWriteProjects(input, workspace) {
|
|
254
332
|
if (input.purpose === "review") {
|
|
@@ -367,10 +445,19 @@ function validateDesiredRole(role) {
|
|
|
367
445
|
if (role.defaultAccess !== "read" && role.defaultAccess !== "write") {
|
|
368
446
|
throw new Error("Role default access is invalid.");
|
|
369
447
|
}
|
|
448
|
+
if ("executionEnvironment" in role && role.executionEnvironment !== undefined) {
|
|
449
|
+
if (!("taskId" in role))
|
|
450
|
+
throw new Error("Only a Task Role may use an execution environment.");
|
|
451
|
+
validateExecutionEnvironmentSnapshot(role.executionEnvironment);
|
|
452
|
+
if (role.executionEnvironment.taskId !== role.taskId) {
|
|
453
|
+
throw new Error("Role execution environment belongs to another Task.");
|
|
454
|
+
}
|
|
455
|
+
}
|
|
370
456
|
const binding = role.agentBindings[role.activeAgentId];
|
|
371
457
|
if (binding === undefined)
|
|
372
458
|
throw new Error("Role active Agent binding is missing.");
|
|
373
|
-
|
|
459
|
+
// Adapter support is the catalog's fact, not a second list to keep in sync.
|
|
460
|
+
if (!isAgentAdapterId(binding.adapterId)) {
|
|
374
461
|
throw new Error(`Role Agent adapter is unsupported: ${binding.adapterId}.`);
|
|
375
462
|
}
|
|
376
463
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { createPromptEnvelope, createSessionLaunchRequest } from "../runtime/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
|
|
4
|
+
import { formatRunReceiptId } from "../task/taskRecordReference.js";
|
|
4
5
|
/**
|
|
5
6
|
* rr13/test: Test-only liveness seam. Integration tests that spawn a real
|
|
6
7
|
* Controller subprocess cannot inject a fake TmuxDeliveryPort, and a saved
|
|
7
|
-
* active Leader
|
|
8
|
+
* active Leader AgentRun would be reaped by the startup liveness pass without a
|
|
8
9
|
* real tmux role. When this env var is "1", every role reads "present"
|
|
9
10
|
* without probing tmux. The Controller subprocess inherits it from the
|
|
10
11
|
* test's CLI env. Never set in production.
|
|
@@ -38,7 +39,7 @@ export class ExecutorRegistry {
|
|
|
38
39
|
agentId: input.agentId,
|
|
39
40
|
adapterId: input.adapterId,
|
|
40
41
|
mode: input.mode,
|
|
41
|
-
...(input.
|
|
42
|
+
...(input.runId === undefined ? {} : { runId: input.runId })
|
|
42
43
|
};
|
|
43
44
|
const cached = this.#prepared.get(deliveryBase.deliveryId);
|
|
44
45
|
if (cached !== undefined)
|
|
@@ -49,16 +50,6 @@ export class ExecutorRegistry {
|
|
|
49
50
|
if (this.runtimePorts === undefined) {
|
|
50
51
|
planned = this.planner.plan(input);
|
|
51
52
|
sessionStarted = this.tmux.ensureRoleWindow(input.taskId, planned.role, planned.launch);
|
|
52
|
-
if (sessionStarted
|
|
53
|
-
&& planned.launch.env.YUI_JOB_CALLER_KEY !== undefined
|
|
54
|
-
&& this.planner.commitTaskCallerKey !== undefined) {
|
|
55
|
-
this.planner.commitTaskCallerKey({
|
|
56
|
-
taskId: input.taskId,
|
|
57
|
-
roleName: input.roleName,
|
|
58
|
-
agentId: input.agentId,
|
|
59
|
-
callerKey: planned.launch.env.YUI_JOB_CALLER_KEY
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
53
|
session = planned.session;
|
|
63
54
|
}
|
|
64
55
|
else {
|
|
@@ -71,10 +62,11 @@ export class ExecutorRegistry {
|
|
|
71
62
|
...(input.managedWorkspace === undefined
|
|
72
63
|
? {}
|
|
73
64
|
: { managedWorkspace: input.managedWorkspace }),
|
|
65
|
+
...(input.workspaceFree === true ? { workspaceFree: true } : {}),
|
|
74
66
|
...(input.runtimePolicy === undefined
|
|
75
67
|
? {}
|
|
76
68
|
: { runtimePolicy: input.runtimePolicy }),
|
|
77
|
-
...(input.
|
|
69
|
+
...(input.runId === undefined ? {} : { runId: input.runId })
|
|
78
70
|
};
|
|
79
71
|
if (this.runtimePorts.launchCoordinator !== undefined) {
|
|
80
72
|
binding = await this.runtimePorts.launchCoordinator.prepare(input.mode === "new"
|
|
@@ -83,21 +75,16 @@ export class ExecutorRegistry {
|
|
|
83
75
|
...common,
|
|
84
76
|
mode: "resume",
|
|
85
77
|
nativeSessionId: input.nativeSessionId,
|
|
86
|
-
|
|
87
|
-
? {}
|
|
88
|
-
: { hostActivationId: input.hostActivationId })
|
|
89
|
-
}, "deferred", undefined, input.beforeHostStart);
|
|
78
|
+
}, undefined, input.beforeHostStart);
|
|
90
79
|
}
|
|
91
80
|
else {
|
|
92
81
|
const request = input.mode === "new"
|
|
93
82
|
? createSessionLaunchRequest({
|
|
94
83
|
...common,
|
|
95
|
-
runtimeGenerationId: deliveryBase.deliveryId,
|
|
96
84
|
mode: "new"
|
|
97
85
|
})
|
|
98
86
|
: createSessionLaunchRequest({
|
|
99
87
|
...common,
|
|
100
|
-
runtimeGenerationId: deliveryBase.deliveryId,
|
|
101
88
|
mode: "resume",
|
|
102
89
|
nativeSessionId: input.nativeSessionId
|
|
103
90
|
});
|
|
@@ -118,7 +105,6 @@ export class ExecutorRegistry {
|
|
|
118
105
|
}
|
|
119
106
|
const delivery = {
|
|
120
107
|
...deliveryBase,
|
|
121
|
-
...(binding === undefined ? {} : { runtimeGenerationId: binding.runtimeGenerationId }),
|
|
122
108
|
sessionStarted,
|
|
123
109
|
session,
|
|
124
110
|
};
|
|
@@ -141,18 +127,20 @@ export class ExecutorRegistry {
|
|
|
141
127
|
async sendOnce(input) {
|
|
142
128
|
const prepared = this.requirePrepared(input.delivery.prepared);
|
|
143
129
|
if (prepared.binding !== undefined && this.runtimePorts !== undefined) {
|
|
144
|
-
const
|
|
145
|
-
if (
|
|
146
|
-
throw new Error("Runtime prompt delivery requires a Task-local
|
|
130
|
+
const runId = input.delivery.prepared.runId;
|
|
131
|
+
if (runId === undefined && input.notificationId === undefined) {
|
|
132
|
+
throw new Error("Runtime prompt delivery requires a Task-local AgentRun id.");
|
|
147
133
|
}
|
|
148
134
|
const outcome = await this.runtimePorts.promptPush.tryPush({
|
|
149
135
|
binding: prepared.binding,
|
|
150
136
|
envelope: createPromptEnvelope({
|
|
151
137
|
id: input.receiptId,
|
|
152
|
-
source: {
|
|
153
|
-
kind:
|
|
138
|
+
source: input.notificationId !== undefined ? {
|
|
139
|
+
kind: "notification", taskId: input.delivery.prepared.taskId, localId: input.notificationId
|
|
140
|
+
} : {
|
|
141
|
+
kind: input.receiptId === formatRunReceiptId(input.delivery.prepared.taskId, runId) || input.receiptId.startsWith(`${formatRunReceiptId(input.delivery.prepared.taskId, runId)}/attempt/`) ? "run" : "turn-input",
|
|
154
142
|
taskId: input.delivery.prepared.taskId,
|
|
155
|
-
localId:
|
|
143
|
+
localId: runId
|
|
156
144
|
},
|
|
157
145
|
text: input.text,
|
|
158
146
|
createdAt: new Date()
|
|
@@ -174,7 +162,6 @@ export class ExecutorRegistry {
|
|
|
174
162
|
return { status: "unavailable" };
|
|
175
163
|
const outcome = await this.runtimePorts.promptPush.trySteer({
|
|
176
164
|
owner: { scope: "task", taskId: input.taskId, roleName: input.roleName },
|
|
177
|
-
runtimeGenerationId: input.runtimeGenerationId,
|
|
178
165
|
agentId: input.agentId,
|
|
179
166
|
adapterId: input.adapterId,
|
|
180
167
|
nativeSessionId: input.nativeSessionId,
|
|
@@ -182,7 +169,7 @@ export class ExecutorRegistry {
|
|
|
182
169
|
providerAuthority: input.authority,
|
|
183
170
|
envelope: createPromptEnvelope({
|
|
184
171
|
id: input.receiptId,
|
|
185
|
-
source: { kind: "turn-input", taskId: input.taskId, localId:
|
|
172
|
+
source: { kind: "turn-input", taskId: input.taskId, localId: activeRunId(input.receiptId) },
|
|
186
173
|
text: input.text,
|
|
187
174
|
createdAt: new Date()
|
|
188
175
|
})
|
|
@@ -198,12 +185,7 @@ export class ExecutorRegistry {
|
|
|
198
185
|
forgetPrepared(input) {
|
|
199
186
|
for (const [deliveryId, prepared] of this.#prepared) {
|
|
200
187
|
const delivery = prepared.delivery;
|
|
201
|
-
if (delivery.taskId !== input.taskId
|
|
202
|
-
|| delivery.roleName !== input.roleName
|
|
203
|
-
|| (input.turnId !== undefined
|
|
204
|
-
&& delivery.turnId !== input.turnId)
|
|
205
|
-
|| (input.runtimeGenerationId !== undefined
|
|
206
|
-
&& delivery.runtimeGenerationId !== input.runtimeGenerationId)) {
|
|
188
|
+
if (delivery.taskId !== input.taskId || delivery.roleName !== input.roleName || (input.runId !== undefined && delivery.runId !== input.runId)) {
|
|
207
189
|
continue;
|
|
208
190
|
}
|
|
209
191
|
this.#prepared.delete(deliveryId);
|
|
@@ -260,13 +242,12 @@ export class ExecutorRegistry {
|
|
|
260
242
|
const requested = resourceInputs ?? inputs.map((input) => ({
|
|
261
243
|
taskId: input.taskId,
|
|
262
244
|
roleName: input.roleName,
|
|
263
|
-
...(input.
|
|
245
|
+
...(input.runId === undefined ? {} : { runId: input.runId }),
|
|
264
246
|
agentId: input.agentId,
|
|
265
247
|
adapterId: input.adapterId,
|
|
266
248
|
...(input.nativeSessionId === undefined
|
|
267
249
|
? {}
|
|
268
250
|
: { nativeSessionId: input.nativeSessionId }),
|
|
269
|
-
...(input.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: input.runtimeGenerationId }),
|
|
270
251
|
...(input.progressAt === undefined ? {} : { progressAt: input.progressAt })
|
|
271
252
|
}));
|
|
272
253
|
if (this.runtimePorts?.roleResourceInventory !== undefined
|
|
@@ -328,10 +309,10 @@ export class ExecutorRegistry {
|
|
|
328
309
|
return planned;
|
|
329
310
|
}
|
|
330
311
|
}
|
|
331
|
-
function
|
|
312
|
+
function activeRunId(receiptId) {
|
|
332
313
|
const match = /^turn-input:[^/]+\/([^/]+)\/[1-9]\d*$/u.exec(receiptId);
|
|
333
314
|
if (match === null)
|
|
334
|
-
throw new Error("
|
|
315
|
+
throw new Error("AgentRun steer receipt is invalid.");
|
|
335
316
|
return decodeURIComponent(match[1]);
|
|
336
317
|
}
|
|
337
318
|
/**
|
|
@@ -346,10 +327,15 @@ function deliveryReport(outcome) {
|
|
|
346
327
|
};
|
|
347
328
|
}
|
|
348
329
|
export function agentProcessReadinessProbe(adapterId, _surface = "role") {
|
|
349
|
-
|
|
330
|
+
// A tmux pane probe is only meaningful for an Agent that actually has an
|
|
331
|
+
// interactive CLI surface. Asking a protocol-only Agent whether its pane
|
|
332
|
+
// looks alive would answer a question about the wrong thing, so the refusal
|
|
333
|
+
// is derived from the declared surface rather than from an adapter name.
|
|
334
|
+
const driver = builtinAgentDriverRegistry().findByAdapterId(adapterId);
|
|
335
|
+
if (driver === null || !driver.capabilities.surfaces.includes("interactive-cli")) {
|
|
350
336
|
throw new Error(`No tmux readiness probe is registered for Agent adapter: ${adapterId}.`);
|
|
351
337
|
}
|
|
352
|
-
//
|
|
338
|
+
// AgentRun state and receipt fences decide whether delivery is allowed. Provider
|
|
353
339
|
// terminal contents are display-only evidence and never lifecycle input.
|
|
354
340
|
return livePane;
|
|
355
341
|
}
|
|
@@ -364,9 +350,8 @@ function preparedDeliveryId(input) {
|
|
|
364
350
|
input.adapterId,
|
|
365
351
|
input.effective,
|
|
366
352
|
input.mode,
|
|
367
|
-
input.
|
|
368
|
-
input.nativeSessionId ?? null
|
|
369
|
-
input.hostActivationId ?? null
|
|
353
|
+
input.runId ?? null,
|
|
354
|
+
input.nativeSessionId ?? null
|
|
370
355
|
])).digest("hex");
|
|
371
356
|
}
|
|
372
357
|
function hasText(value) {
|