@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,22 +1,41 @@
|
|
|
1
1
|
import { validateEffectiveLaunchSnapshot } from "../executor/effectiveLaunch.js";
|
|
2
2
|
import { validateTaskRecordReference } from "../task/taskRecordReference.js";
|
|
3
3
|
import { validateManagedWorkspace } from "../worktree/managedWorkspace.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
7
|
-
|
|
4
|
+
import { createRunInput, createRunInputEnvelope, validateRunInput } from "../context/runInputContract.js";
|
|
5
|
+
import { boundedRunFailureDiagnostic, MAX_RUN_FAILURE_DIAGNOSTIC_BYTES, MAX_RUN_RESULT_OUTPUT_BYTES } from "../domain/agentResultTransport.js";
|
|
6
|
+
export { boundedRunFailureDiagnostic, MAX_RUN_FAILURE_DIAGNOSTIC_BYTES, MAX_RUN_RESULT_OUTPUT_BYTES, transportAgentResult } from "../domain/agentResultTransport.js";
|
|
7
|
+
/** Record lifecycle and observed delivery are separate read-only facts. */
|
|
8
|
+
export function runExecutionObservation(run, binding, events = []) {
|
|
9
|
+
const current = binding?.run?.runId === run.id ? binding.run : undefined;
|
|
10
|
+
let delivery = current?.status ?? run.result?.provider?.status ?? "unobserved";
|
|
11
|
+
const lastError = events.filter((event) => event.type === "runtime.agent-error"
|
|
12
|
+
&& event.payload.runId === run.id && event.payload.phase === "turn-submit"
|
|
13
|
+
&& (current === undefined || event.payload.attemptId === current.attemptId)).at(-1);
|
|
14
|
+
if ((delivery === "unobserved" || delivery === "submitting") && lastError?.payload.inputDisposition === "unknown") {
|
|
15
|
+
delivery = "delivery-unknown";
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
recordStatus: run.status,
|
|
19
|
+
delivery,
|
|
20
|
+
...(current === undefined ? {} : {
|
|
21
|
+
attemptId: current.attemptId, observedAt: current.updatedAt,
|
|
22
|
+
...(current.nativeTurnId === undefined ? {} : { nativeTurnId: current.nativeTurnId })
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function createRun(id, taskId, roleName, mode, input, now, context) {
|
|
8
27
|
if (mode !== "new" && mode !== "resume") {
|
|
9
|
-
throw new Error(`
|
|
28
|
+
throw new Error(`AgentRun dispatch mode is invalid: ${mode}.`);
|
|
10
29
|
}
|
|
11
30
|
const timestamp = now.toISOString();
|
|
12
|
-
const normalizedInput =
|
|
31
|
+
const normalizedInput = validateRunInput(input);
|
|
13
32
|
return {
|
|
14
33
|
schemaVersion: 5,
|
|
15
|
-
id: requireSafeIdentity(id, "
|
|
34
|
+
id: requireSafeIdentity(id, "AgentRun id"),
|
|
16
35
|
taskId: requireSafeIdentity(taskId, "Task id"),
|
|
17
36
|
roleName: requireSafeIdentity(roleName, "Role name"),
|
|
18
37
|
mode,
|
|
19
|
-
inputs: [
|
|
38
|
+
inputs: [runInputRecord(normalizedInput, 1, timestamp)],
|
|
20
39
|
purpose: context.purpose ?? "execution",
|
|
21
40
|
...(context.workItemId === undefined
|
|
22
41
|
? {}
|
|
@@ -44,48 +63,64 @@ export function createTurn(id, taskId, roleName, mode, input, now, context) {
|
|
|
44
63
|
updatedAt: timestamp
|
|
45
64
|
};
|
|
46
65
|
}
|
|
47
|
-
export function
|
|
66
|
+
export function isActiveRun(run) {
|
|
48
67
|
return run.status === "active";
|
|
49
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The Task lifecycle a Turn of this purpose may run in.
|
|
71
|
+
*
|
|
72
|
+
* Delivery requires an active Task with execution admitted. Planning is the
|
|
73
|
+
* Draft Leader's own conversation, so it is also admitted while the Task is
|
|
74
|
+
* still a Draft; the execution gate still applies, because a stopped Task must
|
|
75
|
+
* not gain a live process through the planning door. Nothing here relaxes the
|
|
76
|
+
* workspace fence — a planning Turn simply has no workspace to be ready.
|
|
77
|
+
*/
|
|
78
|
+
export function runPurposeAdmitsTaskState(purpose, task) {
|
|
79
|
+
if (task.executionGate.state !== "enabled")
|
|
80
|
+
return false;
|
|
81
|
+
return purpose === "planning"
|
|
82
|
+
? task.status === "draft" || task.status === "active"
|
|
83
|
+
: task.status === "active";
|
|
84
|
+
}
|
|
50
85
|
/** Binds a freshly created, not-yet-persisted Turn to its frozen Context. */
|
|
51
|
-
export function
|
|
86
|
+
export function withRunContextSnapshot(run, snapshot, deltaRefIds = []) {
|
|
52
87
|
const initial = run.inputs[0];
|
|
53
88
|
if (run.status !== "active" || initial.input.contextSnapshotRef !== undefined) {
|
|
54
|
-
throw new Error(`Cannot replace the
|
|
89
|
+
throw new Error(`Cannot replace the AgentRun Context Snapshot: ${run.id}.`);
|
|
55
90
|
}
|
|
56
|
-
const input =
|
|
91
|
+
const input = createRunInput({
|
|
57
92
|
...initial.input,
|
|
58
93
|
contextSnapshotRef: snapshot,
|
|
59
94
|
deltaRefIds
|
|
60
95
|
});
|
|
61
|
-
return
|
|
96
|
+
return validateRun(Object.freeze({
|
|
62
97
|
...run,
|
|
63
|
-
inputs: [
|
|
98
|
+
inputs: [runInputRecord(input, 1, initial.submittedAt), ...run.inputs.slice(1)]
|
|
64
99
|
}));
|
|
65
100
|
}
|
|
66
|
-
export function
|
|
67
|
-
|
|
101
|
+
export function appendRunInput(run, input, now) {
|
|
102
|
+
validateRun(run);
|
|
68
103
|
if (run.status !== "active")
|
|
69
|
-
throw new Error(`Cannot append input to terminal
|
|
104
|
+
throw new Error(`Cannot append input to terminal AgentRun: ${run.id}.`);
|
|
70
105
|
const timestamp = now.toISOString();
|
|
71
106
|
if (Date.parse(timestamp) < Date.parse(run.updatedAt)) {
|
|
72
|
-
throw new Error("
|
|
107
|
+
throw new Error("AgentRun input timestamp moved backwards.");
|
|
73
108
|
}
|
|
74
|
-
return
|
|
109
|
+
return validateRun({
|
|
75
110
|
...run,
|
|
76
|
-
inputs: [...run.inputs,
|
|
111
|
+
inputs: [...run.inputs, runInputRecord(input, run.inputs.length + 1, timestamp)],
|
|
77
112
|
updatedAt: timestamp
|
|
78
113
|
});
|
|
79
114
|
}
|
|
80
|
-
/** Derives Provider-visible identity from the
|
|
81
|
-
export function
|
|
82
|
-
|
|
115
|
+
/** Derives Provider-visible identity from the AgentRun, the sole semantic owner. */
|
|
116
|
+
export function runInputEnvelope(run, sequence = 1) {
|
|
117
|
+
validateRun(run);
|
|
83
118
|
const record = run.inputs[sequence - 1];
|
|
84
119
|
if (record === undefined)
|
|
85
|
-
throw new Error(`
|
|
86
|
-
return
|
|
120
|
+
throw new Error(`AgentRun input does not exist: ${run.id}/${sequence}.`);
|
|
121
|
+
return createRunInputEnvelope(runEnvelopeContext(run), record.input);
|
|
87
122
|
}
|
|
88
|
-
export function
|
|
123
|
+
export function validateRun(run) {
|
|
89
124
|
rejectUnknownFields(run, [
|
|
90
125
|
"schemaVersion",
|
|
91
126
|
"id",
|
|
@@ -105,28 +140,28 @@ export function validateTurn(run) {
|
|
|
105
140
|
"result",
|
|
106
141
|
"createdAt",
|
|
107
142
|
"updatedAt"
|
|
108
|
-
], "
|
|
143
|
+
], "AgentRun");
|
|
109
144
|
if (run.schemaVersion !== 5)
|
|
110
|
-
throw new Error("
|
|
111
|
-
validateTaskRecordReference({ taskId: run.taskId, localId: run.id }, "
|
|
145
|
+
throw new Error("AgentRun must use schemaVersion 5.");
|
|
146
|
+
validateTaskRecordReference({ taskId: run.taskId, localId: run.id }, "run");
|
|
112
147
|
requireSafeIdentity(run.roleName, "Role name");
|
|
113
148
|
if (run.mode !== "new" && run.mode !== "resume") {
|
|
114
|
-
throw new Error(`
|
|
149
|
+
throw new Error(`AgentRun dispatch mode is invalid: ${String(run.mode)}.`);
|
|
115
150
|
}
|
|
116
151
|
if (!Array.isArray(run.inputs) || run.inputs.length === 0) {
|
|
117
|
-
throw new Error("
|
|
152
|
+
throw new Error("AgentRun requires at least one input.");
|
|
118
153
|
}
|
|
119
154
|
for (const [index, record] of run.inputs.entries()) {
|
|
120
155
|
if (record.sequence !== index + 1)
|
|
121
|
-
throw new Error("
|
|
122
|
-
requireTimestamp(record.submittedAt, "
|
|
123
|
-
|
|
156
|
+
throw new Error("AgentRun input sequence is invalid.");
|
|
157
|
+
requireTimestamp(record.submittedAt, "AgentRun input submittedAt");
|
|
158
|
+
validateRunInput(record.input);
|
|
124
159
|
if (index > 0 && Date.parse(record.submittedAt) < Date.parse(run.inputs[index - 1].submittedAt)) {
|
|
125
|
-
throw new Error("
|
|
160
|
+
throw new Error("AgentRun input timestamps moved backwards.");
|
|
126
161
|
}
|
|
127
162
|
}
|
|
128
|
-
if (!["execution", "review"].includes(run.purpose)) {
|
|
129
|
-
throw new Error(`
|
|
163
|
+
if (!["execution", "review", "planning"].includes(run.purpose)) {
|
|
164
|
+
throw new Error(`AgentRun purpose is invalid: ${String(run.purpose)}.`);
|
|
130
165
|
}
|
|
131
166
|
if (run.workItemId !== undefined) {
|
|
132
167
|
validateTaskRecordReference({ taskId: run.taskId, localId: run.workItemId }, "workItem");
|
|
@@ -135,7 +170,7 @@ export function validateTurn(run) {
|
|
|
135
170
|
validateTaskRecordReference({ taskId: run.taskId, localId: run.reviewRoundId }, "reviewRound");
|
|
136
171
|
}
|
|
137
172
|
if ((run.executionGroupId === undefined) !== (run.executionLaneId === undefined)) {
|
|
138
|
-
throw new Error("
|
|
173
|
+
throw new Error("AgentRun execution lineage is incomplete.");
|
|
139
174
|
}
|
|
140
175
|
if (run.executionGroupId !== undefined) {
|
|
141
176
|
requireSafeIdentity(run.executionGroupId, "ExecutionGroup id");
|
|
@@ -143,54 +178,77 @@ export function validateTurn(run) {
|
|
|
143
178
|
}
|
|
144
179
|
if (run.sourceExecutionGroupId !== undefined) {
|
|
145
180
|
requireSafeIdentity(run.sourceExecutionGroupId, "Source ExecutionGroup id");
|
|
181
|
+
if (run.purpose === "planning") {
|
|
182
|
+
throw new Error("A planning Turn cannot aggregate an Execution Lane group.");
|
|
183
|
+
}
|
|
146
184
|
if ((run.purpose === "execution" && run.workItemId === undefined)
|
|
147
185
|
|| (run.purpose === "review" && run.reviewRoundId === undefined)) {
|
|
148
|
-
throw new Error("A source ExecutionGroup requires a main execution or review
|
|
186
|
+
throw new Error("A source ExecutionGroup requires a main execution or review AgentRun.");
|
|
187
|
+
}
|
|
188
|
+
if (run.executionGroupId !== undefined || run.executionLaneId !== undefined) {
|
|
189
|
+
throw new Error("A main AgentRun cannot also be an Execution Lane AgentRun.");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (run.purpose === "planning") {
|
|
193
|
+
if (run.effective.executionAuthority !== "planning") {
|
|
194
|
+
throw new Error("A planning AgentRun cannot hold delivery authority.");
|
|
195
|
+
}
|
|
196
|
+
// Draft planning is deliberately delivery-free: no WorkItem, ReviewRound,
|
|
197
|
+
// Lane or workspace. That is what keeps a planning result from ever being
|
|
198
|
+
// read as execution evidence or promoted into a Candidate.
|
|
199
|
+
if (run.workItemId !== undefined) {
|
|
200
|
+
throw new Error("A planning Turn cannot reference a Work Item.");
|
|
201
|
+
}
|
|
202
|
+
if (run.reviewRoundId !== undefined) {
|
|
203
|
+
throw new Error("A planning Turn cannot reference a ReviewRound.");
|
|
149
204
|
}
|
|
150
205
|
if (run.executionGroupId !== undefined || run.executionLaneId !== undefined) {
|
|
151
|
-
throw new Error("A
|
|
206
|
+
throw new Error("A planning Turn cannot be an Execution Lane Turn.");
|
|
207
|
+
}
|
|
208
|
+
if (run.workspace !== undefined) {
|
|
209
|
+
throw new Error("A planning Turn cannot own a managed workspace.");
|
|
152
210
|
}
|
|
153
211
|
}
|
|
154
212
|
if (run.workspace !== undefined) {
|
|
155
213
|
validateManagedWorkspace(run.workspace);
|
|
156
214
|
if (run.workspace.owner.taskId !== run.taskId) {
|
|
157
|
-
throw new Error("
|
|
215
|
+
throw new Error("AgentRun workspace belongs to another Task.");
|
|
158
216
|
}
|
|
159
217
|
if (run.workspace.owner.type === "work-item"
|
|
160
218
|
&& run.workspace.owner.workItemId !== run.workItemId) {
|
|
161
|
-
throw new Error("
|
|
219
|
+
throw new Error("AgentRun workspace belongs to another Work Item.");
|
|
162
220
|
}
|
|
163
221
|
if (run.workspace.owner.type === "work-item" && run.workItemId === undefined) {
|
|
164
|
-
throw new Error("A WorkItem workspace requires a WorkItem
|
|
222
|
+
throw new Error("A WorkItem workspace requires a WorkItem AgentRun reference.");
|
|
165
223
|
}
|
|
166
224
|
if (run.workspace.owner.type === "review-round" && run.purpose !== "review") {
|
|
167
|
-
throw new Error("A ReviewRound workspace requires a review
|
|
225
|
+
throw new Error("A ReviewRound workspace requires a review AgentRun.");
|
|
168
226
|
}
|
|
169
227
|
if (run.workspace.owner.type === "integration-attempt") {
|
|
170
|
-
throw new Error("An IntegrationAttempt workspace cannot be used by a
|
|
228
|
+
throw new Error("An IntegrationAttempt workspace cannot be used by a AgentRun.");
|
|
171
229
|
}
|
|
172
230
|
if (run.workspace.owner.type === "execution-lane") {
|
|
173
231
|
if (run.workspace.owner.executionGroupId !== run.executionGroupId
|
|
174
232
|
|| run.workspace.owner.executionLaneId !== run.executionLaneId) {
|
|
175
|
-
throw new Error("
|
|
233
|
+
throw new Error("AgentRun Execution Lane workspace lineage does not match the AgentRun.");
|
|
176
234
|
}
|
|
177
235
|
if (run.workspace.owner.purpose === "execution"
|
|
178
236
|
&& run.workspace.owner.workItemId !== run.workItemId) {
|
|
179
|
-
throw new Error("
|
|
237
|
+
throw new Error("AgentRun Execution Lane workspace WorkItem does not match the AgentRun.");
|
|
180
238
|
}
|
|
181
239
|
if (run.workspace.owner.purpose === "review"
|
|
182
240
|
&& run.workspace.owner.reviewRoundId !== run.reviewRoundId) {
|
|
183
|
-
throw new Error("
|
|
241
|
+
throw new Error("AgentRun review Lane workspace ReviewRound does not match the AgentRun.");
|
|
184
242
|
}
|
|
185
243
|
}
|
|
186
244
|
if (run.workspace.owner.type === "review-round"
|
|
187
245
|
&& run.workspace.owner.reviewRoundId !== run.reviewRoundId) {
|
|
188
|
-
throw new Error(`
|
|
246
|
+
throw new Error(`AgentRun ReviewRound workspace owner does not match ${run.reviewRoundId ?? "none"}.`);
|
|
189
247
|
}
|
|
190
248
|
}
|
|
191
249
|
if (run.purpose === "review") {
|
|
192
250
|
if (run.reviewRoundId === undefined) {
|
|
193
|
-
throw new Error("A review
|
|
251
|
+
throw new Error("A review AgentRun requires a ReviewRound reference.");
|
|
194
252
|
}
|
|
195
253
|
if (run.workspace === undefined
|
|
196
254
|
|| !((run.workspace.owner.type === "review-round"
|
|
@@ -198,86 +256,86 @@ export function validateTurn(run) {
|
|
|
198
256
|
|| (run.workspace.owner.type === "execution-lane"
|
|
199
257
|
&& run.workspace.owner.purpose === "review"
|
|
200
258
|
&& run.workspace.owner.reviewRoundId === run.reviewRoundId))) {
|
|
201
|
-
throw new Error(`A review
|
|
259
|
+
throw new Error(`A review AgentRun requires its exact ReviewRound workspace owner: ${run.reviewRoundId}.`);
|
|
202
260
|
}
|
|
203
261
|
if (run.workspace.entries.length === 0
|
|
204
262
|
|| run.workspace.entries.some(({ access }) => access !== "write")) {
|
|
205
|
-
throw new Error("A review
|
|
263
|
+
throw new Error("A review AgentRun requires only isolated writable workspace entries.");
|
|
206
264
|
}
|
|
207
265
|
}
|
|
208
266
|
else {
|
|
209
267
|
if (run.reviewRoundId !== undefined) {
|
|
210
|
-
throw new Error("An execution
|
|
268
|
+
throw new Error("An execution AgentRun cannot reference a ReviewRound.");
|
|
211
269
|
}
|
|
212
270
|
if (run.workspace?.owner.type === "review-round") {
|
|
213
|
-
throw new Error("An execution
|
|
271
|
+
throw new Error("An execution AgentRun cannot use a ReviewRound-owned workspace.");
|
|
214
272
|
}
|
|
215
273
|
if (run.workspace?.owner.type === "execution-lane" && run.workspace.owner.purpose !== "execution") {
|
|
216
|
-
throw new Error("An execution
|
|
274
|
+
throw new Error("An execution AgentRun cannot use a review Lane workspace.");
|
|
217
275
|
}
|
|
218
276
|
}
|
|
219
277
|
validateEffectiveLaunchSnapshot(run.effective);
|
|
220
278
|
if (run.workspace !== undefined
|
|
221
279
|
&& (run.effective.workspace.root !== run.workspace.root
|
|
222
280
|
|| JSON.stringify(run.effective.workspace.entries) !== JSON.stringify(run.workspace.entries))) {
|
|
223
|
-
throw new Error("
|
|
281
|
+
throw new Error("AgentRun effective workspace does not match its managed workspace.");
|
|
224
282
|
}
|
|
225
283
|
if (run.purpose === "review") {
|
|
226
284
|
if (run.effective.reviewRoundId !== run.reviewRoundId) {
|
|
227
|
-
throw new Error("Review
|
|
285
|
+
throw new Error("Review AgentRun effective provenance does not match its ReviewRound.");
|
|
228
286
|
}
|
|
229
287
|
if (!run.workspace.entries.some(({ baseCommit }) => baseCommit === run.effective.reviewBaseCommit)) {
|
|
230
|
-
throw new Error("Review
|
|
288
|
+
throw new Error("Review AgentRun effective base does not match its workspace.");
|
|
231
289
|
}
|
|
232
290
|
}
|
|
233
291
|
else if (run.effective.reviewRoundId !== undefined) {
|
|
234
|
-
throw new Error("Execution
|
|
292
|
+
throw new Error("Execution AgentRun cannot carry Review effective provenance.");
|
|
235
293
|
}
|
|
236
294
|
for (const record of run.inputs) {
|
|
237
|
-
|
|
295
|
+
createRunInputEnvelope(runEnvelopeContext(run), record.input);
|
|
238
296
|
}
|
|
239
297
|
if (!["active", "completed", "failed"].includes(run.status)) {
|
|
240
|
-
throw new Error(`
|
|
298
|
+
throw new Error(`AgentRun status is invalid: ${String(run.status)}.`);
|
|
241
299
|
}
|
|
242
|
-
requireTimestamp(run.createdAt, "
|
|
243
|
-
requireTimestamp(run.updatedAt, "
|
|
300
|
+
requireTimestamp(run.createdAt, "AgentRun createdAt");
|
|
301
|
+
requireTimestamp(run.updatedAt, "AgentRun updatedAt");
|
|
244
302
|
if (run.status === "active") {
|
|
245
303
|
if (run.result !== undefined)
|
|
246
|
-
throw new Error("An active
|
|
304
|
+
throw new Error("An active AgentRun cannot have a result.");
|
|
247
305
|
}
|
|
248
306
|
else {
|
|
249
|
-
const result =
|
|
307
|
+
const result = validateRunResult(run.result);
|
|
250
308
|
if (run.status === "failed") {
|
|
251
|
-
if (!
|
|
252
|
-
throw new Error(`Failed
|
|
309
|
+
if (!isRunFailureReason(result.failureReason)) {
|
|
310
|
+
throw new Error(`Failed AgentRun reason is invalid: ${String(result.failureReason)}.`);
|
|
253
311
|
}
|
|
254
312
|
if (result.diagnostic === undefined) {
|
|
255
|
-
throw new Error("A failed
|
|
313
|
+
throw new Error("A failed AgentRun requires a Core diagnostic.");
|
|
256
314
|
}
|
|
257
315
|
if (result.systemEvidence !== undefined) {
|
|
258
|
-
throw new Error("A failed
|
|
316
|
+
throw new Error("A failed AgentRun cannot carry successful system evidence.");
|
|
259
317
|
}
|
|
260
318
|
}
|
|
261
319
|
else {
|
|
262
320
|
if (result.output === undefined) {
|
|
263
|
-
throw new Error("A completed
|
|
321
|
+
throw new Error("A completed AgentRun requires an Agent result.");
|
|
264
322
|
}
|
|
265
323
|
if (result.failureReason !== undefined || result.diagnostic !== undefined) {
|
|
266
|
-
throw new Error("A completed
|
|
324
|
+
throw new Error("A completed AgentRun cannot carry failure metadata.");
|
|
267
325
|
}
|
|
268
326
|
}
|
|
269
327
|
}
|
|
270
328
|
return run;
|
|
271
329
|
}
|
|
272
|
-
export function
|
|
273
|
-
return
|
|
330
|
+
export function completeRun(run, output, now, provider, systemEvidence) {
|
|
331
|
+
return finishRun(run, "completed", output, now, undefined, provider, systemEvidence);
|
|
274
332
|
}
|
|
275
|
-
export function
|
|
276
|
-
return
|
|
333
|
+
export function failRun(run, reason, diagnostic, now, provider, output) {
|
|
334
|
+
return finishRun(run, "failed", output, now, reason, provider, undefined, boundedRunFailureDiagnostic(diagnostic));
|
|
277
335
|
}
|
|
278
|
-
function
|
|
336
|
+
function finishRun(run, status, output, now, failureReason, provider, systemEvidence, diagnostic) {
|
|
279
337
|
if (run.status !== "active") {
|
|
280
|
-
throw new Error(`
|
|
338
|
+
throw new Error(`AgentRun is already terminal: ${run.id}.`);
|
|
281
339
|
}
|
|
282
340
|
const timestamp = now.toISOString();
|
|
283
341
|
const terminal = {
|
|
@@ -285,24 +343,24 @@ function finishTurn(run, status, output, now, failureReason, provider, systemEvi
|
|
|
285
343
|
status,
|
|
286
344
|
result: {
|
|
287
345
|
schemaVersion: 2,
|
|
288
|
-
...(output === undefined ? {} : { output: requireResultText(output, "
|
|
346
|
+
...(output === undefined ? {} : { output: requireResultText(output, "AgentRun result output") }),
|
|
289
347
|
...(diagnostic === undefined
|
|
290
348
|
? {}
|
|
291
|
-
: { diagnostic: requireDiagnosticText(diagnostic, "
|
|
349
|
+
: { diagnostic: requireDiagnosticText(diagnostic, "AgentRun result diagnostic") }),
|
|
292
350
|
completedAt: timestamp,
|
|
293
|
-
...(provider === undefined ? {} : { provider:
|
|
351
|
+
...(provider === undefined ? {} : { provider: validateRunProviderResult(provider) }),
|
|
294
352
|
...(systemEvidence === undefined
|
|
295
353
|
? {}
|
|
296
|
-
: { systemEvidence:
|
|
354
|
+
: { systemEvidence: validateRunSystemEvidence(systemEvidence) }),
|
|
297
355
|
...(failureReason === undefined ? {} : { failureReason })
|
|
298
356
|
},
|
|
299
357
|
updatedAt: timestamp,
|
|
300
358
|
};
|
|
301
|
-
return
|
|
359
|
+
return validateRun(terminal);
|
|
302
360
|
}
|
|
303
|
-
function
|
|
361
|
+
function validateRunResult(result) {
|
|
304
362
|
if (result === undefined || result.schemaVersion !== 2) {
|
|
305
|
-
throw new Error("A terminal
|
|
363
|
+
throw new Error("A terminal AgentRun requires AgentRunResult schemaVersion 2.");
|
|
306
364
|
}
|
|
307
365
|
rejectUnknownFields(result, [
|
|
308
366
|
"schemaVersion",
|
|
@@ -312,48 +370,47 @@ function validateTurnResult(result) {
|
|
|
312
370
|
"provider",
|
|
313
371
|
"systemEvidence",
|
|
314
372
|
"failureReason"
|
|
315
|
-
], "
|
|
373
|
+
], "AgentRun result");
|
|
316
374
|
if (result.output !== undefined)
|
|
317
|
-
requireResultText(result.output, "
|
|
375
|
+
requireResultText(result.output, "AgentRun result output");
|
|
318
376
|
if (result.diagnostic !== undefined) {
|
|
319
|
-
requireDiagnosticText(result.diagnostic, "
|
|
377
|
+
requireDiagnosticText(result.diagnostic, "AgentRun result diagnostic");
|
|
320
378
|
}
|
|
321
|
-
requireTimestamp(result.completedAt, "
|
|
379
|
+
requireTimestamp(result.completedAt, "AgentRun result completedAt");
|
|
322
380
|
if (result.provider !== undefined)
|
|
323
|
-
|
|
381
|
+
validateRunProviderResult(result.provider);
|
|
324
382
|
if (result.systemEvidence !== undefined)
|
|
325
|
-
|
|
383
|
+
validateRunSystemEvidence(result.systemEvidence);
|
|
326
384
|
return result;
|
|
327
385
|
}
|
|
328
|
-
function
|
|
386
|
+
function validateRunSystemEvidence(evidence) {
|
|
329
387
|
rejectUnknownFields(evidence, [
|
|
330
388
|
"workspaceSnapshot"
|
|
331
|
-
], "
|
|
389
|
+
], "AgentRun system evidence");
|
|
332
390
|
if (evidence.workspaceSnapshot !== undefined) {
|
|
333
391
|
const snapshot = evidence.workspaceSnapshot;
|
|
334
392
|
if (snapshot.schemaVersion !== 1 || !Array.isArray(snapshot.projects)) {
|
|
335
|
-
throw new Error("
|
|
393
|
+
throw new Error("AgentRun workspace snapshot is invalid.");
|
|
336
394
|
}
|
|
337
395
|
const projectIds = new Set();
|
|
338
396
|
for (const project of snapshot.projects) {
|
|
339
|
-
requireSafeIdentity(project.projectId, "
|
|
397
|
+
requireSafeIdentity(project.projectId, "AgentRun workspace snapshot Project id");
|
|
340
398
|
if (projectIds.has(project.projectId)) {
|
|
341
|
-
throw new Error("
|
|
399
|
+
throw new Error("AgentRun workspace snapshot Project ids must be unique.");
|
|
342
400
|
}
|
|
343
401
|
projectIds.add(project.projectId);
|
|
344
402
|
if (!/^[0-9a-f]{40}$/u.test(project.headCommit)) {
|
|
345
|
-
throw new Error("
|
|
403
|
+
throw new Error("AgentRun workspace snapshot commit is invalid.");
|
|
346
404
|
}
|
|
347
|
-
requireText(project.branch, "
|
|
405
|
+
requireText(project.branch, "AgentRun workspace snapshot branch");
|
|
348
406
|
}
|
|
349
407
|
}
|
|
350
408
|
return evidence;
|
|
351
409
|
}
|
|
352
|
-
function
|
|
410
|
+
function validateRunProviderResult(provider) {
|
|
353
411
|
requireText(provider.providerNamespace, "Provider namespace");
|
|
354
412
|
requireText(provider.accountScope, "Provider account scope");
|
|
355
413
|
requireText(provider.conversationId, "Provider Conversation id");
|
|
356
|
-
requireText(provider.activationId, "Provider Activation id");
|
|
357
414
|
if (provider.nativeTurnId !== undefined)
|
|
358
415
|
requireText(provider.nativeTurnId, "Provider native Turn id");
|
|
359
416
|
if (provider.attemptId !== undefined)
|
|
@@ -362,21 +419,21 @@ function validateTurnProviderResult(provider) {
|
|
|
362
419
|
throw new Error("Provider result requires a native Turn or exact attempt identity.");
|
|
363
420
|
}
|
|
364
421
|
if (!["completed", "failed", "cancelled"].includes(provider.status)) {
|
|
365
|
-
throw new Error(`Provider
|
|
422
|
+
throw new Error(`Provider AgentRun result status is invalid: ${String(provider.status)}.`);
|
|
366
423
|
}
|
|
367
424
|
return provider;
|
|
368
425
|
}
|
|
369
|
-
function
|
|
370
|
-
const normalized =
|
|
426
|
+
function runInputRecord(input, sequence, submittedAt) {
|
|
427
|
+
const normalized = validateRunInput(input);
|
|
371
428
|
return Object.freeze({
|
|
372
429
|
sequence,
|
|
373
430
|
submittedAt,
|
|
374
431
|
input: normalized
|
|
375
432
|
});
|
|
376
433
|
}
|
|
377
|
-
function
|
|
434
|
+
function runEnvelopeContext(run) {
|
|
378
435
|
return {
|
|
379
|
-
|
|
436
|
+
runId: run.id,
|
|
380
437
|
roleName: run.roleName,
|
|
381
438
|
purpose: run.purpose,
|
|
382
439
|
subject: {
|
|
@@ -415,8 +472,8 @@ function requireResultText(value, label) {
|
|
|
415
472
|
throw new Error(`${label} is invalid.`);
|
|
416
473
|
if (value.trim().length === 0)
|
|
417
474
|
throw new Error(`${label} is required.`);
|
|
418
|
-
if (Buffer.byteLength(value, "utf8") >
|
|
419
|
-
throw new Error(`${label} exceeds ${
|
|
475
|
+
if (Buffer.byteLength(value, "utf8") > MAX_RUN_RESULT_OUTPUT_BYTES) {
|
|
476
|
+
throw new Error(`${label} exceeds ${MAX_RUN_RESULT_OUTPUT_BYTES} bytes.`);
|
|
420
477
|
}
|
|
421
478
|
return value;
|
|
422
479
|
}
|
|
@@ -425,8 +482,8 @@ function requireDiagnosticText(value, label) {
|
|
|
425
482
|
throw new Error(`${label} is invalid.`);
|
|
426
483
|
if (value.trim().length === 0)
|
|
427
484
|
throw new Error(`${label} is required.`);
|
|
428
|
-
if (Buffer.byteLength(value, "utf8") >
|
|
429
|
-
throw new Error(`${label} exceeds ${
|
|
485
|
+
if (Buffer.byteLength(value, "utf8") > MAX_RUN_FAILURE_DIAGNOSTIC_BYTES) {
|
|
486
|
+
throw new Error(`${label} exceeds ${MAX_RUN_FAILURE_DIAGNOSTIC_BYTES} bytes.`);
|
|
430
487
|
}
|
|
431
488
|
return value;
|
|
432
489
|
}
|
|
@@ -435,7 +492,7 @@ function requireTimestamp(value, label) {
|
|
|
435
492
|
throw new Error(`${label} must be an ISO timestamp.`);
|
|
436
493
|
}
|
|
437
494
|
}
|
|
438
|
-
function
|
|
495
|
+
function isRunFailureReason(value) {
|
|
439
496
|
return [
|
|
440
497
|
"startup-failed",
|
|
441
498
|
"runtime-failed",
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { MAX_SESSION_TITLE_LENGTH } from "../runtime/sessionTitle.js";
|
|
2
2
|
/**
|
|
3
3
|
* Prefixes managed launch input with its session title. The bootstrap body
|
|
4
|
-
* exposes the exact current
|
|
4
|
+
* exposes the exact current AgentRun identity to the Agent, while structured
|
|
5
5
|
* delivery metadata and control hooks retain the delivery fence.
|
|
6
6
|
*/
|
|
7
7
|
export function prefixYuiTitleInput(input, title) {
|
|
8
8
|
const text = input.replace(/\r/g, "").trim();
|
|
9
9
|
if (text.length === 0)
|
|
10
10
|
throw new Error("Managed input body is required.");
|
|
11
|
-
return `${
|
|
11
|
+
return `${requireRunTitle(title)}\n\n${text}`;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function requireRunTitle(value) {
|
|
14
14
|
const title = value.trim();
|
|
15
15
|
if (title.length === 0
|
|
16
16
|
|| title.length > MAX_SESSION_TITLE_LENGTH
|
|
17
17
|
|| /[\r\n\0]/u.test(title)
|
|
18
18
|
|| !title.startsWith("Yui ")) {
|
|
19
|
-
throw new Error("
|
|
19
|
+
throw new Error("AgentRun title is invalid.");
|
|
20
20
|
}
|
|
21
21
|
return title;
|
|
22
22
|
}
|
package/dist/brief/taskBrief.js
CHANGED
|
@@ -11,6 +11,7 @@ export function createTaskBrief(input, now) {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
export function updateTaskBrief(brief, patch, updatedBy, now) {
|
|
14
|
+
validateTaskBrief(brief);
|
|
14
15
|
return createTaskBrief({
|
|
15
16
|
objective: patch.objective ?? brief.objective,
|
|
16
17
|
boundaries: patch.boundaries ?? brief.boundaries,
|
|
@@ -20,6 +21,17 @@ export function updateTaskBrief(brief, patch, updatedBy, now) {
|
|
|
20
21
|
updatedBy
|
|
21
22
|
}, now);
|
|
22
23
|
}
|
|
24
|
+
export function validateTaskBrief(brief) {
|
|
25
|
+
if (brief.schemaVersion !== 2) {
|
|
26
|
+
throw new Error("Task Brief requires schemaVersion 2.");
|
|
27
|
+
}
|
|
28
|
+
if (!Array.isArray(brief.boundaries) || typeof brief.technicalApproach !== "string"
|
|
29
|
+
|| typeof brief.updatedAt !== "string" || !Number.isFinite(Date.parse(brief.updatedAt))) {
|
|
30
|
+
throw new Error("Task Brief content or timestamp is invalid.");
|
|
31
|
+
}
|
|
32
|
+
createTaskBrief(brief, new Date(brief.updatedAt));
|
|
33
|
+
return brief;
|
|
34
|
+
}
|
|
23
35
|
function normalizeBoundaries(values) {
|
|
24
36
|
const normalized = values.map((value) => {
|
|
25
37
|
if (typeof value !== "string" || value.includes("\0")) {
|
|
@@ -78,6 +78,19 @@ export async function selectAgentPermission(resolved, io, current) {
|
|
|
78
78
|
const mode = await selectPermissionField(resolved, io, "permission.mode", claude?.mode, claude === undefined ? undefined : OMIT);
|
|
79
79
|
if (mode.kind === "cancelled")
|
|
80
80
|
return mode;
|
|
81
|
+
// ACP's configured permission is exactly the mode, and its adapter requires
|
|
82
|
+
// one: the value is matched against what the Agent enumerates at launch, so
|
|
83
|
+
// there is no "configured with nothing set" to fall back to. Claude's remains
|
|
84
|
+
// optional because its other native options can carry the configuration
|
|
85
|
+
// instead.
|
|
86
|
+
if (resolved.catalog.adapterId === "acp") {
|
|
87
|
+
return mode.value === undefined
|
|
88
|
+
? { kind: "cancelled" }
|
|
89
|
+
: {
|
|
90
|
+
kind: "selected",
|
|
91
|
+
permission: { strategy: "configured", mode: mode.value }
|
|
92
|
+
};
|
|
93
|
+
}
|
|
81
94
|
const permission = {
|
|
82
95
|
...(claude ?? { strategy: "configured" })
|
|
83
96
|
};
|