@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,10 +1,23 @@
|
|
|
1
1
|
export const AGENT_ADAPTER_CATALOG = Object.freeze([
|
|
2
2
|
Object.freeze({ id: "codex", label: "Codex" }),
|
|
3
|
-
Object.freeze({ id: "claude", label: "Claude" })
|
|
3
|
+
Object.freeze({ id: "claude", label: "Claude" }),
|
|
4
|
+
// One adapter for the Agent Client Protocol, not one per product. Which ACP
|
|
5
|
+
// Agent runs is a launch descriptor fact, so a further ACP product needs no
|
|
6
|
+
// new adapter and no new branch anywhere above this line.
|
|
7
|
+
Object.freeze({ id: "acp", label: "Agent Client Protocol" })
|
|
4
8
|
]);
|
|
5
9
|
export function supportedAgentAdapterIds() {
|
|
6
10
|
return AGENT_ADAPTER_CATALOG.map(({ id }) => id).sort();
|
|
7
11
|
}
|
|
8
12
|
export function isAgentAdapterId(value) {
|
|
9
|
-
return
|
|
13
|
+
return AGENT_ADAPTER_CATALOG.some(({ id }) => id === value);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The catalog's own display label, falling back to the raw id.
|
|
17
|
+
*
|
|
18
|
+
* The fallback is deliberate: a stored binding may name an adapter this build
|
|
19
|
+
* no longer ships, and showing that id is more useful than hiding it.
|
|
20
|
+
*/
|
|
21
|
+
export function agentAdapterLabel(adapterId) {
|
|
22
|
+
return AGENT_ADAPTER_CATALOG.find(({ id }) => id === adapterId)?.label ?? adapterId;
|
|
10
23
|
}
|
package/dist/agent/agent.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isAgentAdapterId } from "./adapterCatalog.js";
|
|
2
|
+
import { adapterIdForExecutionComponent, resolveAgentExecutionComponent } from "./executionComponents.js";
|
|
2
3
|
import { validateAgentBaseArguments } from "./argumentPolicy.js";
|
|
3
|
-
export function createConfiguredAgent(id, adapterId, command, baseArgs, environment, now) {
|
|
4
|
+
export function createConfiguredAgent(id, adapterId, command, baseArgs, environment, now, component) {
|
|
4
5
|
const normalizedId = requireSafeIdentity(id, "Agent id");
|
|
5
6
|
if (!isAgentAdapterId(adapterId))
|
|
6
7
|
throw new Error(`Agent adapter is unsupported: ${adapterId}.`);
|
|
@@ -8,8 +9,11 @@ export function createConfiguredAgent(id, adapterId, command, baseArgs, environm
|
|
|
8
9
|
validateAgentBaseArguments(adapterId, baseArgs);
|
|
9
10
|
const timestamp = now.toISOString();
|
|
10
11
|
return {
|
|
11
|
-
schemaVersion:
|
|
12
|
+
schemaVersion: 3,
|
|
12
13
|
id: normalizedId,
|
|
14
|
+
// An unnamed component resolves from the plan, which for ACP means the
|
|
15
|
+
// unidentified entry rather than a guess at which product is installed.
|
|
16
|
+
component: resolveAgentExecutionComponent(adapterId, component),
|
|
13
17
|
adapterId,
|
|
14
18
|
command: normalizedCommand,
|
|
15
19
|
baseArgs: [...baseArgs],
|
|
@@ -41,11 +45,27 @@ export function resolveAgentEnvironment(agent, processEnvironment = process.env)
|
|
|
41
45
|
}));
|
|
42
46
|
}
|
|
43
47
|
export function validateConfiguredAgent(agent) {
|
|
44
|
-
if (agent.schemaVersion !==
|
|
48
|
+
if (agent.schemaVersion !== 3)
|
|
45
49
|
throw new Error("Agent schema version is invalid.");
|
|
46
50
|
requireSafeIdentity(agent.id, "Agent id");
|
|
47
51
|
if (!isAgentAdapterId(agent.adapterId))
|
|
48
52
|
throw new Error(`Agent adapter is unsupported: ${agent.adapterId}.`);
|
|
53
|
+
// A schema 3 record always carries a component: storage 10 backfilled every
|
|
54
|
+
// stored Agent, and the constructor resolves one for every new Agent. So an
|
|
55
|
+
// absent value here is a corrupt record, not an old one, and resolving it to
|
|
56
|
+
// the plan default would invent a product identity for data that never lost
|
|
57
|
+
// one. That default belongs to the constructor, where an operator naming
|
|
58
|
+
// only a plan is a real and supported request — this validator reads records
|
|
59
|
+
// that were already written, where the same silence means something else.
|
|
60
|
+
if (agent.component === undefined) {
|
|
61
|
+
throw new Error(`Agent is missing its execution component: ${agent.id}.`);
|
|
62
|
+
}
|
|
63
|
+
// The component determines its plan, so a stored pair that disagrees is
|
|
64
|
+
// corruption rather than a configuration the operator can act on.
|
|
65
|
+
const expected = adapterIdForExecutionComponent(resolveAgentExecutionComponent(agent.adapterId, agent.component));
|
|
66
|
+
if (expected !== agent.adapterId) {
|
|
67
|
+
throw new Error(`Agent execution component ${agent.component} does not match adapter ${agent.adapterId}.`);
|
|
68
|
+
}
|
|
49
69
|
requireText(agent.command, "Agent command");
|
|
50
70
|
validateAgentBaseArguments(agent.adapterId, agent.baseArgs);
|
|
51
71
|
if (!Array.isArray(agent.environment))
|
|
@@ -18,7 +18,13 @@ const OWNED_ARGUMENTS_BY_ADAPTER = {
|
|
|
18
18
|
"--fallback-model", "--tools", "--system-prompt", "--system-prompt-file",
|
|
19
19
|
"--append-system-prompt", "--append-system-prompt-file", "--plugin-dir",
|
|
20
20
|
"--name", "-n", "--output-format", "--input-format"
|
|
21
|
-
]
|
|
21
|
+
],
|
|
22
|
+
// The ACP adapter compiles no arguments of its own: the protocol is spoken
|
|
23
|
+
// over stdio once the product is running, and how a given product enters ACP
|
|
24
|
+
// mode (`acp`, `--experimental-acp`, …) is a descriptor fact. Reserving any
|
|
25
|
+
// name here would both encode one product's spelling and reject the very
|
|
26
|
+
// baseArgs that select ACP mode.
|
|
27
|
+
acp: []
|
|
22
28
|
};
|
|
23
29
|
export function ownedArgumentsForAdapter(adapterId) {
|
|
24
30
|
return OWNED_ARGUMENTS_BY_ADAPTER[adapterId];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The connection plan: how Yui reaches an execution component.
|
|
3
|
+
*
|
|
4
|
+
* Yui's adapter id has always carried this meaning, but two of its values are
|
|
5
|
+
* product names and one is a protocol name, which reads as a single mixed axis.
|
|
6
|
+
* Nothing about the plans changes here; they are stated explicitly instead of
|
|
7
|
+
* being implied by an adapter id and a lookup table elsewhere.
|
|
8
|
+
*
|
|
9
|
+
* A plan names its protocol and its transport together, as one authoritative
|
|
10
|
+
* binding. Protocol and transport are not independently selectable: there is no
|
|
11
|
+
* combination graph to assemble, because a wire protocol and the carrier it
|
|
12
|
+
* runs over are decided as a pair by the implementation that speaks them.
|
|
13
|
+
*
|
|
14
|
+
* Static protocol support is what this table records: what Yui's own client
|
|
15
|
+
* implements. It is not what a given Agent agreed to. Live handshake facts are
|
|
16
|
+
* negotiated per connection and reported separately; where a plan negotiates
|
|
17
|
+
* nothing, its handshake is explicitly `none` rather than silently absent.
|
|
18
|
+
*/
|
|
19
|
+
import { AGENT_ADAPTER_CATALOG } from "./adapterCatalog.js";
|
|
20
|
+
export const AGENT_CONNECTION_PLANS = Object.freeze([
|
|
21
|
+
Object.freeze({
|
|
22
|
+
id: "codex",
|
|
23
|
+
label: "Codex app-server",
|
|
24
|
+
protocol: "codex-app-server",
|
|
25
|
+
// Codex versions its app-server interface with the CLI, not separately.
|
|
26
|
+
protocolVersion: "unknown",
|
|
27
|
+
transport: "codex-app-server-proxy",
|
|
28
|
+
handshake: "none"
|
|
29
|
+
}),
|
|
30
|
+
Object.freeze({
|
|
31
|
+
id: "claude",
|
|
32
|
+
label: "Claude Code stream-json",
|
|
33
|
+
protocol: "claude-stream-json",
|
|
34
|
+
protocolVersion: "unknown",
|
|
35
|
+
transport: "claude-stream-json",
|
|
36
|
+
handshake: "none"
|
|
37
|
+
}),
|
|
38
|
+
Object.freeze({
|
|
39
|
+
id: "acp",
|
|
40
|
+
label: "Agent Client Protocol (stdio)",
|
|
41
|
+
protocol: "agent-client-protocol",
|
|
42
|
+
protocolVersion: "1",
|
|
43
|
+
transport: "acp-stdio",
|
|
44
|
+
handshake: "negotiated",
|
|
45
|
+
handshakeMethod: "initialize"
|
|
46
|
+
})
|
|
47
|
+
]);
|
|
48
|
+
export function agentConnectionPlan(adapterId) {
|
|
49
|
+
const plan = AGENT_CONNECTION_PLANS.find(({ id }) => id === adapterId);
|
|
50
|
+
if (plan === undefined) {
|
|
51
|
+
throw new Error(`No connection plan for adapter: ${adapterId}.`);
|
|
52
|
+
}
|
|
53
|
+
return plan;
|
|
54
|
+
}
|
|
55
|
+
export function agentTransportForAdapter(adapterId) {
|
|
56
|
+
return agentConnectionPlan(adapterId).transport;
|
|
57
|
+
}
|
|
58
|
+
// Every catalogued adapter must have exactly one plan. Checking at module load
|
|
59
|
+
// turns a missing entry into an immediate, obvious failure rather than a
|
|
60
|
+
// transport mismatch surfacing at launch.
|
|
61
|
+
for (const { id } of AGENT_ADAPTER_CATALOG)
|
|
62
|
+
agentConnectionPlan(id);
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which execution component runs an Agent, stated independently from how Yui
|
|
3
|
+
* reaches it.
|
|
4
|
+
*
|
|
5
|
+
* Yui's adapter id answers one question: the connection plan — the protocol
|
|
6
|
+
* Yui speaks and the transport it speaks over. It deliberately does not answer
|
|
7
|
+
* "which product is running", because several distinct products are reachable
|
|
8
|
+
* through the same plan. The Agent Client Protocol is the clear case: Claude
|
|
9
|
+
* Code's CLI, the Claude Agent SDK bridge and any other ACP Agent all arrive
|
|
10
|
+
* over `acp`, and treating that protocol name as a product identity makes them
|
|
11
|
+
* indistinguishable in registration, display, Role bindings and Session
|
|
12
|
+
* snapshots.
|
|
13
|
+
*
|
|
14
|
+
* So the component is its own axis. Every component names exactly one
|
|
15
|
+
* connection plan it is reachable through, and that mapping is one-way and
|
|
16
|
+
* total: the component determines the plan, never the reverse. There is still
|
|
17
|
+
* exactly one authoritative binding to write, so the two facts cannot drift
|
|
18
|
+
* into disagreement, and no arbitrary component/protocol combination graph
|
|
19
|
+
* exists to be assembled.
|
|
20
|
+
*
|
|
21
|
+
* Naming follows the component that actually executes — a CLI or an SDK — and
|
|
22
|
+
* never "native", which names no product.
|
|
23
|
+
*/
|
|
24
|
+
import { isAgentAdapterId } from "./adapterCatalog.js";
|
|
25
|
+
export const AGENT_EXECUTION_COMPONENT_CATALOG = Object.freeze([
|
|
26
|
+
Object.freeze({
|
|
27
|
+
id: "codex-cli",
|
|
28
|
+
label: "Codex CLI",
|
|
29
|
+
adapterId: "codex",
|
|
30
|
+
kind: "cli",
|
|
31
|
+
identified: true
|
|
32
|
+
}),
|
|
33
|
+
// Claude Code's own CLI, driven over its stream-json interface. This is a
|
|
34
|
+
// different access implementation from the SDK bridge below: different
|
|
35
|
+
// executable, different startup, different authentication surface and a
|
|
36
|
+
// different set of settings Yui can express. Neither one's configuration
|
|
37
|
+
// may be assumed to work for the other.
|
|
38
|
+
Object.freeze({
|
|
39
|
+
id: "claude-code-cli",
|
|
40
|
+
label: "Claude Code CLI",
|
|
41
|
+
adapterId: "claude",
|
|
42
|
+
kind: "cli",
|
|
43
|
+
identified: true
|
|
44
|
+
}),
|
|
45
|
+
// The Claude Agent SDK reached through an ACP bridge process. It speaks the
|
|
46
|
+
// protocol Yui already implements, so it needs no product branch in the
|
|
47
|
+
// codec — only its own identity here, so an operator can see and select it.
|
|
48
|
+
Object.freeze({
|
|
49
|
+
id: "claude-agent-sdk",
|
|
50
|
+
label: "Claude Agent SDK (ACP)",
|
|
51
|
+
adapterId: "acp",
|
|
52
|
+
kind: "sdk",
|
|
53
|
+
identified: true,
|
|
54
|
+
// The bridge exposes Claude Code's own permission modes, where
|
|
55
|
+
// `bypassPermissions` is the documented mode that skips approval
|
|
56
|
+
// prompts. The bridge offers it only when its own preconditions hold, so
|
|
57
|
+
// its presence in a Session's option list is still checked rather than
|
|
58
|
+
// assumed.
|
|
59
|
+
bypassPermissionMode: "bypassPermissions"
|
|
60
|
+
}),
|
|
61
|
+
// Every other ACP Agent, and every binding made before components were
|
|
62
|
+
// recorded. Yui does not know which product answers, and a command string
|
|
63
|
+
// is not evidence: an executable named `claude-agent-acp` may be a wrapper,
|
|
64
|
+
// a shim or something else entirely. Guessing a product here would attach a
|
|
65
|
+
// confident label to an unverified fact, so the honest value is this one.
|
|
66
|
+
// It states no bypass mode for the same reason: not knowing the product
|
|
67
|
+
// means not knowing which of its modes, if any, grants that authority.
|
|
68
|
+
Object.freeze({
|
|
69
|
+
id: "unknown-acp-agent",
|
|
70
|
+
label: "ACP Agent (unidentified)",
|
|
71
|
+
adapterId: "acp",
|
|
72
|
+
kind: "unknown",
|
|
73
|
+
identified: false
|
|
74
|
+
})
|
|
75
|
+
]);
|
|
76
|
+
/**
|
|
77
|
+
* The component recorded when a connection plan is selected without naming one.
|
|
78
|
+
*
|
|
79
|
+
* A plan with a single possible component resolves to it. The ACP plan carries
|
|
80
|
+
* many products, so it resolves to the unidentified entry rather than to
|
|
81
|
+
* whichever product happens to be most common.
|
|
82
|
+
*/
|
|
83
|
+
const DEFAULT_COMPONENT_BY_ADAPTER = Object.freeze({
|
|
84
|
+
codex: "codex-cli",
|
|
85
|
+
claude: "claude-code-cli",
|
|
86
|
+
acp: "unknown-acp-agent"
|
|
87
|
+
});
|
|
88
|
+
export function supportedAgentExecutionComponentIds() {
|
|
89
|
+
return AGENT_EXECUTION_COMPONENT_CATALOG.map(({ id }) => id).sort();
|
|
90
|
+
}
|
|
91
|
+
export function isAgentExecutionComponentId(value) {
|
|
92
|
+
return AGENT_EXECUTION_COMPONENT_CATALOG.some(({ id }) => id === value);
|
|
93
|
+
}
|
|
94
|
+
export function agentExecutionComponent(componentId) {
|
|
95
|
+
const entry = AGENT_EXECUTION_COMPONENT_CATALOG.find(({ id }) => id === componentId);
|
|
96
|
+
if (entry === undefined) {
|
|
97
|
+
throw new Error(`Agent execution component is unsupported: ${componentId}.`);
|
|
98
|
+
}
|
|
99
|
+
return entry;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The component's display label, falling back to the raw id.
|
|
103
|
+
*
|
|
104
|
+
* As with adapters, a stored binding may name a component this build no longer
|
|
105
|
+
* ships; showing that id is more useful than hiding it.
|
|
106
|
+
*/
|
|
107
|
+
export function agentExecutionComponentLabel(componentId) {
|
|
108
|
+
return AGENT_EXECUTION_COMPONENT_CATALOG.find(({ id }) => id === componentId)?.label
|
|
109
|
+
?? componentId;
|
|
110
|
+
}
|
|
111
|
+
/** The connection plan a component is reached through. */
|
|
112
|
+
export function adapterIdForExecutionComponent(componentId) {
|
|
113
|
+
return agentExecutionComponent(componentId).adapterId;
|
|
114
|
+
}
|
|
115
|
+
/** Components reachable through one connection plan, in catalog order. */
|
|
116
|
+
export function executionComponentsForAdapter(adapterId) {
|
|
117
|
+
return AGENT_EXECUTION_COMPONENT_CATALOG.filter((entry) => entry.adapterId === adapterId);
|
|
118
|
+
}
|
|
119
|
+
export function defaultExecutionComponentForAdapter(adapterId) {
|
|
120
|
+
return DEFAULT_COMPONENT_BY_ADAPTER[adapterId];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The component to show for a record that was parsed rather than constructed.
|
|
124
|
+
*
|
|
125
|
+
* Display surfaces read values back over the wire, where neither field is
|
|
126
|
+
* guaranteed to be a value this build knows. Refusing to render is the wrong
|
|
127
|
+
* answer there, so this never throws: a recognised component wins, an absent
|
|
128
|
+
* one falls back to its plan's default, and anything unrecognised is shown
|
|
129
|
+
* verbatim rather than replaced with a guess.
|
|
130
|
+
*/
|
|
131
|
+
export function displayExecutionComponent(adapterId, componentId) {
|
|
132
|
+
if (componentId !== undefined)
|
|
133
|
+
return componentId;
|
|
134
|
+
return isAgentAdapterId(adapterId)
|
|
135
|
+
? defaultExecutionComponentForAdapter(adapterId)
|
|
136
|
+
: adapterId;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolve the component for a connection plan, given what the caller stated.
|
|
140
|
+
*
|
|
141
|
+
* An absent component is not an error: it means the caller named only the plan,
|
|
142
|
+
* which is how every binding made before this axis existed reads. It resolves
|
|
143
|
+
* to the plan's default, which for ACP is the unidentified entry — the value is
|
|
144
|
+
* never inferred from a command, an argument or an environment variable.
|
|
145
|
+
*/
|
|
146
|
+
export function resolveAgentExecutionComponent(adapterId, componentId) {
|
|
147
|
+
if (componentId === undefined)
|
|
148
|
+
return defaultExecutionComponentForAdapter(adapterId);
|
|
149
|
+
if (!isAgentExecutionComponentId(componentId)) {
|
|
150
|
+
throw new Error(`Agent execution component is unsupported: ${componentId}.`);
|
|
151
|
+
}
|
|
152
|
+
const expected = adapterIdForExecutionComponent(componentId);
|
|
153
|
+
if (expected !== adapterId) {
|
|
154
|
+
throw new Error(`Agent execution component ${componentId} is reached over the ${expected} `
|
|
155
|
+
+ `connection plan, not ${adapterId}.`);
|
|
156
|
+
}
|
|
157
|
+
return componentId;
|
|
158
|
+
}
|
|
@@ -56,14 +56,42 @@ export const AGENT_OPERATIONAL_ENVIRONMENT_NAMES = [
|
|
|
56
56
|
"REQUESTS_CA_BUNDLE",
|
|
57
57
|
"SSH_AUTH_SOCK"
|
|
58
58
|
];
|
|
59
|
+
/** Native account context. Credential values remain volatile and belong only
|
|
60
|
+
* to this adapter; they are never copied into Roles, Tasks or launch arguments.
|
|
61
|
+
* Do not inherit numeric credential FDs across unrelated processes. */
|
|
62
|
+
const CLAUDE_NATIVE_ENVIRONMENT_NAMES = [
|
|
63
|
+
"CLAUDE_CONFIG_DIR",
|
|
64
|
+
"ANTHROPIC_API_KEY",
|
|
65
|
+
"ANTHROPIC_BASE_URL",
|
|
66
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
67
|
+
"ANTHROPIC_CUSTOM_HEADERS",
|
|
68
|
+
"ANTHROPIC_PROFILE",
|
|
69
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
70
|
+
"ANTHROPIC_DEFAULT_OPUS_MODEL",
|
|
71
|
+
"ANTHROPIC_DEFAULT_SONNET_MODEL",
|
|
72
|
+
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
|
73
|
+
"CLAUDE_CODE_SUBAGENT_MODEL",
|
|
74
|
+
"CLAUDE_CODE_USE_BEDROCK",
|
|
75
|
+
"CLAUDE_CODE_USE_VERTEX",
|
|
76
|
+
"CLAUDE_CODE_USE_FOUNDRY",
|
|
77
|
+
"CLAUDE_CODE_USE_GATEWAY",
|
|
78
|
+
"CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST",
|
|
79
|
+
"CLAUDE_CODE_HOST_CREDS_FILE",
|
|
80
|
+
"CLAUDE_CODE_API_KEY_HELPER_TTL_MS",
|
|
81
|
+
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC",
|
|
82
|
+
"DISABLE_AUTOUPDATER"
|
|
83
|
+
];
|
|
59
84
|
export const NATIVE_AGENT_ENVIRONMENT_NAMES = [
|
|
60
|
-
"CODEX_HOME",
|
|
61
|
-
"CLAUDE_CONFIG_DIR"
|
|
85
|
+
"CODEX_HOME", ...CLAUDE_NATIVE_ENVIRONMENT_NAMES
|
|
62
86
|
];
|
|
63
87
|
export function nativeAgentEnvironmentNames(adapterId) {
|
|
64
88
|
switch (adapterId) {
|
|
65
89
|
case "codex": return ["CODEX_HOME"];
|
|
66
|
-
case "claude": return
|
|
90
|
+
case "claude": return CLAUDE_NATIVE_ENVIRONMENT_NAMES;
|
|
91
|
+
// ACP standardizes the protocol, not where a product keeps its
|
|
92
|
+
// configuration. Naming a variable here would be a product branch, so an
|
|
93
|
+
// ACP Agent that needs one declares it as an ordinary environment binding.
|
|
94
|
+
case "acp": return [];
|
|
67
95
|
}
|
|
68
96
|
}
|
|
69
97
|
export function selectEnvironment(source, names) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Environment values owned by Yui's managed runtime.
|
|
3
3
|
*
|
|
4
|
-
* These values carry control-plane, Task, workspace, or runtime
|
|
4
|
+
* These values carry control-plane, Task, workspace, or runtime identity. They
|
|
5
5
|
* are never user Agent environment bindings, and an ordinary repository test
|
|
6
6
|
* must not inherit them from the managed Session that launched the test
|
|
7
7
|
* command.
|
|
@@ -16,8 +16,7 @@ export const YUI_MANAGED_RUNTIME_ENVIRONMENT_NAMES = Object.freeze([
|
|
|
16
16
|
"YUI_ADAPTER_ID",
|
|
17
17
|
"YUI_DRIVER_ID",
|
|
18
18
|
"YUI_WORKSPACE",
|
|
19
|
-
"
|
|
20
|
-
"YUI_RUNTIME_GENERATION_ID",
|
|
19
|
+
"YUI_RUN_ID",
|
|
21
20
|
"YUI_NATIVE_SESSION_ROOT",
|
|
22
21
|
"YUI_NATIVE_SESSION_ID",
|
|
23
22
|
// Retired: Yui no longer publishes a frozen control-plane descriptor into a
|
|
@@ -31,6 +30,5 @@ export const YUI_MANAGED_RUNTIME_ENVIRONMENT_NAMES = Object.freeze([
|
|
|
31
30
|
"YUI_AGENT_BASE_ARGS",
|
|
32
31
|
"YUI_WRITABLE_PROJECT_IDS",
|
|
33
32
|
"YUI_CONTEXT_PROJECT_IDS",
|
|
34
|
-
"YUI_WORKSPACE_PROJECTS"
|
|
35
|
-
"YUI_JOB_CALLER_KEY"
|
|
33
|
+
"YUI_WORKSPACE_PROJECTS"
|
|
36
34
|
]);
|