@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,44 +1,46 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { prepareMessageContinuations, interruptThenTerminalState } from "../message/messageContinuation.js";
|
|
3
|
-
import { freezeRunContextSnapshot } from "../context/runContextPack.js";
|
|
4
|
-
import { contextSnapshotRef } from "../context/contextSnapshot.js";
|
|
5
2
|
import { isDeepStrictEqual } from "node:util";
|
|
3
|
+
import { contextSnapshotRef } from "../context/contextSnapshot.js";
|
|
4
|
+
import { freezeRunContextSnapshot } from "../context/runContextPack.js";
|
|
5
|
+
import { settleGlobalRetryInput } from "../message/globalProviderRetry.js";
|
|
6
|
+
import { interruptThenTerminalState, prepareMessageContinuations } from "../message/messageContinuation.js";
|
|
6
7
|
import { assertExecutionEnvironmentCurrent } from "../runtime/executionEnvironment.js";
|
|
7
|
-
import {
|
|
8
|
+
import { deferProviderRetry, providerRetryPending, recordProviderFailure } from "../runtime/providerRetry.js";
|
|
9
|
+
import { AgentHostObservationDeferred, recordAgentHostConnection, resolveAgentHostObservation } from "./agentHostObservation.js";
|
|
10
|
+
import { admitOwnedProviderInput, ownedProviderInput } from "./providerRetryAdmission.js";
|
|
8
11
|
import { RuntimeHookRunFenceError } from "./runtimeHookRunFence.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
12
|
+
import { appendRunInput, createRun, runPurposeAdmitsTaskState, withRunContextSnapshot } from "../agentRun/agentRun.js";
|
|
13
|
+
import { createRunInput } from "../context/runInputContract.js";
|
|
14
|
+
import { bindExecution, claimPending, completeProcessing, consumePendingBatch, mailboxHasWork, releaseProcessing } from "../coordination/workMailbox.js";
|
|
15
|
+
import { enqueueWork, settleRoleRunDispatch as settleRoleRunDispatchMailbox } from "../coordination/workMailboxQueue.js";
|
|
16
|
+
import { transportAgentResult } from "../domain/agentResultTransport.js";
|
|
11
17
|
import { createTaskEvent } from "../event/taskEvent.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { createTaskWake, fallbackWakeCursor, latestTaskWake, markTaskWakeConsumed } from "../scheduler/taskWake.js";
|
|
18
|
+
import { activeLiveRoleAgentSession, bindGlobalRoleProviderRuntime, bindTaskRoleProviderRuntime, createRoleSessionSet, detachRoleAgentSessionHost, recordRoleAgentSession, recordTaskRoleNativeTurnBoundary, rememberRoleAgentCompletedTurn, replaceTaskRoleAgentSession, selectNewTaskRoleSession, taskRoleControlTarget, updateGlobalRoleProviderRuntime, updateRoleAgentSessionStatus, updateTaskRoleProviderRuntime } from "../executor/agentExecutor.js";
|
|
19
|
+
import { effectiveLaunchWithTaskMainWorkspace, resolveEffectiveLaunch, roleSessionMayContinue, validateEffectiveLaunchSnapshot } from "../executor/effectiveLaunch.js";
|
|
15
20
|
import { answerInputRequest } from "../input/inputRequest.js";
|
|
21
|
+
import { createCanonicalLifecycleEvent, foldCanonicalLifecycleEvent } from "../lifecycle/canonicalLifecycleEvent.js";
|
|
22
|
+
import { cancelQuiescentRoleRuns, terminalizeExactTaskRun } from "../lifecycle/exactRunTerminalization.js";
|
|
23
|
+
import { markGlobalRoleMessageDelivered, markGlobalRoleMessageNotDelivered, recordTaskMessageControlOutcome } from "../message/message.js";
|
|
24
|
+
import { snapshotExecutionLaneWorkspaceSync } from "../repository/executionLaneGitSnapshot.js";
|
|
16
25
|
import { activeRoleAgentBinding } from "../role/role.js";
|
|
17
|
-
import { effectiveLaunchWithTaskMainWorkspace, roleSessionMayContinue, resolveEffectiveLaunch, validateEffectiveLaunchSnapshot } from "../executor/effectiveLaunch.js";
|
|
18
26
|
import { SYSTEM_OPERATOR_ROLE } from "../role/systemRoles.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
27
|
+
import { standardAgentError } from "../runtime/agentError.js";
|
|
28
|
+
import { recordTaskAgentError } from "./taskAgentError.js";
|
|
29
|
+
import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
|
|
30
|
+
import { RUNTIME_CLEANUP_REQUIRED_REASON, RUNTIME_HOST_DETACH_REQUIRED_REASON, RUNTIME_LIFECYCLE_OWNER, hasRuntimeCleanupObligation, hasRuntimeLifecycleWork, isRuntimeCleanupReason, runtimeCleanupDisposition, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
|
|
23
31
|
import { classifyRuntimeProcessExit, validateRuntimeProcessExitObservation } from "../runtime/processExitObservation.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
32
|
+
import { providerContinuationKey } from "../runtime/providerContinuation.js";
|
|
33
|
+
import { acceptProviderTurn, beginProviderTurn, cancelQuiescentProviderInput, clearProviderGoal, createProviderRuntimeBinding, currentProviderConversation, managedProviderTurnId, settleProviderTurn, settleProviderTurnSubmission, supersedeProviderConversation, transferProviderAuthority, updateProviderConversationRecoverability, updateProviderGoal } from "../runtime/providerRuntimeIdentity.js";
|
|
34
|
+
import { projectProviderContinuations } from "../runtime/runtimeContinuationProjection.js";
|
|
35
|
+
import { RUNTIME_OBSERVATION_TASK_EVENT, createRuntimeObservation, isRuntimeTokenEvidence, runtimeObservationFenceMatches, runtimeObservationFromTaskEvent, runtimeObservationRunFenceMatches, runtimeObservationTaskEventPayload } from "../runtime/runtimeObservation.js";
|
|
26
36
|
import { recordLeaderFailure } from "../scheduler/leaderFailure.js";
|
|
27
|
-
import { recordLeaderAttentionRequired, routeRoleEvent } from "../scheduler/operatorEvent.js";
|
|
28
|
-
import {
|
|
37
|
+
import { enqueueSupervisorEvent, recordLeaderAttentionRequired, routeRoleEvent } from "../scheduler/operatorEvent.js";
|
|
38
|
+
import { RUN_DIAGNOSTIC_FINISHED_EVENT, RUN_PROGRESS_EVENT, RUN_RECOVERED_EVENT, RUN_STALLED_EVENT, foldRunProgressFacts, isRoleRunStalled, latestRunDurableProgressAt, latestRunEventTime, latestStallEvidenceKey } from "../scheduler/roleRunStall.js";
|
|
39
|
+
import { createTaskWake, latestTaskWake, markTaskWakeConsumed } from "../scheduler/taskWake.js";
|
|
29
40
|
import { wakeReason } from "../scheduler/wakeReason.js";
|
|
30
|
-
import {
|
|
41
|
+
import { queueLeaderWakeup } from "../scheduler/wakeupQueue.js";
|
|
31
42
|
import { pendingWakeupProjection } from "../storage/taskStore.js";
|
|
32
|
-
import { projectProviderContinuations } from "../runtime/runtimeContinuationProjection.js";
|
|
33
|
-
import { providerContinuationKey } from "../runtime/providerContinuation.js";
|
|
34
43
|
import { formatRunReceiptId } from "../task/taskRecordReference.js";
|
|
35
|
-
import { bindExecution, claimPending, completeProcessing, consumePendingBatch, mailboxHasWork, releaseProcessing } from "../coordination/workMailbox.js";
|
|
36
|
-
import { enqueueWork, settleRoleRunDispatch as settleRoleRunDispatchMailbox } from "../coordination/workMailboxQueue.js";
|
|
37
|
-
import { RUNTIME_CLEANUP_REQUIRED_REASON, RUNTIME_HOST_DETACH_REQUIRED_REASON, RUNTIME_LIFECYCLE_OWNER, hasRuntimeCleanupObligation, hasRuntimeLifecycleWork, isRuntimeCleanupReason, runtimeCleanupDisposition, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
|
|
38
|
-
import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
|
|
39
|
-
import { standardAgentError } from "../runtime/agentError.js";
|
|
40
|
-
import { RUNTIME_OBSERVATION_TASK_EVENT, createRuntimeObservation, isRuntimeTokenEvidence, runtimeObservationFenceMatches, runtimeObservationFromTaskEvent, runtimeObservationRunFenceMatches, runtimeObservationTaskEventPayload } from "../runtime/runtimeObservation.js";
|
|
41
|
-
import { snapshotExecutionLaneWorkspaceSync } from "../repository/executionLaneGitSnapshot.js";
|
|
42
44
|
export class AgentHostProviderTurnFenceError extends Error {
|
|
43
45
|
constructor(message) {
|
|
44
46
|
super(message);
|
|
@@ -404,7 +406,9 @@ export class FileSchedulerStoreAdapter {
|
|
|
404
406
|
}
|
|
405
407
|
else if (binding.run?.status !== "accepted")
|
|
406
408
|
return "applied";
|
|
407
|
-
const message = store.listGlobalRoleMessages(fence.roleName).find(entry => receipt === `global-input:${fence.roleName}/${entry.id}`
|
|
409
|
+
const message = store.listGlobalRoleMessages(fence.roleName).find(entry => receipt === `global-input:${fence.roleName}/${entry.id}`
|
|
410
|
+
|| binding?.retry?.currentAttemptId === receipt && binding.retry.input.kind === "message"
|
|
411
|
+
&& binding.retry.input.messageId === entry.id);
|
|
408
412
|
if (message !== undefined)
|
|
409
413
|
store.updateGlobalRoleMessage(markGlobalRoleMessageDelivered(message, new Date(at)));
|
|
410
414
|
}
|
|
@@ -417,7 +421,9 @@ export class FileSchedulerStoreAdapter {
|
|
|
417
421
|
if (input.kind === "turn.completed" && binding.run != null
|
|
418
422
|
&& ["submitting", "delivery-unknown"].includes(binding.run.status)) {
|
|
419
423
|
binding = acceptProviderTurn(binding, { attemptId: receipt, nativeTurnId: fence.nativeTurnId, acceptedAt: at });
|
|
420
|
-
const message = store.listGlobalRoleMessages(fence.roleName).find(entry => receipt === `global-input:${fence.roleName}/${entry.id}`
|
|
424
|
+
const message = store.listGlobalRoleMessages(fence.roleName).find(entry => receipt === `global-input:${fence.roleName}/${entry.id}`
|
|
425
|
+
|| binding?.retry?.currentAttemptId === receipt && binding.retry.input.kind === "message"
|
|
426
|
+
&& binding.retry.input.messageId === entry.id);
|
|
421
427
|
if (message !== undefined)
|
|
422
428
|
store.updateGlobalRoleMessage(markGlobalRoleMessageDelivered(message, new Date(at)));
|
|
423
429
|
}
|
|
@@ -449,7 +455,13 @@ export class FileSchedulerStoreAdapter {
|
|
|
449
455
|
else if (input.kind === "conversation.observed" && input.payload.recoverability !== undefined) {
|
|
450
456
|
binding = updateProviderConversationRecoverability(binding, input.payload.recoverability);
|
|
451
457
|
}
|
|
458
|
+
if (input.kind === "turn.failed" && matches && input.payload.failure !== undefined) {
|
|
459
|
+
binding = recordProviderFailure(binding, {
|
|
460
|
+
error: input.payload.failure.error, failureRef: input.eventId, at: now.getTime()
|
|
461
|
+
});
|
|
462
|
+
}
|
|
452
463
|
store.saveGlobalRoleSessionSet(updateGlobalRoleProviderRuntime(sessions, binding, now));
|
|
464
|
+
settleGlobalRetryInput(store, fence.roleName, binding, now);
|
|
453
465
|
return "applied";
|
|
454
466
|
});
|
|
455
467
|
}
|
|
@@ -727,31 +739,25 @@ export class FileSchedulerStoreAdapter {
|
|
|
727
739
|
const run = input.fence.runId === undefined
|
|
728
740
|
? null
|
|
729
741
|
: store.getRun(taskId, input.fence.runId);
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
inputDisposition: error.inputDisposition,
|
|
747
|
-
sessionDisposition: error.sessionDisposition,
|
|
748
|
-
...(error.retryAfterMs === undefined
|
|
749
|
-
? {}
|
|
750
|
-
: { retryAfterMs: String(error.retryAfterMs) }),
|
|
751
|
-
...(failure.lastOutput === undefined ? {} : { lastOutput: failure.lastOutput })
|
|
742
|
+
const errorSessions = store.getTaskRoleSessionSet(taskId, input.fence.roleName);
|
|
743
|
+
const errorSession = [...Object.values(errorSessions?.sessions ?? {}), ...(errorSessions?.history ?? [])]
|
|
744
|
+
.find(session => session.nativeSessionId === input.fence.nativeSessionId
|
|
745
|
+
&& session.agentId === input.fence.agentId);
|
|
746
|
+
const effective = run?.effective ?? errorSession?.effective;
|
|
747
|
+
const { event: errorEvent, created } = recordTaskAgentError(store, {
|
|
748
|
+
taskId, roleName: input.fence.roleName, sourceEventId: input.eventId,
|
|
749
|
+
agentId: input.fence.agentId, adapterId: effective?.adapterId ?? "unknown",
|
|
750
|
+
driverId: input.fence.driverId, error, effective,
|
|
751
|
+
evidence: {
|
|
752
|
+
observationEventId,
|
|
753
|
+
runId: input.fence.runId,
|
|
754
|
+
nativeSessionId: input.fence.nativeSessionId,
|
|
755
|
+
nativeTurnId: input.fence.nativeTurnId,
|
|
756
|
+
lastOutput: failure.lastOutput
|
|
757
|
+
},
|
|
752
758
|
}, now);
|
|
753
|
-
store.
|
|
754
|
-
|
|
759
|
+
if (created && !providerRetryPending(store.getTaskRoleSessionSet(taskId, input.fence.roleName)?.providerBinding))
|
|
760
|
+
routeRoleEvent(store, errorEvent, input.fence.roleName, wakeReason("agent-error", errorEvent.id), now);
|
|
755
761
|
}
|
|
756
762
|
if ((input.kind === "operation.completed" || input.kind === "operation.failed")
|
|
757
763
|
&& input.payload.operation === "subagent") {
|
|
@@ -841,29 +847,6 @@ export class FileSchedulerStoreAdapter {
|
|
|
841
847
|
getTaskBrief(taskId) { return this.store.getTaskBrief(taskId); }
|
|
842
848
|
listDecisions(taskId) { return this.store.listDecisions(taskId); }
|
|
843
849
|
listMilestones(taskId) { return this.store.listMilestones(taskId); }
|
|
844
|
-
getTaskWakeEnvelope(taskId) {
|
|
845
|
-
return this.store.transaction((reader) => {
|
|
846
|
-
const pending = reader.getPendingWakeup(taskId);
|
|
847
|
-
if (pending === null)
|
|
848
|
-
return null;
|
|
849
|
-
const task = reader.getTask(taskId);
|
|
850
|
-
if (task === null)
|
|
851
|
-
return null;
|
|
852
|
-
const latest = latestTaskWake(reader.listTaskWakes(taskId));
|
|
853
|
-
const fromCursor = latest?.toCursor ?? fallbackWakeCursor({
|
|
854
|
-
taskCreatedAt: task.createdAt,
|
|
855
|
-
leaderRunCreatedAt: operationalTaskRecords(reader.listRuns(taskId), reader.listEvents(taskId), "run")
|
|
856
|
-
.filter((run) => run.roleName === "leader")
|
|
857
|
-
.at(-1)?.createdAt
|
|
858
|
-
});
|
|
859
|
-
return buildTaskWakeEnvelope(reader, {
|
|
860
|
-
taskId,
|
|
861
|
-
wakeId: reader.peekNextTaskWakeId(taskId),
|
|
862
|
-
reasons: pending.reasons,
|
|
863
|
-
fromCursor
|
|
864
|
-
});
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
850
|
listRoles(taskId) {
|
|
868
851
|
return this.store.listRoles(taskId).map((role) => mapRole(this.store, role));
|
|
869
852
|
}
|
|
@@ -1092,7 +1075,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1092
1075
|
throw new AgentHostProviderTurnFenceError("Global Session admission is stopped.");
|
|
1093
1076
|
}
|
|
1094
1077
|
const sessions = store.getGlobalRoleSessionSet(input.roleName);
|
|
1095
|
-
|
|
1078
|
+
let binding = sessions?.providerBinding;
|
|
1096
1079
|
const session = sessions?.sessions[input.agentId];
|
|
1097
1080
|
if (sessions === null || binding == null || session === undefined
|
|
1098
1081
|
|| sessions.activeAgentId !== input.agentId || session.status !== "active"
|
|
@@ -1104,8 +1087,10 @@ export class FileSchedulerStoreAdapter {
|
|
|
1104
1087
|
throw new AgentHostProviderTurnFenceError("Global input carries a stale Session or writer fence.");
|
|
1105
1088
|
}
|
|
1106
1089
|
const turn = binding.run;
|
|
1107
|
-
if (turn?.attemptId === input.attemptId && turn.status === "submitting")
|
|
1090
|
+
if (turn?.attemptId === input.attemptId && turn.status === "submitting") {
|
|
1091
|
+
admitOwnedProviderInput(store, binding, input);
|
|
1108
1092
|
return;
|
|
1093
|
+
}
|
|
1109
1094
|
if (turn != null && ["submitting", "accepted", "delivery-unknown"].includes(turn.status)) {
|
|
1110
1095
|
throw new AgentHostProviderSessionBusyError("Global Conversation has an unsettled input.");
|
|
1111
1096
|
}
|
|
@@ -1139,7 +1124,10 @@ export class FileSchedulerStoreAdapter {
|
|
|
1139
1124
|
receiptId: input.attemptId, outcome: "pending", observedAt: input.now.toISOString()
|
|
1140
1125
|
} });
|
|
1141
1126
|
}
|
|
1127
|
+
binding = admitOwnedProviderInput(store, binding, input);
|
|
1142
1128
|
store.saveGlobalRoleSessionSet(updateGlobalRoleProviderRuntime(sessions, beginProviderTurn(binding, { attemptId: input.attemptId,
|
|
1129
|
+
input: binding.retry?.currentAttemptId === input.attemptId ? binding.retry.input : ownedProviderInput(input),
|
|
1130
|
+
retrySupported: input.retrySupported,
|
|
1143
1131
|
authorityEpoch: input.authorityEpoch, submittedAt: input.now.toISOString() }), input.now));
|
|
1144
1132
|
});
|
|
1145
1133
|
return;
|
|
@@ -1157,7 +1145,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1157
1145
|
}
|
|
1158
1146
|
const sessions = store.getTaskRoleSessionSet(input.taskId, input.roleName);
|
|
1159
1147
|
const session = sessions?.sessions[input.agentId];
|
|
1160
|
-
|
|
1148
|
+
let binding = sessions?.providerBinding;
|
|
1161
1149
|
const active = store.getActiveRun(input.taskId, input.roleName);
|
|
1162
1150
|
if (sessions === null || sessions === undefined || binding === null || binding === undefined || (input.runId !== undefined && (active?.id !== input.runId || active.effective.agentId !== input.agentId)) || session === undefined || session.nativeSessionId !== input.nativeSessionId || currentProviderConversation(binding).conversationId !== input.nativeSessionId || binding.authority.owner !== input.authorityOwner || binding.authority.epoch !== input.authorityEpoch || binding.authority.holderId !== input.holderId) {
|
|
1163
1151
|
throw new AgentHostProviderTurnFenceError("Agent Host Provider Turn carries a stale durable writer fence. Release and reacquire Provider authority before retrying input.");
|
|
@@ -1214,11 +1202,14 @@ export class FileSchedulerStoreAdapter {
|
|
|
1214
1202
|
}
|
|
1215
1203
|
}
|
|
1216
1204
|
}
|
|
1205
|
+
binding = admitOwnedProviderInput(store, binding, input);
|
|
1217
1206
|
store.saveTaskRoleSessionSet(updateTaskRoleProviderRuntime(sessions, beginProviderTurn(binding, {
|
|
1218
1207
|
...(input.runId === undefined ? {} : { runId: input.runId }),
|
|
1219
1208
|
attemptId: input.attemptId,
|
|
1220
1209
|
authorityEpoch: input.authorityEpoch,
|
|
1221
|
-
submittedAt: input.now.toISOString()
|
|
1210
|
+
submittedAt: input.now.toISOString(),
|
|
1211
|
+
input: binding.retry?.currentAttemptId === input.attemptId ? binding.retry.input : ownedProviderInput(input),
|
|
1212
|
+
retrySupported: input.retrySupported
|
|
1222
1213
|
}), input.now));
|
|
1223
1214
|
});
|
|
1224
1215
|
}
|
|
@@ -1230,8 +1221,11 @@ export class FileSchedulerStoreAdapter {
|
|
|
1230
1221
|
if (input.runId !== undefined || sessions == null || binding?.run?.attemptId !== input.attemptId) {
|
|
1231
1222
|
throw new Error("Global input submission is no longer current.");
|
|
1232
1223
|
}
|
|
1233
|
-
|
|
1234
|
-
reason: input.reason, resolvedAt: input.now.toISOString() })
|
|
1224
|
+
let resolved = settleProviderTurnSubmission(binding, { attemptId: input.attemptId, status: input.status,
|
|
1225
|
+
reason: input.reason, resolvedAt: input.now.toISOString() });
|
|
1226
|
+
resolved = this.retrySubmissionResolution(resolved, input, sessions.sessions[sessions.activeAgentId]?.adapterId);
|
|
1227
|
+
store.saveGlobalRoleSessionSet(updateGlobalRoleProviderRuntime(sessions, resolved, input.now));
|
|
1228
|
+
settleGlobalRetryInput(store, input.roleName, resolved, input.now);
|
|
1235
1229
|
const message = store.listGlobalRoleMessages(input.roleName).find(entry => input.attemptId === `global-input:${input.roleName}/${entry.id}`);
|
|
1236
1230
|
if (message !== undefined && message.delivery?.via !== "provider") {
|
|
1237
1231
|
const outcome = input.status === "delivery-unknown" ? "delivery-unknown" : "rejected";
|
|
@@ -1239,7 +1233,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1239
1233
|
requestId: message.inputControl?.requestId ?? message.interruptThen.requestId,
|
|
1240
1234
|
receiptId: input.attemptId, outcome, observedAt: input.now.toISOString()
|
|
1241
1235
|
} };
|
|
1242
|
-
store.updateGlobalRoleMessage(input.status === "rejected" && updated.delivery === undefined
|
|
1236
|
+
store.updateGlobalRoleMessage(input.status === "rejected" && updated.delivery === undefined && !providerRetryPending(resolved)
|
|
1243
1237
|
? markGlobalRoleMessageNotDelivered(updated, input.reason, input.now) : updated);
|
|
1244
1238
|
}
|
|
1245
1239
|
});
|
|
@@ -1257,20 +1251,18 @@ export class FileSchedulerStoreAdapter {
|
|
|
1257
1251
|
|| binding.run?.attemptId !== input.attemptId) {
|
|
1258
1252
|
throw new Error("Agent Host Provider Turn submission is no longer current.");
|
|
1259
1253
|
}
|
|
1260
|
-
|
|
1254
|
+
let updated = settleProviderTurnSubmission(binding, {
|
|
1261
1255
|
attemptId: input.attemptId,
|
|
1262
1256
|
status: input.status,
|
|
1263
1257
|
reason: input.reason,
|
|
1264
1258
|
resolvedAt: input.now.toISOString()
|
|
1265
1259
|
});
|
|
1260
|
+
updated = this.retrySubmissionResolution(updated, input, sessions.sessions[sessions.activeAgentId]?.adapterId);
|
|
1266
1261
|
store.saveTaskRoleSessionSet(updateTaskRoleProviderRuntime(sessions, updated, input.now));
|
|
1267
|
-
|
|
1268
|
-
return;
|
|
1269
|
-
const run = store.getRun(input.taskId, input.runId);
|
|
1262
|
+
const run = input.runId === undefined ? null : store.getRun(input.taskId, input.runId);
|
|
1270
1263
|
const session = sessions.sessions[sessions.activeAgentId];
|
|
1271
|
-
const
|
|
1272
|
-
|
|
1273
|
-
: this.drivers.findByAdapterId(run.effective.adapterId);
|
|
1264
|
+
const adapterId = run?.effective.adapterId ?? session?.adapterId;
|
|
1265
|
+
const driver = adapterId === undefined ? null : this.drivers.findByAdapterId(adapterId);
|
|
1274
1266
|
const error = standardAgentError({
|
|
1275
1267
|
source: "driver",
|
|
1276
1268
|
phase: "turn-submit",
|
|
@@ -1282,41 +1274,46 @@ export class FileSchedulerStoreAdapter {
|
|
|
1282
1274
|
raw: input.raw,
|
|
1283
1275
|
inputDisposition: input.status === "delivery-unknown" ? "unknown" : "not-accepted"
|
|
1284
1276
|
});
|
|
1285
|
-
const errorEvent =
|
|
1286
|
-
sourceEventId: input.attemptId,
|
|
1287
|
-
runId: input.runId,
|
|
1288
|
-
roleName: input.roleName,
|
|
1277
|
+
const { event: errorEvent, created } = recordTaskAgentError(store, {
|
|
1278
|
+
taskId: input.taskId, roleName: input.roleName, sourceEventId: input.attemptId,
|
|
1289
1279
|
agentId: run?.effective.agentId ?? sessions.activeAgentId,
|
|
1290
|
-
adapterId:
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
// one the Provider genuinely reported.
|
|
1296
|
-
...optionalEventFields({
|
|
1280
|
+
adapterId: adapterId ?? "unknown", driverId: driver?.id ?? "unknown",
|
|
1281
|
+
error, effective: run?.effective ?? session?.effective,
|
|
1282
|
+
evidence: {
|
|
1283
|
+
attemptId: input.attemptId,
|
|
1284
|
+
runId: input.runId,
|
|
1297
1285
|
nativeSessionId: session?.nativeSessionId
|
|
1298
|
-
}
|
|
1299
|
-
source: error.source,
|
|
1300
|
-
phase: error.phase,
|
|
1301
|
-
category: error.category,
|
|
1302
|
-
code: error.code,
|
|
1303
|
-
message: error.message,
|
|
1304
|
-
raw: error.raw,
|
|
1305
|
-
inputDisposition: error.inputDisposition,
|
|
1306
|
-
sessionDisposition: error.sessionDisposition
|
|
1286
|
+
}
|
|
1307
1287
|
}, input.now);
|
|
1308
|
-
|
|
1309
|
-
if (input.status === "deferred")
|
|
1288
|
+
if (!created || input.status === "deferred" || providerRetryPending(updated))
|
|
1310
1289
|
return;
|
|
1311
|
-
|
|
1312
|
-
? { kind: "operator" }
|
|
1313
|
-
: { kind: "role", taskId: input.taskId, roleName: "leader" };
|
|
1314
|
-
enqueueWork(store, route, input.roleName === "leader"
|
|
1290
|
+
enqueueSupervisorEvent(store, errorEvent, input.roleName === "leader" ? "operator" : "leader", input.roleName === "leader"
|
|
1315
1291
|
? "leader-turn-submission-error"
|
|
1316
|
-
: wakeReason("agent-error", errorEvent.id), input.now
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1292
|
+
: wakeReason("agent-error", errorEvent.id), input.now);
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
retrySubmissionResolution(binding, input, adapterId) {
|
|
1296
|
+
if (input.status === "deferred")
|
|
1297
|
+
return deferProviderRetry(binding, input.now.getTime());
|
|
1298
|
+
const driver = adapterId === undefined ? null : this.drivers.findByAdapterId(adapterId);
|
|
1299
|
+
const classification = driver?.runtime.mapError({ message: input.reason, raw: input.raw });
|
|
1300
|
+
const error = standardAgentError({
|
|
1301
|
+
source: "driver", phase: "turn-submit", classification,
|
|
1302
|
+
message: input.reason, raw: input.raw,
|
|
1303
|
+
inputDisposition: input.status === "delivery-unknown" ? "unknown" : "not-accepted"
|
|
1304
|
+
});
|
|
1305
|
+
// Native preflight issued no mutation. Transient metadata failures may
|
|
1306
|
+
// cool down within the same deadline; unavailable proof needs an Agent.
|
|
1307
|
+
const noProviderWrite = input.status === "rejected" && input.noProviderWrite === true;
|
|
1308
|
+
if (noProviderWrite && classification?.retryable !== true) {
|
|
1309
|
+
const recorded = binding.run === null ? binding : {
|
|
1310
|
+
...binding, run: { ...binding.run, failure: { error, ref: input.attemptId } }
|
|
1311
|
+
};
|
|
1312
|
+
return deferProviderRetry(recorded, input.now.getTime(), input.reason);
|
|
1313
|
+
}
|
|
1314
|
+
return recordProviderFailure(binding, {
|
|
1315
|
+
error,
|
|
1316
|
+
failureRef: input.attemptId, at: input.now.getTime(), noProviderWrite
|
|
1320
1317
|
});
|
|
1321
1318
|
}
|
|
1322
1319
|
getProviderAuthorityFence(input) {
|
|
@@ -1356,15 +1353,19 @@ export class FileSchedulerStoreAdapter {
|
|
|
1356
1353
|
}
|
|
1357
1354
|
recordAgentError(input, now) {
|
|
1358
1355
|
return this.store.transaction((store) => {
|
|
1359
|
-
|
|
1356
|
+
if (input.runId === undefined && input.attemptId === undefined) {
|
|
1357
|
+
throw new Error("An Agent error needs an exact Run or notification attempt.");
|
|
1358
|
+
}
|
|
1359
|
+
const run = input.runId === undefined ? null : store.getRun(input.taskId, input.runId);
|
|
1360
1360
|
const sessionSet = store.getTaskRoleSessionSet(input.taskId, input.roleName);
|
|
1361
|
-
const
|
|
1361
|
+
const effective = input.effective ?? run?.effective;
|
|
1362
|
+
const sessionAgentId = effective?.agentId ?? sessionSet?.activeAgentId;
|
|
1362
1363
|
const session = sessionAgentId === undefined
|
|
1363
1364
|
? undefined
|
|
1364
1365
|
: sessionSet?.sessions[sessionAgentId];
|
|
1365
|
-
const driver =
|
|
1366
|
+
const driver = effective === undefined
|
|
1366
1367
|
? null
|
|
1367
|
-
: this.drivers.findByAdapterId(
|
|
1368
|
+
: this.drivers.findByAdapterId(effective.adapterId);
|
|
1368
1369
|
const error = standardAgentError({
|
|
1369
1370
|
source: input.source,
|
|
1370
1371
|
phase: input.phase,
|
|
@@ -1381,57 +1382,22 @@ export class FileSchedulerStoreAdapter {
|
|
|
1381
1382
|
? {}
|
|
1382
1383
|
: { sessionDisposition: input.sessionDisposition })
|
|
1383
1384
|
});
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
&& event.payload.hostState === input.hostState
|
|
1394
|
-
&& (input.attemptId === undefined
|
|
1395
|
-
? event.payload.raw === error.raw
|
|
1396
|
-
: event.payload.message === error.message
|
|
1397
|
-
&& event.payload.errorName === input.errorName
|
|
1398
|
-
&& event.payload.causeName === input.causeName)));
|
|
1399
|
-
// Re-reading one failed attempt may add a different caller stack, not a
|
|
1400
|
-
// new execution fact. Preserve its first full cause without multiplying
|
|
1401
|
-
// notifications; changed disposition/identity/diagnostic remains visible.
|
|
1402
|
-
if (duplicate !== undefined)
|
|
1403
|
-
return duplicate.id;
|
|
1404
|
-
const event = createTaskEvent(store.nextEventId(input.taskId), input.taskId, "runtime.agent-error", {
|
|
1405
|
-
sourceEventId: `${input.runId}:${input.phase}${input.attemptId === undefined ? "" : `:${input.attemptId}`}`,
|
|
1406
|
-
runId: input.runId,
|
|
1407
|
-
roleName: input.roleName,
|
|
1408
|
-
agentId: run?.effective.agentId ?? session?.agentId ?? "unknown",
|
|
1409
|
-
adapterId: run?.effective.adapterId ?? session?.adapterId ?? "unknown",
|
|
1410
|
-
driverId: driver?.id ?? "unknown",
|
|
1411
|
-
source: error.source,
|
|
1412
|
-
phase: error.phase,
|
|
1413
|
-
category: error.category,
|
|
1414
|
-
code: error.code,
|
|
1415
|
-
message: error.message,
|
|
1416
|
-
raw: error.raw,
|
|
1417
|
-
inputDisposition: error.inputDisposition,
|
|
1418
|
-
sessionDisposition: error.sessionDisposition,
|
|
1419
|
-
// Structured facts from the failing operation. Absent keys stay
|
|
1420
|
-
// absent rather than becoming an empty string, so a reader can tell
|
|
1421
|
-
// "the Host did not report this" from "the Host reported nothing".
|
|
1422
|
-
// The Session identities follow the same rule: this failure can
|
|
1423
|
-
// happen before any Session record exists, and there is no native
|
|
1424
|
-
// AgentRun to name at all.
|
|
1425
|
-
...optionalEventFields({
|
|
1426
|
-
nativeSessionId: session?.nativeSessionId,
|
|
1427
|
-
errorName: input.errorName,
|
|
1428
|
-
causeName: input.causeName,
|
|
1429
|
-
hostState: input.hostState,
|
|
1430
|
-
attemptId: input.attemptId,
|
|
1385
|
+
const { event, created } = recordTaskAgentError(store, {
|
|
1386
|
+
taskId: input.taskId, roleName: input.roleName,
|
|
1387
|
+
sourceEventId: `${input.runId ?? input.attemptId}:${input.phase}${input.runId === undefined || input.attemptId === undefined ? "" : `:${input.attemptId}`}`,
|
|
1388
|
+
agentId: effective?.agentId ?? session?.agentId ?? "unknown",
|
|
1389
|
+
adapterId: effective?.adapterId ?? session?.adapterId ?? "unknown",
|
|
1390
|
+
driverId: driver?.id ?? "unknown", error, effective,
|
|
1391
|
+
evidence: {
|
|
1392
|
+
runId: input.runId, attemptId: input.attemptId, nativeSessionId: session?.nativeSessionId,
|
|
1393
|
+
errorName: input.errorName, causeName: input.causeName, hostState: input.hostState,
|
|
1431
1394
|
registrationDisposition: input.registrationDisposition
|
|
1432
|
-
}
|
|
1395
|
+
}
|
|
1433
1396
|
}, now);
|
|
1434
|
-
|
|
1397
|
+
if (!created)
|
|
1398
|
+
return event.id;
|
|
1399
|
+
if (store.getTask(input.taskId)?.status === "archived")
|
|
1400
|
+
return event.id;
|
|
1435
1401
|
if (input.phase === "turn-submit" && error.inputDisposition === "unknown"
|
|
1436
1402
|
&& input.attemptId !== undefined && sessionSet?.providerBinding?.run?.attemptId === input.attemptId
|
|
1437
1403
|
&& sessionSet.providerBinding.run.status === "submitting") {
|
|
@@ -1445,18 +1411,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1445
1411
|
return event.id;
|
|
1446
1412
|
const leaderCannotReceive = input.roleName === "leader"
|
|
1447
1413
|
&& ["host-start", "session-start", "session-restore", "turn-submit"].includes(input.phase);
|
|
1448
|
-
|
|
1449
|
-
enqueueWork(store, { kind: "role", taskId: input.taskId, roleName: "leader" }, wakeReason("agent-error", event.id), now, [{ type: "event", taskId: input.taskId, id: event.id }], {
|
|
1450
|
-
source: driver?.id ?? input.source,
|
|
1451
|
-
dedupeKey: `agent-error:${input.taskId}:${input.runId}:${input.phase}:${event.id}`
|
|
1452
|
-
});
|
|
1453
|
-
}
|
|
1454
|
-
if (leaderCannotReceive) {
|
|
1455
|
-
enqueueWork(store, { kind: "operator" }, "leader-agent-error", now, [{ type: "event", taskId: input.taskId, id: event.id }], {
|
|
1456
|
-
source: driver?.id ?? input.source,
|
|
1457
|
-
dedupeKey: `leader-agent-error:${input.taskId}:${input.runId}:${event.id}`
|
|
1458
|
-
});
|
|
1459
|
-
}
|
|
1414
|
+
enqueueSupervisorEvent(store, event, leaderCannotReceive ? "operator" : "leader", leaderCannotReceive ? "leader-agent-error" : wakeReason("agent-error", event.id), now);
|
|
1460
1415
|
return event.id;
|
|
1461
1416
|
});
|
|
1462
1417
|
}
|
|
@@ -1750,6 +1705,13 @@ export class FileSchedulerStoreAdapter {
|
|
|
1750
1705
|
const task = store.getTask(taskId);
|
|
1751
1706
|
if (task == null || !["active", "draft"].includes(task.status) || task.executionGate.state !== "enabled")
|
|
1752
1707
|
return null;
|
|
1708
|
+
// Admission refuses input while this Session is being cleaned up.
|
|
1709
|
+
// Leave the original batch pending for its successor instead of
|
|
1710
|
+
// claiming a notification that cannot legally reach the Provider.
|
|
1711
|
+
if (hasRuntimeCleanupObligation(store.getWorkMailbox(runtimeLifecycleTarget({
|
|
1712
|
+
scope: "task", taskId, roleName: "leader"
|
|
1713
|
+
}))))
|
|
1714
|
+
return null;
|
|
1753
1715
|
const target = { kind: "role", taskId, roleName: "leader" };
|
|
1754
1716
|
let mailbox = store.getWorkMailbox(target);
|
|
1755
1717
|
if (mailbox === null)
|
|
@@ -1775,8 +1737,10 @@ export class FileSchedulerStoreAdapter {
|
|
|
1775
1737
|
return null;
|
|
1776
1738
|
}
|
|
1777
1739
|
if (native?.status === "rejected" || previous?.payload.outcome === "rejected") {
|
|
1778
|
-
|
|
1779
|
-
|
|
1740
|
+
if (previous?.payload.outcome !== "rejected") {
|
|
1741
|
+
this.settleLeaderNotification(taskId, attemptId, "rejected", now);
|
|
1742
|
+
}
|
|
1743
|
+
return { wakeId, attemptId, disposition: "rejected" };
|
|
1780
1744
|
}
|
|
1781
1745
|
if (native?.status === "submitting")
|
|
1782
1746
|
return { wakeId, attemptId, disposition: "pending" };
|
|
@@ -1851,7 +1815,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1851
1815
|
return { wakeId, attemptId, disposition: "submit" };
|
|
1852
1816
|
});
|
|
1853
1817
|
}
|
|
1854
|
-
settleLeaderNotification(taskId, attemptId, outcome, now, detail) {
|
|
1818
|
+
settleLeaderNotification(taskId, attemptId, outcome, now, detail, failure) {
|
|
1855
1819
|
this.store.transaction((store) => {
|
|
1856
1820
|
const target = { kind: "role", taskId, roleName: "leader" };
|
|
1857
1821
|
const mailbox = store.getWorkMailbox(target);
|
|
@@ -1861,19 +1825,35 @@ export class FileSchedulerStoreAdapter {
|
|
|
1861
1825
|
return;
|
|
1862
1826
|
if (!store.listEvents(taskId).some((event) => event.type === "notification.delivery"
|
|
1863
1827
|
&& event.payload.attemptId === attemptId && event.payload.outcome === outcome)) {
|
|
1864
|
-
|
|
1828
|
+
// Native ingress may already have persisted the same rejection. Reuse
|
|
1829
|
+
// that original failure rather than reporting it twice from the caller.
|
|
1830
|
+
const existing = store.listEventsByType(taskId, ["runtime.agent-error"])
|
|
1831
|
+
.find(event => event.payload.roleName === "leader"
|
|
1832
|
+
&& (event.payload.attemptId === attemptId || event.payload.sourceEventId === attemptId));
|
|
1833
|
+
const errorEventId = existing?.id ?? (failure !== undefined
|
|
1834
|
+
&& (outcome === "rejected" || outcome === "unknown")
|
|
1835
|
+
? this.recordAgentError({
|
|
1836
|
+
taskId, roleName: "leader", attemptId, effective: failure.effective,
|
|
1837
|
+
source: "host", phase: failure.phase,
|
|
1838
|
+
message: detail ?? `Notification ${outcome}.`, raw: failure.raw,
|
|
1839
|
+
inputDisposition: outcome === "unknown" ? "unknown" : "not-accepted",
|
|
1840
|
+
...(failure.phase === "session-start" ? { registrationDisposition: "not-committed" } : {})
|
|
1841
|
+
}, now) : undefined);
|
|
1842
|
+
store.saveEvent(taskId, createTaskEvent(store.nextEventId(taskId), taskId, "notification.delivery", { attemptId, outcome, ...(detail === undefined ? {} : { detail }),
|
|
1843
|
+
...(errorEventId === undefined ? {} : { errorEventId }) }, now));
|
|
1865
1844
|
}
|
|
1866
1845
|
if (store.getTask(taskId)?.status === "archived")
|
|
1867
1846
|
return;
|
|
1868
|
-
|
|
1847
|
+
// Rejection proves nondelivery, not consumption of the original input.
|
|
1848
|
+
// Keep the exact claim as the existing recovery/completion boundary.
|
|
1849
|
+
// An explicit retry or Session replacement can release it later.
|
|
1850
|
+
if (outcome !== "accepted")
|
|
1869
1851
|
return;
|
|
1870
1852
|
store.saveWorkMailbox(completeProcessing(mailbox, attemptId));
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
store.saveTaskWake(taskId, markTaskWakeConsumed(wake, now));
|
|
1876
|
-
}
|
|
1853
|
+
const wakeId = processing.owner.slice("leader-notification:".length);
|
|
1854
|
+
const wake = store.listTaskWakes(taskId).find((entry) => entry.id === wakeId);
|
|
1855
|
+
if (wake !== undefined)
|
|
1856
|
+
store.saveTaskWake(taskId, markTaskWakeConsumed(wake, now));
|
|
1877
1857
|
});
|
|
1878
1858
|
}
|
|
1879
1859
|
saveRoleRunPrepared(input) {
|
|
@@ -2085,12 +2065,6 @@ export class FileSchedulerStoreAdapter {
|
|
|
2085
2065
|
let sessions = store.getTaskRoleSessionSet(input.taskId, input.roleName)
|
|
2086
2066
|
?? createRoleSessionSet({ scope: "task", taskId: input.taskId, roleName: input.roleName }, input.agentId, now);
|
|
2087
2067
|
const canonicalRunId = input.nativeTurnId ?? resolved.nativeTurnId;
|
|
2088
|
-
const existing = sessions.sessions[input.agentId];
|
|
2089
|
-
const owner = {
|
|
2090
|
-
scope: "task",
|
|
2091
|
-
taskId: input.taskId,
|
|
2092
|
-
roleName: input.roleName
|
|
2093
|
-
};
|
|
2094
2068
|
assertConsistentTerminal(store, input, observedRun);
|
|
2095
2069
|
// A historical operation failure stays failed. The immutable terminal
|
|
2096
2070
|
// observation retains the late report for explicit Leader adoption.
|
|
@@ -2140,6 +2114,12 @@ export class FileSchedulerStoreAdapter {
|
|
|
2140
2114
|
&& sessions.providerBinding !== null) {
|
|
2141
2115
|
sessions = updateTaskRoleProviderRuntime(sessions, updateProviderConversationRecoverability(sessions.providerBinding, "unrecoverable"), now);
|
|
2142
2116
|
}
|
|
2117
|
+
if (input.observation?.kind === "turn.failed" && input.observation.payload.failure !== undefined
|
|
2118
|
+
&& sessions.providerBinding !== null) {
|
|
2119
|
+
sessions = updateTaskRoleProviderRuntime(sessions, recordProviderFailure(sessions.providerBinding, {
|
|
2120
|
+
error: input.observation.payload.failure.error, failureRef: input.observation.eventId, at: now.getTime()
|
|
2121
|
+
}), now);
|
|
2122
|
+
}
|
|
2143
2123
|
store.saveTaskRoleSessionSet(sessions);
|
|
2144
2124
|
let terminalRun;
|
|
2145
2125
|
if (recordedProviderTurn && observedRun?.status === "active") {
|
|
@@ -2482,6 +2462,14 @@ export class FileSchedulerStoreAdapter {
|
|
|
2482
2462
|
return "obsolete";
|
|
2483
2463
|
}
|
|
2484
2464
|
store.saveTaskRoleSessionSet(recordStructuredProviderAcceptance(sessions, input, now));
|
|
2465
|
+
const retry = binding.retry;
|
|
2466
|
+
if (retry?.currentAttemptId === ordinaryAttemptId && retry.input.kind === "wake") {
|
|
2467
|
+
const originalWakeId = retry.input.wakeId;
|
|
2468
|
+
const original = store.listTaskWakes(input.fence.taskId).find(w => w.id === originalWakeId);
|
|
2469
|
+
if (original !== undefined && original.status !== "consumed") {
|
|
2470
|
+
store.saveTaskWake(input.fence.taskId, markTaskWakeConsumed(original, now));
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2485
2473
|
return "applied";
|
|
2486
2474
|
}
|
|
2487
2475
|
}
|
|
@@ -3149,28 +3137,6 @@ function requireRole(store, taskId, roleName) {
|
|
|
3149
3137
|
throw new Error(`Role not found: ${taskId}/${roleName}.`);
|
|
3150
3138
|
return role;
|
|
3151
3139
|
}
|
|
3152
|
-
function runLaunchEventPayload(run) {
|
|
3153
|
-
return {
|
|
3154
|
-
runId: run.id,
|
|
3155
|
-
role: run.roleName,
|
|
3156
|
-
purpose: run.purpose,
|
|
3157
|
-
mode: run.mode,
|
|
3158
|
-
agent: `${run.effective.agentId}/${run.effective.adapterId}`,
|
|
3159
|
-
component: run.effective.component,
|
|
3160
|
-
effectiveRevision: String(run.effective.sourceDesiredRevision),
|
|
3161
|
-
profileAccess: run.effective.profileAccess,
|
|
3162
|
-
effectivePermission: run.effective.permission.strategy,
|
|
3163
|
-
writeProjectIds: run.effective.writeProjectIds.join(",") || "none"
|
|
3164
|
-
};
|
|
3165
|
-
}
|
|
3166
|
-
/**
|
|
3167
|
-
* Keeps only the fields the caller actually knew. Event payloads are a
|
|
3168
|
-
* string map, so an unknown fact has to be an absent key: writing `""` would
|
|
3169
|
-
* claim the Host reported an empty value.
|
|
3170
|
-
*/
|
|
3171
|
-
function optionalEventFields(fields) {
|
|
3172
|
-
return Object.fromEntries(Object.entries(fields).filter((entry) => typeof entry[1] === "string" && entry[1].trim().length > 0));
|
|
3173
|
-
}
|
|
3174
3140
|
function runtimeObservationTelemetryEntry(input) {
|
|
3175
3141
|
return {
|
|
3176
3142
|
taskId: input.fence.taskId,
|