@zq-silk/yui 0.15.11 → 0.16.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 +11 -6
- package/ARCHITECTURE.zh-CN.md +8 -4
- package/README.md +13 -5
- package/dist/agentRun/agentRun.js +3 -0
- package/dist/artifacts/artifactCommitLock.js +16 -55
- package/dist/artifacts/taskArtifactRepository.js +3 -3
- package/dist/cli/agentConfigurationPicker.js +1 -1
- package/dist/cli/commandCatalog.js +92 -48
- package/dist/cli/completion.js +18 -18
- package/dist/cli/completionWizard.js +1 -1
- package/dist/cli/dynamicCompletion.js +1 -1
- package/dist/cli/interactionPolicy.js +11 -3
- package/dist/cli/invocationAuthority.js +64 -0
- package/dist/cli/managedDiagnostics.js +2 -2
- package/dist/cli/parseRepeatable.js +35 -0
- package/dist/cli/updatePorts.js +26 -5
- package/dist/cli.js +1303 -1235
- package/dist/commands/agentCommands.js +4 -4
- package/dist/commands/capabilityCommands.js +1 -1
- package/dist/commands/configCommands.js +6 -57
- package/dist/commands/configOverview.js +2 -2
- package/dist/commands/durableJobCommands.js +12 -6
- package/dist/commands/executionAuditCommands.js +10 -0
- package/dist/commands/globalRoleCommands.js +78 -29
- package/dist/commands/grantCommands.js +0 -3
- package/dist/commands/jobCommands.js +1 -4
- package/dist/commands/operatorCommands.js +3 -3
- package/dist/commands/projectCommands.js +45 -25
- package/dist/commands/resourcesCommands.js +10 -40
- package/dist/commands/roleConfiguration.js +2 -6
- package/dist/commands/taskActivationCommands.js +4 -8
- package/dist/commands/taskAgentCapabilities.js +9 -0
- package/dist/commands/taskCommandSupport.js +155 -0
- package/dist/commands/taskCommandTypes.js +1 -0
- package/dist/commands/taskCommands.js +355 -732
- package/dist/commands/taskCompletionGate.js +1 -1
- package/dist/commands/taskExecutionCommands.js +1 -1
- package/dist/commands/taskFactCommands.js +325 -0
- package/dist/commands/taskInputCommands.js +12 -42
- package/dist/commands/taskIntegrationCommands.js +20 -58
- package/dist/commands/taskNextActionCommand.js +7 -6
- package/dist/commands/taskPublicationAdoptCommand.js +127 -0
- package/dist/commands/taskPublicationCommands.js +12 -3
- package/dist/commands/taskPublicationVerifyCommand.js +24 -40
- package/dist/commands/taskRemoteDeliveryCommand.js +5 -86
- package/dist/commands/taskUpstreamCommands.js +19 -8
- package/dist/commands/workflowCommands.js +6 -1
- package/dist/completion/completionInstaller.js +26 -26
- package/dist/completion/completionState.js +26 -26
- package/dist/completion/fileCompletionManager.js +6 -11
- package/dist/config/configCatalog.js +0 -2
- package/dist/config/timeZone.js +14 -0
- package/dist/config/yuiConfig.js +0 -29
- package/dist/context/runContextPack.js +5 -3
- package/dist/context/taskCatalog.js +185 -0
- package/dist/context/taskContext.js +152 -151
- package/dist/context/wakeRunReferences.js +11 -0
- package/dist/controller/agentCapabilities.js +58 -0
- package/dist/controller/agentRuntimeObserver.js +6 -11
- package/dist/controller/clientRuntime.js +22 -14
- package/dist/controller/controller.js +20 -24
- package/dist/controller/fileSchedulerStoreAdapter.js +191 -225
- package/dist/controller/globalInputDelivery.js +13 -0
- package/dist/controller/jobClient.js +4 -4
- package/dist/controller/jobControl.js +60 -25
- package/dist/controller/jobSupervisor.js +4 -4
- package/dist/controller/providerRetryAdmission.js +100 -0
- package/dist/controller/providerRetryDelivery.js +218 -0
- package/dist/controller/runtime.js +85 -43
- package/dist/controller/runtimeEventProcessor.js +0 -5
- package/dist/controller/sessionOwnerReconciliation.js +5 -0
- package/dist/controller/taskAgentError.js +35 -0
- package/dist/coordination/workMailboxQueue.js +2 -24
- package/dist/core/controllerClient.js +2 -2
- package/dist/core/fileLockOwner.js +74 -0
- package/dist/decision/decision.js +17 -0
- package/dist/doctor/doctor.js +18 -9
- package/dist/event/taskEvent.js +12 -0
- package/dist/execution/workItemExecutionProjection.js +2 -2
- package/dist/executor/agentCapabilityConfig.js +43 -0
- package/dist/executor/agentConfigurationCatalog.js +49 -11
- package/dist/executor/agentExecutor.js +5 -8
- package/dist/executor/fileRoleLaunchPlanner.js +11 -53
- package/dist/executor/taskAgentCapabilities.js +64 -0
- package/dist/integration/deliveryObligation.js +1 -69
- package/dist/integration/gitIntegrationService.js +79 -90
- package/dist/integration/integrationAttempt.js +3 -14
- package/dist/integration/integrationSourceApplication.js +4 -12
- package/dist/integration/manifestTags.js +2 -2
- package/dist/job/durableJob.js +4 -25
- package/dist/job/jobAssignmentScope.js +22 -0
- package/dist/job/jobOperation.js +16 -0
- package/dist/job/jobRunner.js +2 -1
- package/dist/job/stepDirectory.js +15 -0
- package/dist/kernel/builtinCapabilities.js +15 -11
- package/dist/kernel/kernelPorts.js +1 -17
- package/dist/lifecycle/exactRunTerminalization.js +5 -10
- package/dist/message/globalProviderRetry.js +15 -0
- package/dist/message/inputControlResolution.js +3 -4
- package/dist/message/message.js +17 -20
- package/dist/message/messageContinuation.js +1 -1
- package/dist/milestone/milestone.js +11 -0
- package/dist/observability/executionAudit.js +19 -0
- package/dist/observability/orchestrationMetrics.js +24 -1
- package/dist/observability/runtimeIdentity.js +1 -17
- package/dist/output/agentConfigurationPresentation.js +2 -0
- package/dist/output/timePresentation.js +1 -14
- package/dist/plugins/pluginService.js +12 -4
- package/dist/release/releaseWorkflowPorts.js +45 -96
- package/dist/release/runtimeRelease.js +9 -15
- package/dist/repository/gitWorkspace.js +371 -105
- package/dist/repository/projectMaintenanceLock.js +98 -82
- package/dist/repository/taskBaseFreshness.js +1 -1
- package/dist/repository/taskWorkspaceCoordinator.js +82 -144
- package/dist/repository/taskWorkspacePreparer.js +113 -47
- package/dist/repository/workspaceCleanupInspection.js +187 -0
- package/dist/resources/autoResourceGc.js +4 -77
- package/dist/resources/liveReferences.js +7 -54
- package/dist/resources/resourceDiscovery.js +5 -118
- package/dist/resources/resourceGc.js +233 -181
- package/dist/resources/resourceRegistrar.js +5 -4
- package/dist/resources/resourceRegistry.js +3 -37
- package/dist/resources/resourceRegistryStore.js +13 -36
- package/dist/resources/sqliteResourceRegistry.js +43 -26
- package/dist/review/deltaRecheck.js +1 -1
- package/dist/review/reviewAcceptance.js +1 -1
- package/dist/review/reviewDecision.js +1 -1
- package/dist/review/reviewRound.js +8 -7
- package/dist/review/taskFinalReviewContractResolution.js +1 -1
- package/dist/runtime/acpProtocol.js +4 -51
- package/dist/runtime/acpSession.js +10 -75
- package/dist/runtime/acpSessionConfiguration.js +1 -8
- package/dist/runtime/agentEndpoint.js +3 -2
- package/dist/runtime/agentError.js +5 -3
- package/dist/runtime/agentFailureContext.js +43 -0
- package/dist/runtime/agentHost.js +42 -25
- package/dist/runtime/builtinAgentErrorMappers.js +91 -0
- package/dist/runtime/codexAppServerRuntime.js +34 -3
- package/dist/runtime/codexInteractiveHost.js +2 -2
- package/dist/runtime/index.js +0 -1
- package/dist/runtime/managedCaller.js +21 -1
- package/dist/runtime/providerControl.js +5 -1
- package/dist/runtime/providerErrors.js +38 -0
- package/dist/runtime/providerRetry.js +198 -0
- package/dist/runtime/providerRuntimeIdentity.js +28 -2
- package/dist/runtime/runtimeObservation.js +0 -5
- package/dist/runtime/runtimeSessionCandidate.js +2 -3
- package/dist/runtime/sessionOwnerIdentity.js +1 -1
- package/dist/runtime/sessionTokenMetrics.js +15 -5
- package/dist/runtime/structuredProviderHost.js +10 -43
- package/dist/runtime/taskUsageMetrics.js +275 -0
- package/dist/runtime/tmuxAdapters.js +6 -8
- package/dist/scheduler/activeRoleRunDelivery.js +19 -7
- package/dist/scheduler/leaderWakeupProcessor.js +24 -6
- package/dist/scheduler/operatorEvent.js +12 -20
- package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
- package/dist/scheduler/ports.js +5 -8
- package/dist/scheduler/roleRunLiveness.js +4 -4
- package/dist/scheduler/roleRunStall.js +16 -23
- package/dist/scheduler/taskExecutionProjection.js +49 -36
- package/dist/scheduler/taskObservabilityProjection.js +6 -45
- package/dist/scheduler/taskWake.js +5 -10
- package/dist/scheduler/wakeReason.js +2 -0
- package/dist/scheduler/wakeupQueue.js +2 -4
- package/dist/setup/setupCommand.js +1 -1
- package/dist/storage/contextRecords.js +106 -0
- package/dist/storage/currentTaskStore.js +1 -1
- package/dist/storage/homeLayout.js +13 -17
- package/dist/storage/migrations/agentFailureContext.js +22 -0
- package/dist/storage/migrations/currentInputContract.js +86 -0
- package/dist/storage/migrations/currentRuntimeContract.js +228 -0
- package/dist/storage/migrations/historicalVerificationPlan.js +35 -0
- package/dist/storage/migrations/integrationContinuation.js +5 -4
- package/dist/storage/migrations/narrowAgentFailureContext.js +65 -0
- package/dist/storage/migrations/notificationOnlyWakes.js +74 -0
- package/dist/storage/migrations/verificationPlanV1.js +162 -0
- package/dist/storage/migrations/verificationPolicy.js +74 -0
- package/dist/storage/migrations/workItemHistory.js +46 -0
- package/dist/storage/persistenceWorker.js +12 -4
- package/dist/storage/recordValidation.js +87 -0
- package/dist/storage/sqliteSchema.js +173 -1
- package/dist/storage/sqliteStore.js +172 -161
- package/dist/storage/storageSchema.js +2 -14
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +16 -7
- package/dist/storage/taskCatalog.js +123 -0
- package/dist/storage/taskStore.js +5 -7
- package/dist/storage/upgrade/upgradeOrchestrator.js +25 -37
- package/dist/task/archiveDiagnostics.js +1 -0
- package/dist/task/archivePreflight.js +124 -0
- package/dist/task/completionReadiness.js +5 -24
- package/dist/task/draftPlan.js +0 -53
- package/dist/task/nextAction.js +7 -13
- package/dist/task/publicationAdoption.js +56 -0
- package/dist/task/publicationReference.js +10 -0
- package/dist/task/remoteDelivery.js +31 -16
- package/dist/task/remoteDeliveryService.js +89 -0
- package/dist/task/taskActivation.js +2 -25
- package/dist/task/taskActivationService.js +0 -2
- package/dist/task/taskRecordReference.js +0 -1
- package/dist/task/taskSubmission.js +3 -14
- package/dist/telemetry/sqliteTelemetryBatch.js +29 -0
- package/dist/telemetry/sqliteTelemetryStore.js +49 -49
- package/dist/telemetry/telemetryWiring.js +4 -3
- package/dist/tmux/tmuxManager.js +29 -20
- package/dist/verification/gateArtifact.js +15 -24
- package/dist/verification/gateArtifactStore.js +14 -7
- package/dist/verification/verificationGateService.js +29 -88
- package/dist/verification/verificationPlan.js +27 -72
- package/dist/web/assets/client/app.js +92 -17
- package/dist/web/assets/client/components.js +55 -13
- package/dist/web/assets/client/i18n.js +72 -4
- package/dist/web/assets/client/taskSurface.js +6 -5
- package/dist/web/assets/client/view.js +35 -7
- package/dist/web/assets/shell.js +6 -0
- package/dist/web/assets/styles/layout.js +7 -0
- package/dist/web/webServer.js +12 -3
- package/dist/web/webSnapshot.js +14 -85
- package/dist/web/webTaskSurface.js +17 -46
- package/dist/workItem/workItem.js +1 -12
- package/dist/workspace/cleanupInspection.js +63 -0
- package/dist/workspace/workItemChangeSetManager.js +110 -50
- package/docs/agent-result-consumption.md +4 -0
- package/docs/agent-result-consumption.zh-CN.md +3 -0
- package/docs/agent-runtime-drivers.md +7 -0
- package/docs/agent-runtime-drivers.zh-CN.md +5 -0
- package/docs/architecture/README.md +2 -0
- package/docs/architecture/README.zh-CN.md +3 -1
- package/docs/architecture/capabilities-and-resources.md +42 -5
- package/docs/architecture/capabilities-and-resources.zh-CN.md +33 -3
- package/docs/managed-turn-and-session-runtime.md +121 -1
- package/docs/managed-turn-and-session-runtime.zh-CN.md +96 -2
- package/docs/observability/README.md +62 -0
- package/docs/observability/README.zh-CN.md +47 -0
- package/docs/plugin-sdk.md +4 -2
- package/docs/project-refresh.md +77 -0
- package/docs/project-refresh.zh-CN.md +59 -0
- package/docs/provider-retry.md +70 -0
- package/docs/provider-runtime.md +3 -1
- package/docs/provider-runtime.zh-CN.md +4 -2
- package/docs/release-workflow.md +190 -7
- package/docs/release-workflow.zh-CN.md +139 -5
- package/docs/roles-and-configuration.md +29 -0
- package/docs/roles-and-configuration.zh-CN.md +21 -0
- package/docs/sqlite-control-plane-design.md +16 -3
- package/docs/sqlite-control-plane-design.zh-CN.md +13 -2
- package/docs/task-dag-semantics.md +3 -3
- package/docs/task-dag-semantics.zh-CN.md +2 -2
- package/docs/task-delivery.md +223 -17
- package/docs/task-delivery.zh-CN.md +171 -14
- package/docs/task-discovery.md +101 -0
- package/docs/task-discovery.zh-CN.md +85 -0
- package/docs/testing/verification-levels.md +161 -9
- package/docs/testing/verification-levels.zh-CN.md +116 -9
- package/i18n/README.zh-CN.md +13 -7
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +5 -0
- package/skills/yui-leader/references/execution.md +3 -2
- package/skills/yui-leader/references/integration.md +9 -5
- package/skills/yui-leader/references/planning.md +9 -3
- package/skills/yui-operator/SKILL.md +24 -8
- package/skills/yui-reviewer/SKILL.md +4 -0
- package/skills/yui-runtime/SKILL.md +17 -2
- package/skills/yui-runtime/references/publication.md +26 -4
- package/skills/yui-runtime/references/recovery.md +71 -0
- package/dist/agent/agentRegistry.js +0 -10
- package/dist/agentRun/runIdentity.js +0 -22
- package/dist/commands/deliveryGuardPreflight.js +0 -30
- package/dist/commands/taskIntegrationQueueCommands.js +0 -226
- package/dist/commands/taskOverviewCommand.js +0 -376
- package/dist/completion/completionWizard.js +0 -125
- package/dist/context/dispatchContext.js +0 -110
- package/dist/context/wakeNotification.js +0 -144
- package/dist/integration/integrationCheckEvidenceReuse.js +0 -53
- package/dist/integration/integrationQueueEntry.js +0 -191
- package/dist/integration/integrationQueueService.js +0 -810
- package/dist/release/fakeReleasePorts.js +0 -55
- package/dist/runtime/sessionOwnerRegistry.js +0 -137
- package/dist/task/deliveryGuard.js +0 -226
- /package/dist/{commands/taskActor.js → task/taskAuthority.js} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
|
-
import { agentNotFound, usageError } from "../errors/cliError.js";
|
|
3
|
-
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
4
2
|
import { isAgentAdapterId, supportedAgentAdapterIds } from "../agent/adapterCatalog.js";
|
|
5
|
-
import { adapterIdForExecutionComponent, agentExecutionComponentLabel, defaultExecutionComponentForAdapter, isAgentExecutionComponentId, supportedAgentExecutionComponentIds } from "../agent/executionComponents.js";
|
|
6
3
|
import { createConfiguredAgent, validateConfiguredAgent } from "../agent/agent.js";
|
|
7
|
-
import {
|
|
4
|
+
import { adapterIdForExecutionComponent, agentExecutionComponentLabel, defaultExecutionComponentForAdapter, isAgentExecutionComponentId, supportedAgentExecutionComponentIds } from "../agent/executionComponents.js";
|
|
5
|
+
import { agentNotFound, usageError } from "../errors/cliError.js";
|
|
6
|
+
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
8
7
|
import { hasRuntimeLifecycleWork, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
|
|
8
|
+
import { LIVE_SESSION_ACKNOWLEDGEMENT_OPTION } from "./roleRuntimeGuard.js";
|
|
9
9
|
export function runAgentCommand(args, store) {
|
|
10
10
|
const [command, ...rest] = args;
|
|
11
11
|
switch (command) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { usageError } from "../errors/cliError.js";
|
|
2
|
-
import { resolveJobCaller } from "
|
|
2
|
+
import { resolveJobCaller } from "../task/taskAuthority.js";
|
|
3
3
|
import { callFileTaskController } from "../controller/clientRuntime.js";
|
|
4
4
|
export async function runCapabilityCommand(args, home, environment) {
|
|
5
5
|
const [action, ...rest] = args;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { mkdirSync, realpathSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
|
-
import { usageError } from "../errors/cliError.js";
|
|
4
|
-
import { DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_LEADER_NEXT_ACTION_MODE, DEFAULT_LEADER_SEMANTIC_BUDGET_RUNS, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, LEADER_NEXT_ACTION_MODES, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetRuns, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
|
|
5
3
|
import { CONFIG_DEFINITIONS, CONFIG_KEYS, configDefinition, configDefinitionsForDomain } from "../config/configCatalog.js";
|
|
6
|
-
import { resolveTimeZone } from "../
|
|
4
|
+
import { resolveTimeZone } from "../config/timeZone.js";
|
|
5
|
+
import { DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
|
|
6
|
+
import { usageError } from "../errors/cliError.js";
|
|
7
7
|
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
8
8
|
import { REVIEW_TRIGGERS } from "../review/reviewConfig.js";
|
|
9
9
|
/**
|
|
10
10
|
* One uniform key model for every durable setting. Each catalog domain uses
|
|
11
|
-
* the same show/set/clear contract
|
|
12
|
-
* `leader-next-action` are keys like any other.
|
|
11
|
+
* the same show/set/clear contract, including the explicit review policy.
|
|
13
12
|
*/
|
|
14
13
|
export { CONFIG_KEYS } from "../config/configCatalog.js";
|
|
15
14
|
const CONFIG_PROPERTIES = Object.fromEntries(CONFIG_DEFINITIONS.map(({ key, property }) => [
|
|
@@ -20,7 +19,6 @@ const TIME_ZONE_SET_USAGE = "System config set usage: yui config system set time
|
|
|
20
19
|
const RECONCILIATION_SET_USAGE = "Runtime config set usage: yui config runtime set reconciliation-interval-seconds <5-300>.";
|
|
21
20
|
const RESOURCES_GC_MODE_SET_USAGE = "Resources config set usage: yui config resources set resources-gc-mode <report|quarantine>.";
|
|
22
21
|
const RESOURCES_GC_AUTO_QUARANTINE_SET_USAGE = "Resources config set usage: yui config resources set resources-gc-auto-quarantine <true|false>.";
|
|
23
|
-
const LEADER_NEXT_ACTION_SET_USAGE = `Workflow config set usage: yui config workflow set leader-next-action <${LEADER_NEXT_ACTION_MODES.join("|")}>.`;
|
|
24
22
|
const REVIEW_SET_USAGE = "Workflow config set usage: yui config workflow set review --role <global-role> --trigger <always|leader|final>.";
|
|
25
23
|
export function runConfigCommand(domain, args, store) {
|
|
26
24
|
const keys = configDefinitionsForDomain(domain).map(({ key }) => key);
|
|
@@ -65,7 +63,6 @@ export function effectiveConfigData(config, domain) {
|
|
|
65
63
|
lastTaskId: config.lastTaskId ?? null,
|
|
66
64
|
reconciliationIntervalSeconds: config.reconciliationIntervalSeconds
|
|
67
65
|
?? DEFAULT_RECONCILIATION_INTERVAL_SECONDS,
|
|
68
|
-
leaderNextActionMode: resolveLeaderNextActionMode(config.leaderNextActionMode),
|
|
69
66
|
resourcesGcMode: resolveResourcesGcMode(config.resourcesGcMode),
|
|
70
67
|
resourcesGcAutoQuarantine: resolveResourcesGcAutoQuarantine(config.resourcesGcAutoQuarantine),
|
|
71
68
|
resourcesQuarantineTtlHours: resolveResourcesQuarantineTtlHours(config.resourcesQuarantineTtlHours),
|
|
@@ -77,7 +74,6 @@ export function effectiveConfigData(config, domain) {
|
|
|
77
74
|
controllerTaskConcurrency: resolveControllerTaskConcurrency(config.controllerTaskConcurrency),
|
|
78
75
|
agentLaunchInactivityTimeoutSeconds: resolveAgentLaunchInactivityTimeoutSeconds(config.agentLaunchInactivityTimeoutSeconds),
|
|
79
76
|
deliveryTimeoutSeconds: resolveDeliveryTimeoutSeconds(config.deliveryTimeoutSeconds),
|
|
80
|
-
leaderSemanticBudgetRuns: resolveLeaderSemanticBudgetRuns(config.leaderSemanticBudgetRuns),
|
|
81
77
|
tmuxBin: resolveTmuxBin(config.tmuxBin),
|
|
82
78
|
tmuxHistoryLimit: resolveTmuxHistoryLimit(config.tmuxHistoryLimit),
|
|
83
79
|
telemetryEnabled: resolveTelemetryEnabled(config.telemetryEnabled),
|
|
@@ -164,7 +160,7 @@ const CONFIG_KEY_HANDLERS = [
|
|
|
164
160
|
throw usageError("System config set usage: yui config system set default-agent <agent-id>.");
|
|
165
161
|
}
|
|
166
162
|
const defaultAgent = args[0].trim();
|
|
167
|
-
if (store.getConfiguredAgent
|
|
163
|
+
if (store.getConfiguredAgent(defaultAgent) === null) {
|
|
168
164
|
throw usageError(`Configured Agent not found: ${defaultAgent}.`);
|
|
169
165
|
}
|
|
170
166
|
saveConfigKey(store, (config) => ({ ...config, defaultAgent }));
|
|
@@ -237,51 +233,6 @@ const CONFIG_KEY_HANDLERS = [
|
|
|
237
233
|
return `Reconciliation interval reset to ${DEFAULT_RECONCILIATION_INTERVAL_SECONDS} seconds\n`;
|
|
238
234
|
}
|
|
239
235
|
},
|
|
240
|
-
{
|
|
241
|
-
key: "leader-next-action",
|
|
242
|
-
showLabel: "Leader next-action mode",
|
|
243
|
-
showValue: (config) => resolveLeaderNextActionMode(config.leaderNextActionMode),
|
|
244
|
-
set(args, store) {
|
|
245
|
-
if (args.length !== 1)
|
|
246
|
-
throw usageError(LEADER_NEXT_ACTION_SET_USAGE);
|
|
247
|
-
let mode;
|
|
248
|
-
try {
|
|
249
|
-
mode = resolveLeaderNextActionMode(args[0]);
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
throw usageError(error instanceof Error ? error.message : String(error), LEADER_NEXT_ACTION_SET_USAGE);
|
|
253
|
-
}
|
|
254
|
-
saveConfigKey(store, (config) => ({ ...config, leaderNextActionMode: mode }));
|
|
255
|
-
return `Leader next-action mode set to ${mode}\n`;
|
|
256
|
-
},
|
|
257
|
-
clear(store) {
|
|
258
|
-
saveConfigKey(store, (config) => {
|
|
259
|
-
const { leaderNextActionMode: _removed, ...rest } = config;
|
|
260
|
-
return rest;
|
|
261
|
-
});
|
|
262
|
-
return `Leader next-action mode reset to ${DEFAULT_LEADER_NEXT_ACTION_MODE}\n`;
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
key: "leader-semantic-budget-runs",
|
|
267
|
-
showLabel: "Leader semantic budget",
|
|
268
|
-
showValue: (config) => `${resolveLeaderSemanticBudgetRuns(config.leaderSemanticBudgetRuns)} runs`,
|
|
269
|
-
set(args, store) {
|
|
270
|
-
const usage = "Workflow config set usage: yui config workflow set leader-semantic-budget-runs <1-20>.";
|
|
271
|
-
if (args.length !== 1)
|
|
272
|
-
throw usageError(usage);
|
|
273
|
-
const leaderSemanticBudgetRuns = validatedConfigValue(() => resolveLeaderSemanticBudgetRuns(Number(args[0])), usage);
|
|
274
|
-
saveConfigKey(store, (config) => ({ ...config, leaderSemanticBudgetRuns }));
|
|
275
|
-
return `Leader semantic budget set to ${leaderSemanticBudgetRuns} runs\n`;
|
|
276
|
-
},
|
|
277
|
-
clear(store) {
|
|
278
|
-
saveConfigKey(store, (config) => {
|
|
279
|
-
const { leaderSemanticBudgetRuns: _removed, ...rest } = config;
|
|
280
|
-
return rest;
|
|
281
|
-
});
|
|
282
|
-
return `Leader semantic budget reset to ${DEFAULT_LEADER_SEMANTIC_BUDGET_RUNS} runs\n`;
|
|
283
|
-
}
|
|
284
|
-
},
|
|
285
236
|
{
|
|
286
237
|
key: "resources-gc-mode",
|
|
287
238
|
showLabel: "Resources GC mode",
|
|
@@ -565,7 +516,7 @@ const CONFIG_KEY_HANDLERS = [
|
|
|
565
516
|
|| !REVIEW_TRIGGERS.includes(rawTrigger)) {
|
|
566
517
|
throw usageError(REVIEW_SET_USAGE);
|
|
567
518
|
}
|
|
568
|
-
if (store.getGlobalRole
|
|
519
|
+
if (store.getGlobalRole(roleName) === null) {
|
|
569
520
|
throw usageError(`Global Role not found: ${roleName}.`);
|
|
570
521
|
}
|
|
571
522
|
const trigger = rawTrigger;
|
|
@@ -598,8 +549,6 @@ if (missingConfigHandlers.length > 0 || duplicateConfigHandlers.length > 0) {
|
|
|
598
549
|
}
|
|
599
550
|
function resolveDefaultWorkspace(value, store) {
|
|
600
551
|
const requested = resolve(value);
|
|
601
|
-
if (store.rootDirectory === undefined)
|
|
602
|
-
return requested;
|
|
603
552
|
const requestedHome = resolve(store.rootDirectory());
|
|
604
553
|
assertWorkspaceOutsideHome(requested, requestedHome);
|
|
605
554
|
mkdirSync(requested, { recursive: true, mode: 0o700 });
|
|
@@ -12,7 +12,7 @@ import { CONFIG_DOMAINS } from "../config/configCatalog.js";
|
|
|
12
12
|
* therefore explain what the user sees without reconstructing configuration
|
|
13
13
|
* from help text or implementation defaults.
|
|
14
14
|
*/
|
|
15
|
-
export function runConfigOverview(args, store, environment,
|
|
15
|
+
export function runConfigOverview(args, store, environment, roleOptions) {
|
|
16
16
|
if (args.length !== 0)
|
|
17
17
|
throw usageError("Config show usage: yui config show.");
|
|
18
18
|
const domains = Object.fromEntries(CONFIG_DOMAINS.map((domain) => [
|
|
@@ -27,7 +27,7 @@ export function runConfigOverview(args, store, environment, identity, roleOption
|
|
|
27
27
|
]));
|
|
28
28
|
const profileResult = runProfileCommand(["list"], store);
|
|
29
29
|
const profiles = profileResult.data.profiles;
|
|
30
|
-
const completion = inspectCompletionStates(store.getConfig(), environment
|
|
30
|
+
const completion = inspectCompletionStates(store.getConfig(), environment);
|
|
31
31
|
const roleOutput = runGlobalRoleCommand(["list"], store, roleOptions);
|
|
32
32
|
if (typeof roleOutput !== "string") {
|
|
33
33
|
throw new Error("Config overview received an invalid Role control result.");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { usageError } from "../errors/cliError.js";
|
|
2
2
|
import { ensureFileTaskController } from "../controller/clientRuntime.js";
|
|
3
3
|
import { acknowledgeDurableJob, cancelDurableJob, getDurableJob, startDurableJob } from "../controller/jobClient.js";
|
|
4
|
-
import { resolveJobCaller, taskLocalActor } from "
|
|
4
|
+
import { resolveJobCaller, taskLocalActor } from "../task/taskAuthority.js";
|
|
5
5
|
/**
|
|
6
6
|
* The textual `--owner` forms accepted by `job start`. The public help text in
|
|
7
7
|
* the command catalog must document exactly these forms.
|
|
@@ -25,7 +25,7 @@ export async function runDurableJobCommand(args, options) {
|
|
|
25
25
|
throw usageError(command === undefined
|
|
26
26
|
? "Job command is required: start, get, cancel, or acknowledge."
|
|
27
27
|
: `Unknown command: job ${command}`, "yui job start --task <id> --project <project> --head <sha> --workspace <dir> "
|
|
28
|
-
+ "--step <name>=<command> [--step ...] [--env K=V ...] "
|
|
28
|
+
+ "--request-id <id> --step <name>=<command> [--step ...] [--env K=V ...] "
|
|
29
29
|
+ `[--owner ${JOB_OWNER_USAGE}] [--retry-of <job-id>]\n`
|
|
30
30
|
+ "yui job get --task <id> --job <job-id>\n"
|
|
31
31
|
+ "yui job cancel --task <id> --job <job-id>\n"
|
|
@@ -36,6 +36,7 @@ async function startJob(args, options) {
|
|
|
36
36
|
await ensureFileTaskController(options.home, { environment: options.environment });
|
|
37
37
|
const caller = resolveJobCaller(options.environment, parsed.taskId);
|
|
38
38
|
const params = {
|
|
39
|
+
requestId: parsed.requestId,
|
|
39
40
|
taskId: parsed.taskId,
|
|
40
41
|
owner: parsed.owner,
|
|
41
42
|
projectId: parsed.projectId,
|
|
@@ -54,8 +55,9 @@ async function startJob(args, options) {
|
|
|
54
55
|
}
|
|
55
56
|
async function getJob(args, options) {
|
|
56
57
|
const ref = parseRefArgs(args, "get");
|
|
58
|
+
const caller = resolveJobCaller(options.environment, ref.taskId);
|
|
57
59
|
await ensureFileTaskController(options.home, { environment: options.environment });
|
|
58
|
-
const job = await getDurableJob(options.home, ref.taskId, ref.jobId);
|
|
60
|
+
const job = await getDurableJob(options.home, ref.taskId, ref.jobId, caller);
|
|
59
61
|
if (options.json === true)
|
|
60
62
|
return `${JSON.stringify(job, null, 2)}\n`;
|
|
61
63
|
const lines = [
|
|
@@ -111,6 +113,7 @@ async function acknowledgeJob(args, options) {
|
|
|
111
113
|
}
|
|
112
114
|
function parseStartArgs(args) {
|
|
113
115
|
let taskId;
|
|
116
|
+
let requestId;
|
|
114
117
|
let projectId;
|
|
115
118
|
let head;
|
|
116
119
|
let workspace;
|
|
@@ -129,6 +132,9 @@ function parseStartArgs(args) {
|
|
|
129
132
|
case "--task":
|
|
130
133
|
taskId = value;
|
|
131
134
|
break;
|
|
135
|
+
case "--request-id":
|
|
136
|
+
requestId = value;
|
|
137
|
+
break;
|
|
132
138
|
case "--project":
|
|
133
139
|
projectId = value;
|
|
134
140
|
break;
|
|
@@ -165,10 +171,10 @@ function parseStartArgs(args) {
|
|
|
165
171
|
}
|
|
166
172
|
}
|
|
167
173
|
if (taskId === undefined || projectId === undefined || head === undefined
|
|
168
|
-
|| workspace === undefined || steps.length === 0) {
|
|
169
|
-
throw usageError("job start requires --task, --project, --head, --workspace, and at least one --step.", "yui job start ...");
|
|
174
|
+
|| workspace === undefined || requestId === undefined || requestId.trim().length === 0 || steps.length === 0) {
|
|
175
|
+
throw usageError("job start requires --request-id, --task, --project, --head, --workspace, and at least one --step.", "yui job start ...");
|
|
170
176
|
}
|
|
171
|
-
return { taskId, owner, projectId, head, workspace, env, steps, retryOf };
|
|
177
|
+
return { taskId, requestId, owner, projectId, head, workspace, env, steps, retryOf };
|
|
172
178
|
}
|
|
173
179
|
export function parseJobOwner(value) {
|
|
174
180
|
if (value === "task")
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { usageError } from "../errors/cliError.js";
|
|
9
9
|
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
10
|
+
import { formatUsageMetric } from "../runtime/taskUsageMetrics.js";
|
|
10
11
|
import { runExecutionAudit } from "../observability/executionAudit.js";
|
|
11
12
|
export function parseExecutionAuditOptions(args) {
|
|
12
13
|
const options = {};
|
|
@@ -246,6 +247,15 @@ export function renderExecutionAudit(report, width = defaultTableWidth()) {
|
|
|
246
247
|
else {
|
|
247
248
|
lines.push("", ...sectionError("orchestration", report));
|
|
248
249
|
}
|
|
250
|
+
if (report.usage.status === "ok" && report.usage.data !== undefined) {
|
|
251
|
+
lines.push("", "Observed usage — Task lifetime, observed sources only (audit time window not applied):");
|
|
252
|
+
for (const usage of report.usage.data) {
|
|
253
|
+
lines.push(` ${usage.taskId}: tokens=${formatUsageMetric(usage.tokens)}; tools=${formatUsageMetric(usage.toolCalls)}; elapsed=${formatUsageMetric(usage.elapsedSeconds, "s")}; native execution sum=${formatUsageMetric(usage.executionSeconds, "s")}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
lines.push("", ...sectionError("usage", report));
|
|
258
|
+
}
|
|
249
259
|
if (report.storage.status === "ok" && report.storage.data !== undefined) {
|
|
250
260
|
const storage = report.storage.data;
|
|
251
261
|
lines.push("", `Storage: backend ${storage.backend} · state.json ${formatBytes(storage.stateJsonBytes)} · yui.db ${formatBytes(storage.databaseBytes)}`
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { roleNotFound, usageError } from "../errors/cliError.js";
|
|
2
|
+
import { controlProviderRetry, providerRetryProjection, renderProviderRetry } from "../runtime/providerRetry.js";
|
|
3
|
+
import { settleGlobalRetryInput } from "../message/globalProviderRetry.js";
|
|
2
4
|
import { createRoleSessionSet, recordRoleAgentSession } from "../executor/agentExecutor.js";
|
|
3
5
|
import { resolveEffectiveLaunch } from "../executor/effectiveLaunch.js";
|
|
4
6
|
import { managedGlobalRoleWorkspace } from "../storage/homeLayout.js";
|
|
@@ -12,30 +14,41 @@ import { isSystemRoleName, SYSTEM_ROLE_NAMES, systemRoleDescription } from "../r
|
|
|
12
14
|
import { hasAgentConfigOptions, hasNoRoleMutation, parseRoleOptions, patchRoleAgentBinding, roleOptionSpecs, roleProfileFrom, roleProfilePatch } from "./roleConfiguration.js";
|
|
13
15
|
import { hasRoleLaunchContextOptions, validateConfiguredRoleSkills } from "./roleSkillValidation.js";
|
|
14
16
|
import { assertLiveRoleSessionAcknowledged, assertRoleRuntimeMutationAllowed, LIVE_SESSION_ACKNOWLEDGEMENT_OPTION } from "./roleRuntimeGuard.js";
|
|
15
|
-
export function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
export function applyGlobalInputControl(name, input, store, options = {}) {
|
|
18
|
+
assertGlobalInputAuthority(store, options, name);
|
|
19
|
+
return input.action === "interrupt"
|
|
20
|
+
? interruptGlobalInput(name, input, store)
|
|
21
|
+
: messageGlobalInput(name, input, store, options);
|
|
22
|
+
}
|
|
23
|
+
function inputOutput(output, data) {
|
|
24
|
+
return { kind: "output", output, data };
|
|
25
|
+
}
|
|
26
|
+
function renderGlobalInput(result, options) {
|
|
27
|
+
return result.kind === "output" ? jsonOrText(options, result.output, result.data) : result;
|
|
28
|
+
}
|
|
29
|
+
function assertGlobalInputAuthority(store, options, target) {
|
|
30
|
+
const env = options.env ?? process.env;
|
|
31
|
+
if (env.YUI_SESSION_SCOPE !== undefined && env.YUI_SESSION_SCOPE !== "global"
|
|
32
|
+
|| env.YUI_SESSION_SCOPE === "global" && env.YUI_ROLE !== "operator" && env.YUI_ROLE !== target) {
|
|
33
|
+
throw usageError("Global input mutation is outside the exact Session authority.");
|
|
34
|
+
}
|
|
35
|
+
if (env.YUI_SESSION_SCOPE === "global") {
|
|
36
|
+
const caller = store.getGlobalRoleSessionSet(env.YUI_ROLE ?? "");
|
|
37
|
+
const session = caller?.sessions[caller.activeAgentId];
|
|
38
|
+
if (session === undefined || session.status !== "active" || env.YUI_AGENT_ID !== session.agentId
|
|
39
|
+
|| env.YUI_ADAPTER_ID !== session.adapterId
|
|
40
|
+
|| (env.CODEX_THREAD_ID ?? env.YUI_NATIVE_SESSION_ID) !== session.nativeSessionId) {
|
|
41
|
+
throw usageError("Global input mutation requires the current native caller Session.");
|
|
37
42
|
}
|
|
38
43
|
}
|
|
44
|
+
else if (env.YUI_ROLE !== undefined || env.YUI_AGENT_ID !== undefined || env.YUI_NATIVE_SESSION_ID !== undefined) {
|
|
45
|
+
throw usageError("Incomplete managed identity cannot acquire user authority.");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function runGlobalRoleCommand(args, store, options = {}) {
|
|
49
|
+
const [command, ...rest] = args;
|
|
50
|
+
if (command === "session" && rest[0] === "retry")
|
|
51
|
+
assertGlobalInputAuthority(store, options, rest[1]);
|
|
39
52
|
switch (command) {
|
|
40
53
|
case "add": return addRole(rest, store, options);
|
|
41
54
|
case "list": return listRoles(rest, store);
|
|
@@ -126,6 +139,7 @@ function roleContext(args, store, options) {
|
|
|
126
139
|
pendingMessages: pendingQueue,
|
|
127
140
|
messages: store.listGlobalRoleMessages(name),
|
|
128
141
|
nativeTurn: sessions?.providerBinding?.run ?? null,
|
|
142
|
+
retry: providerRetryProjection(sessions?.providerBinding),
|
|
129
143
|
interrupts: sessions?.interrupts ?? {},
|
|
130
144
|
sessionManifestPath: environment.YUI_SESSION_MANIFEST,
|
|
131
145
|
cliCommand: "yui"
|
|
@@ -382,6 +396,28 @@ function enterRole(args, store) {
|
|
|
382
396
|
}
|
|
383
397
|
function roleSession(args, store, options) {
|
|
384
398
|
const [command, rawName, ...tail] = args;
|
|
399
|
+
if (command === "retry") {
|
|
400
|
+
const name = roleName(rawName);
|
|
401
|
+
const [action = "show", ...extra] = tail;
|
|
402
|
+
if (extra.length > 0 || !["show", "cancel", "disable", "enable"].includes(action)) {
|
|
403
|
+
throw usageError("Usage: yui session retry <role> [show|cancel|disable|enable]");
|
|
404
|
+
}
|
|
405
|
+
return store.transaction(tx => {
|
|
406
|
+
requireRole(name, tx);
|
|
407
|
+
const sessions = tx.getGlobalRoleSessionSet(name);
|
|
408
|
+
let binding = sessions?.providerBinding ?? null;
|
|
409
|
+
if (action !== "show") {
|
|
410
|
+
if (sessions === null || binding === null)
|
|
411
|
+
throw usageError("No current Provider Session.");
|
|
412
|
+
binding = controlProviderRetry(binding, action, Date.now());
|
|
413
|
+
tx.saveGlobalRoleSessionSet({ ...sessions, providerBinding: binding });
|
|
414
|
+
settleGlobalRetryInput(tx, name, binding, new Date());
|
|
415
|
+
}
|
|
416
|
+
return options.jsonOutput ? JSON.stringify({
|
|
417
|
+
roleName: name, retry: providerRetryProjection(binding), disabled: binding?.retryDisabled ?? false
|
|
418
|
+
}) + "\n" : renderProviderRetry(binding) + "\n";
|
|
419
|
+
});
|
|
420
|
+
}
|
|
385
421
|
if (command !== "record" && command !== "replace") {
|
|
386
422
|
throw usageError("Session usage: yui session record|replace <role> --native-id <id> [--reason <reason>].");
|
|
387
423
|
}
|
|
@@ -526,6 +562,13 @@ function globalRoleMessage(args, store, options) {
|
|
|
526
562
|
const expectedTarget = action === "steer"
|
|
527
563
|
? required(parsed.one("--expected-target"), "--expected-target")
|
|
528
564
|
: undefined;
|
|
565
|
+
return renderGlobalInput(applyGlobalInputControl(name, action === "steer"
|
|
566
|
+
? { action, body, requestId, expectedTarget: expectedTarget, to: name }
|
|
567
|
+
: { action, body, requestId }, store, options), options);
|
|
568
|
+
}
|
|
569
|
+
function messageGlobalInput(name, input, store, options) {
|
|
570
|
+
const { action, body, requestId } = input;
|
|
571
|
+
const expectedTarget = input.action === "steer" ? input.expectedTarget : undefined;
|
|
529
572
|
const now = new Date();
|
|
530
573
|
// The durable Global input is authored as an operator input: a Global Role has
|
|
531
574
|
// no Task Leader, and the operator is the human authority over Global Roles.
|
|
@@ -538,14 +581,14 @@ function globalRoleMessage(args, store, options) {
|
|
|
538
581
|
});
|
|
539
582
|
if (action === "queue") {
|
|
540
583
|
const state = persisted.idempotentReplay ? "idempotent-replay" : "queued";
|
|
541
|
-
return
|
|
584
|
+
return inputOutput(`Queued Global message ${persisted.message.id} to ${name} (${state}).\n`, { roleName: name, message: persisted.message, delivery: { state } });
|
|
542
585
|
}
|
|
543
586
|
if (persisted.idempotentReplay) {
|
|
544
|
-
return
|
|
587
|
+
return inputOutput(`Steer Global message ${persisted.message.id} already recorded (idempotent-replay).\n`, { roleName: name, message: persisted.message, steer: { state: "idempotent-replay" } });
|
|
545
588
|
}
|
|
546
589
|
const resolution = resolveGlobalInputControl(store, name, "steer", expectedTarget);
|
|
547
590
|
if (resolution.outcome !== "ready") {
|
|
548
|
-
return
|
|
591
|
+
return inputOutput(`Steer Global message ${persisted.message.id} saved but not delivered (${resolution.code}: ${resolution.detail}).\n`, { roleName: name, message: persisted.message,
|
|
549
592
|
steer: { state: "not-steered", code: resolution.code, detail: resolution.detail } });
|
|
550
593
|
}
|
|
551
594
|
store.updateGlobalRoleMessage({ ...persisted.message, control: {
|
|
@@ -571,7 +614,6 @@ function globalRoleMessage(args, store, options) {
|
|
|
571
614
|
* fourth action and not an auto-fallback (decision-3 §4).
|
|
572
615
|
*/
|
|
573
616
|
function globalRoleInterrupt(args, store, options) {
|
|
574
|
-
const usage = "Role interrupt usage: yui role interrupt <role> --expected-target <turn> [--then-message <global-message-id>] [--request-id <id>].";
|
|
575
617
|
const [rawName, ...tail] = args;
|
|
576
618
|
const name = roleName(rawName);
|
|
577
619
|
const parsed = parseOptions(tail, new Map([
|
|
@@ -582,12 +624,19 @@ function globalRoleInterrupt(args, store, options) {
|
|
|
582
624
|
const expectedTarget = required(parsed.one("--expected-target"), "--expected-target");
|
|
583
625
|
const thenMessageId = trimmed(parsed.one("--then-message"));
|
|
584
626
|
const requestId = trimmed(parsed.one("--request-id")) ?? `cancel:${encodeURIComponent(expectedTarget)}`;
|
|
627
|
+
return renderGlobalInput(applyGlobalInputControl(name, {
|
|
628
|
+
action: "interrupt", role: name, expectedTarget, thenMessage: thenMessageId, requestId
|
|
629
|
+
}, store, options), options);
|
|
630
|
+
}
|
|
631
|
+
function interruptGlobalInput(name, input, store) {
|
|
632
|
+
const { expectedTarget, thenMessage: thenMessageId } = input;
|
|
633
|
+
const requestId = input.requestId ?? `cancel:${encodeURIComponent(expectedTarget)}`;
|
|
585
634
|
const fingerprint = JSON.stringify({ expectedTarget, thenMessageId });
|
|
586
635
|
const prior = store.getGlobalRoleSessionSet(name)?.interrupts?.[requestId];
|
|
587
636
|
if (prior !== undefined) {
|
|
588
637
|
if (prior.fingerprint !== fingerprint)
|
|
589
638
|
throw usageError("Interrupt requestId already names another control.");
|
|
590
|
-
return
|
|
639
|
+
return inputOutput(`Interrupt ${requestId} already recorded; no native control repeated.\n`, { roleName: name, interrupt: prior.receipt ?? { state: "interrupt-unknown" }, idempotentReplay: true });
|
|
591
640
|
}
|
|
592
641
|
const resolved = store.transaction((tx) => {
|
|
593
642
|
requireRole(name, tx);
|
|
@@ -620,10 +669,10 @@ function globalRoleInterrupt(args, store, options) {
|
|
|
620
669
|
return resolution;
|
|
621
670
|
});
|
|
622
671
|
if (resolved.outcome === "then-conflict") {
|
|
623
|
-
return
|
|
672
|
+
return inputOutput(`Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
|
|
624
673
|
}
|
|
625
674
|
if (resolved.outcome !== "ready") {
|
|
626
|
-
return
|
|
675
|
+
return inputOutput(`Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
|
|
627
676
|
}
|
|
628
677
|
return {
|
|
629
678
|
kind: "input-interrupt",
|
|
@@ -286,9 +286,6 @@ function requireTask(store, taskId) {
|
|
|
286
286
|
function recordTaskEvent(store, taskId, type, payload, now) {
|
|
287
287
|
store.saveEvent(taskId, createTaskEvent(store.nextEventId(taskId), taskId, type, payload, now));
|
|
288
288
|
}
|
|
289
|
-
function requiredOption(options, name) {
|
|
290
|
-
return requiredText(options.get(name), name);
|
|
291
|
-
}
|
|
292
289
|
function optionalOption(options, name) {
|
|
293
290
|
if (!options.has(name))
|
|
294
291
|
return undefined;
|
|
@@ -93,9 +93,6 @@ function retryJob(args, store, options) {
|
|
|
93
93
|
enqueueWork(tx, { kind: "role", taskId: task.id, roleName: "leader" }, "recovery-retry", now, [{ type: "task", id: task.id }]);
|
|
94
94
|
});
|
|
95
95
|
const target = { kind: "role", taskId, roleName: "leader" };
|
|
96
|
-
|
|
97
|
-
runtime.notifyMailboxChanged(target);
|
|
98
|
-
else
|
|
99
|
-
runtime.notifyStateChanged(taskId);
|
|
96
|
+
runtime.notifyMailboxChanged(target);
|
|
100
97
|
return `Retry requested for ${id}\n`;
|
|
101
98
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { usageError } from "../errors/cliError.js";
|
|
2
1
|
import { agentAdapterLabel as adapterLabel } from "../agent/adapterCatalog.js";
|
|
2
|
+
import { usageError } from "../errors/cliError.js";
|
|
3
3
|
import { createRoleSessionSet } from "../executor/agentExecutor.js";
|
|
4
|
-
import {
|
|
4
|
+
import { TASK_SUBMISSION_INTENTS } from "../message/message.js";
|
|
5
|
+
import { listOperatorSessions, prepareOperatorNewSession, prepareOperatorResumeSession, projectOperatorStatus } from "../operator/operatorSessionHistory.js";
|
|
5
6
|
import { defaultTableWidth, renderTable } from "../output/table.js";
|
|
6
7
|
import { formatRelativeTimestamp } from "../output/timePresentation.js";
|
|
7
8
|
import { updateGlobalRole } from "../role/role.js";
|
|
8
|
-
import { TASK_SUBMISSION_INTENTS } from "../message/message.js";
|
|
9
9
|
import { submitOperatorMessage } from "./taskCommands.js";
|
|
10
10
|
import { readCommandText } from "./textInput.js";
|
|
11
11
|
/** Operator command parsing never launches or attaches a native process. */
|