@sema-agent/client-core 0.99.0 → 0.101.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/CHANGELOG.md +572 -0
- package/README.md +174 -114
- package/dist/adapt/arms.js +109 -50
- package/dist/adapt/panelTasks.d.ts +2 -1
- package/dist/adapt/panelTasks.js +32 -9
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +58 -32
- package/dist/adapt/toolCards.js +9 -8
- package/dist/adapt.js +7 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +31 -2
- package/dist/adapter/activeRunSelfHeal.js +162 -13
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +157 -20
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +219 -39
- package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
- package/dist/adapter/downstream/wiringManifestView.js +1 -0
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +184 -42
- package/dist/adapter/types.d.ts +2 -0
- package/dist/agentsWireCaps.d.ts +9 -7
- package/dist/agentsWireCaps.js +101 -17
- package/dist/approvalDecidedByCapability.js +2 -2
- package/dist/approvalFrameFamilies.d.ts +33 -0
- package/dist/approvalFrameFamilies.js +120 -0
- package/dist/approvalsStreamLiveCapability.js +2 -2
- package/dist/attachmentsWireCaps.js +41 -13
- package/dist/callerCwdCapability.js +2 -2
- package/dist/centerWiringCapability.js +2 -2
- package/dist/clockReading.d.ts +2 -0
- package/dist/clockReading.js +4 -0
- package/dist/cloudConfigWireCaps.d.ts +28 -5
- package/dist/cloudConfigWireCaps.js +334 -103
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +8 -6
- package/dist/decideReceipt.js +2 -2
- package/dist/deviceExecutorManagementCapability.js +2 -2
- package/dist/deviceFlowPolling.js +1 -1
- package/dist/disableSkillsWire.d.ts +1 -1
- package/dist/disableSkillsWire.js +4 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +215 -13
- package/dist/engineAgentPanelStore.d.ts +7 -4
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +23 -6
- package/dist/engineErrorCodes.js +36 -11
- package/dist/engineGenerationConvergence.d.ts +39 -0
- package/dist/engineGenerationConvergence.js +95 -0
- package/dist/engineGenerationPort.d.ts +61 -0
- package/dist/engineGenerationPort.js +144 -0
- package/dist/engineHealthFacts.d.ts +23 -0
- package/dist/engineHealthFacts.js +92 -0
- package/dist/engineIdentity.d.ts +4 -0
- package/dist/engineIdentity.js +11 -0
- package/dist/engineNoticeCodes.d.ts +2 -5
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +6 -4
- package/dist/engineWireFor.d.ts +99 -0
- package/dist/engineWireFor.js +248 -6
- package/dist/engineWireTarget.d.ts +1 -0
- package/dist/engineWireTarget.js +8 -0
- package/dist/env/uiLanguage.js +1 -1
- package/dist/errorSupplementRoles.d.ts +3 -0
- package/dist/errorSupplementRoles.js +37 -0
- package/dist/eventLeg.d.ts +1 -7
- package/dist/eventLeg.js +7 -8
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.d.ts +0 -3
- package/dist/fileHistoryCaptureCapability.js +3 -7
- package/dist/finalVerifyWire.d.ts +6 -3
- package/dist/finalVerifyWire.js +6 -23
- package/dist/flagInput.d.ts +4 -0
- package/dist/flagInput.js +24 -0
- package/dist/fleet/fleetLedger.js +5 -2
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +15 -2
- package/dist/gateVocabulary.js +3 -0
- package/dist/generated/engineFactTables.d.ts +7 -2
- package/dist/generated/engineFactTables.js +79 -0
- package/dist/generated/engineNoticeTables.js +15 -0
- package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
- package/dist/generated/settingsSchemaActiveTiers.js +14 -0
- package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
- package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
- package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
- package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
- package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
- package/dist/generated/settingsSchemaDefaultModel.js +25 -0
- package/dist/generated/settingsSchemaFns.d.ts +66 -0
- package/dist/generated/settingsSchemaFns.js +38 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +156 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
- package/dist/generated/settingsSchemaSettingsSources.js +58 -0
- package/dist/generated/settingsSchemaTables.d.ts +3 -0
- package/dist/generated/settingsSchemaTables.js +18 -0
- package/dist/generated/settingsSchemaTypes.d.ts +28 -0
- package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlPattern.js +183 -0
- package/dist/headlessPermissionModeWire.d.ts +18 -2
- package/dist/headlessPermissionModeWire.js +30 -19
- package/dist/hitl/allowRuleShadow.js +9 -7
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- package/dist/hitl/approvalCardReasons.js +2 -2
- package/dist/hitl/approvalCompleteParked.js +1 -1
- package/dist/hitl/approvalDelivery.d.ts +87 -0
- package/dist/hitl/approvalDelivery.js +193 -0
- package/dist/hitl/approvalHolds.d.ts +14 -0
- package/dist/hitl/approvalHolds.js +41 -0
- package/dist/hitl/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +8 -2
- package/dist/hitl/askClassPair.js +31 -4
- package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
- package/dist/hitl/askParkAutoReopenBlock.js +117 -0
- package/dist/hitl/askParkRowRouting.js +4 -1
- package/dist/hitl/attributionLadder.d.ts +62 -0
- package/dist/hitl/attributionLadder.js +138 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
- package/dist/hitl/automaticAnswerVerdict.js +46 -11
- package/dist/hitl/crashConverged.js +2 -2
- package/dist/hitl/decisionConflict.d.ts +6 -2
- package/dist/hitl/decisionConflict.js +24 -9
- package/dist/hitl/decisionLedger.d.ts +55 -0
- package/dist/hitl/decisionLedger.js +156 -0
- package/dist/hitl/decisionRefusal.d.ts +21 -10
- package/dist/hitl/decisionRefusal.js +100 -55
- package/dist/hitl/decisionSend.d.ts +116 -0
- package/dist/hitl/decisionSend.js +563 -0
- package/dist/hitl/frameRouter.d.ts +1 -0
- package/dist/hitl/frameRouter.js +9 -2
- package/dist/hitl/hitlBridge.d.ts +18 -6
- package/dist/hitl/hitlBridge.js +59 -43
- package/dist/hitl/livePendingAsk.js +4 -3
- package/dist/hitl/noAllowCause.js +1 -1
- package/dist/hitl/parkResolver.js +3 -2
- package/dist/hitl/persistedRulesWire.js +1 -0
- package/dist/hitl/planReviewWire.d.ts +4 -0
- package/dist/hitl/planReviewWire.js +104 -106
- package/dist/hitl/resumeRunningCard.d.ts +3 -2
- package/dist/hitl/resumeRunningCard.js +17 -11
- package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
- package/dist/hitl/sessionPolicyDeliverable.js +65 -35
- package/dist/hitl/sessionPolicyWire.d.ts +13 -3
- package/dist/hitl/sessionPolicyWire.js +81 -16
- package/dist/hitl/standingRows.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +9 -10
- package/dist/hitl/toolApprovalWire.js +103 -151
- package/dist/hookMatcherVerdict.d.ts +2 -0
- package/dist/hookMatcherVerdict.js +12 -0
- package/dist/hooksCompactTransition.d.ts +19 -0
- package/dist/hooksCompactTransition.js +41 -0
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +202 -203
- package/dist/host.d.ts +1 -14
- package/dist/host.js +0 -8
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +1 -1
- package/dist/hostSettingsSource.d.ts +172 -0
- package/dist/hostSettingsSource.js +675 -0
- package/dist/hostTurnSettings.d.ts +114 -19
- package/dist/hostTurnSettings.js +966 -68
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +4 -2
- package/dist/humanTurn.js +40 -10
- package/dist/humanTurnRead.js +4 -3
- package/dist/humanTurnSentences.d.ts +10 -0
- package/dist/humanTurnSentences.js +74 -0
- package/dist/i18n/messages.en.d.ts +313 -0
- package/dist/i18n/messages.en.js +326 -13
- package/dist/i18n/messages.zh.js +341 -13
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +85 -15
- package/dist/index.js +53 -12
- package/dist/inheritEnvCapability.d.ts +4 -1
- package/dist/inheritEnvCapability.js +38 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/interactiveToolsWire.d.ts +4 -2
- package/dist/interactiveToolsWire.js +5 -5
- package/dist/jsonFaithful.d.ts +20 -0
- package/dist/jsonFaithful.js +152 -0
- package/dist/limitsWire.d.ts +7 -2
- package/dist/limitsWire.js +19 -13
- package/dist/liveInitToolFace.d.ts +6 -1
- package/dist/liveInitToolFace.js +5 -3
- package/dist/liveModelCatalog.d.ts +22 -0
- package/dist/liveModelCatalog.js +132 -18
- package/dist/mcpPanel.js +3 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpReconnect.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.d.ts +6 -0
- package/dist/mcpToolToggles.js +47 -0
- package/dist/mcpWireCaps.d.ts +48 -4
- package/dist/mcpWireCaps.js +338 -99
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/model/catalogDefault.d.ts +24 -0
- package/dist/model/catalogDefault.js +4 -0
- package/dist/model/liveCatalogShape.js +5 -4
- package/dist/model/modelsPolicy.js +4 -3
- package/dist/model/onboardJudgement.d.ts +1 -0
- package/dist/model/onboardJudgement.js +1 -1
- package/dist/model/subagentModelWord.js +2 -2
- package/dist/modelCapabilityProbe.d.ts +2 -1
- package/dist/modelCapabilityProbe.js +16 -15
- package/dist/modelIdentityResolvability.d.ts +12 -1
- package/dist/modelIdentityResolvability.js +69 -28
- package/dist/modsKernelIdentity.d.ts +10 -0
- package/dist/modsKernelIdentity.js +103 -0
- package/dist/modsKernelTransit.d.ts +8 -0
- package/dist/modsKernelTransit.js +6 -0
- package/dist/notifications.d.ts +30 -12
- package/dist/notifications.js +241 -53
- package/dist/outputStyleSeatCapability.js +2 -2
- package/dist/ownKey.d.ts +37 -0
- package/dist/ownKey.js +238 -2
- package/dist/panelReduce.d.ts +5 -0
- package/dist/panelReduce.js +45 -13
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/peerFrames.d.ts +1 -1
- package/dist/peerFrames.js +6 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.js +4 -4
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +24 -21
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionsAllowGrantCapability.js +2 -2
- package/dist/permissionsDeclaration.d.ts +43 -4
- package/dist/permissionsDeclaration.js +102 -35
- package/dist/pluginHooksWire.d.ts +20 -4
- package/dist/pluginHooksWire.js +101 -60
- package/dist/prepareRefusal.d.ts +9 -0
- package/dist/prepareRefusal.js +90 -0
- package/dist/printInitToolFace.js +2 -2
- package/dist/printModelStatus.js +1 -1
- package/dist/projectMemory.d.ts +32 -0
- package/dist/projectMemory.js +70 -0
- package/dist/promptBlockedCopy.d.ts +2 -1
- package/dist/promptBlockedCopy.js +2 -1
- package/dist/promptDelivery.d.ts +23 -3
- package/dist/promptDelivery.js +169 -30
- package/dist/providerRejection.d.ts +19 -1
- package/dist/providerRejection.js +75 -4
- package/dist/queuedDelivery.d.ts +48 -0
- package/dist/queuedDelivery.js +233 -0
- package/dist/reattachWindow.d.ts +94 -0
- package/dist/reattachWindow.js +127 -0
- package/dist/request/printNotification.d.ts +1 -1
- package/dist/request/printNotification.js +5 -1
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +22 -14
- package/dist/request/taskRequest.js +312 -202
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/resumeRefusalCopy.d.ts +3 -1
- package/dist/resumeRefusalCopy.js +22 -4
- package/dist/retryStatus.d.ts +26 -0
- package/dist/retryStatus.js +133 -28
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/rewindEngineAction.d.ts +2 -0
- package/dist/rewindEngineAction.js +23 -1
- package/dist/rowKind.d.ts +36 -0
- package/dist/rowKind.js +97 -0
- package/dist/ruleCompileVerdict.d.ts +18 -0
- package/dist/ruleCompileVerdict.js +67 -2
- package/dist/ruleReadings.d.ts +58 -0
- package/dist/ruleReadings.js +132 -0
- package/dist/ruleRefusalSentence.d.ts +8 -0
- package/dist/ruleRefusalSentence.js +64 -0
- package/dist/runCancelContext.d.ts +0 -1
- package/dist/runCancelContext.js +1 -2
- package/dist/runTerminal.d.ts +5 -0
- package/dist/runTerminal.js +52 -17
- package/dist/sandboxWire.d.ts +3 -2
- package/dist/sandboxWire.js +59 -27
- package/dist/scenarioRefusal.d.ts +2 -1
- package/dist/scenarioRefusal.js +6 -6
- package/dist/scenarioSkills.d.ts +20 -0
- package/dist/scenarioSkills.js +72 -0
- package/dist/scenarioWire.d.ts +5 -2
- package/dist/scenarioWire.js +9 -9
- package/dist/sealedKeyCapability.js +2 -2
- package/dist/seam.d.ts +26 -9
- package/dist/seam.js +44 -4
- package/dist/seatContract.d.ts +62 -9
- package/dist/seatContract.js +70 -25
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionPolicyCapability.js +2 -2
- package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
- package/dist/sessionRulesChildrenReadLive.js +5 -0
- package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
- package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +274 -0
- package/dist/settingsHooksSalvage.d.ts +1 -0
- package/dist/settingsHooksSalvage.js +7 -1
- package/dist/settingsLayerAdmission.d.ts +4 -0
- package/dist/settingsLayerAdmission.js +16 -0
- package/dist/skillToolListsCapability.js +6 -5
- package/dist/skillsWireCaps.d.ts +14 -3
- package/dist/skillsWireCaps.js +48 -18
- package/dist/slashCommandGate.d.ts +24 -0
- package/dist/slashCommandGate.js +74 -0
- package/dist/slashCommandTable.d.ts +14 -0
- package/dist/slashCommandTable.js +99 -0
- package/dist/sqlEngineCapability.js +2 -2
- package/dist/steerPriorityCapability.js +2 -2
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/agentStateDetail.js +1 -1
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
- package/dist/subagent/engineDelegatedPrompt.js +38 -7
- package/dist/subagent/engineRowStopGate.js +2 -2
- package/dist/subagent/engineSubagentResume.js +3 -3
- package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
- package/dist/subagent/engineTaskHandleWire.js +10 -0
- package/dist/subagentContentStore.d.ts +1 -0
- package/dist/subagentContentStore.js +135 -27
- package/dist/submitFailure.d.ts +8 -0
- package/dist/submitFailure.js +17 -0
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +7 -0
- package/dist/terminationIntent.d.ts +55 -0
- package/dist/terminationIntent.js +352 -0
- package/dist/toolHistoryMismatch.d.ts +8 -0
- package/dist/toolHistoryMismatch.js +37 -6
- package/dist/toolResult.d.ts +13 -3
- package/dist/toolResult.js +158 -9
- package/dist/toolResultContent.d.ts +13 -0
- package/dist/toolResultContent.js +82 -7
- package/dist/toolRoster.d.ts +18 -0
- package/dist/toolRoster.js +64 -0
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.js +41 -96
- package/dist/usageLimitAutoResume.d.ts +74 -0
- package/dist/usageLimitAutoResume.js +227 -0
- package/dist/userAttachmentEnvelope.js +1 -1
- package/dist/userAttachmentSeat.js +5 -5
- package/dist/userInvokedSkillsCapability.js +2 -2
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/wireErrorTriage.js +99 -50
- package/dist/wireFailureShape.d.ts +25 -1
- package/dist/wireFailureShape.js +92 -5
- package/dist/wireRefusalCopy.d.ts +75 -18
- package/dist/wireRefusalCopy.js +532 -148
- package/dist/wiringFleetDoctor.d.ts +3 -0
- package/dist/wiringFleetDoctor.js +21 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +38 -1
- package/dist/workflowClient.d.ts +2 -7
- package/dist/workflowsJournalCapability.js +2 -2
- package/dist/writeProtectionCapability.js +2 -2
- package/docs/INTEGRATION-CLIENTS.md +1013 -190
- package/package.json +15 -4
|
@@ -7,10 +7,12 @@ import { enqueuePlanReviewOutcome } from '../notifications.js';
|
|
|
7
7
|
import { corruptStoredRowContent, corruptStoredRowWhere } from '../wireErrorTriage.js';
|
|
8
8
|
import { decideFailureNote } from '../decideFailureNote.js';
|
|
9
9
|
import { wireFailureTextsOf } from '../wireFailureShape.js';
|
|
10
|
-
import { readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
|
|
10
|
+
import { appendOwnElement, readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
|
|
11
11
|
import { checkpointUnsupportedVersionContent, checkpointUnsupportedVersionFromError, resumeContextUnavailableContent, resumeContextUnavailableFromError } from '../resumeRefusalCopy.js';
|
|
12
12
|
import { REQUEST_FIELD_CONFLICT } from '../engineErrorCodes.js';
|
|
13
13
|
import { refusalDeliveryOf } from './decisionRefusal.js';
|
|
14
|
+
import { directFailureVerdictOf, directSafetyStopOf } from './approvalResolution.js';
|
|
15
|
+
import { __resetDecisionLedgerForTests, decisionInFlightOf, decisionKeyInFlight, decisionLedgerKeysOf, decisionOpsWithKey, decisionReadMark, dropDecisionOp, latestDecisionHandedMark, markLatestDecisionNotApplied, openDecisionOp, planDecisionKey, readMarkOf, settleDecisionOp, settleDecisionOpsOnGateLeft, } from './decisionLedger.js';
|
|
14
16
|
import { denyReasonForWire, isPlanReviewModeAfter } from './hitlBridge.js';
|
|
15
17
|
import { planReviewQuestionId, REOPEN_ID_TAIL, taskIdFromPlanReviewQuestionId } from './gateIdentity.js';
|
|
16
18
|
import { notePlanReviewAnswered, notePlanReviewAnsweredFor, planReviewArmedKeyFor, waitForGateArmedFor, wasGateArmedFor, } from './armedGateRegistry.js';
|
|
@@ -25,12 +27,8 @@ export const PLAN_REVIEW_APPROVE_MANUAL_LABEL = 'Yes, and manually approve edits
|
|
|
25
27
|
const APPROVE_LABEL = PLAN_REVIEW_APPROVE_LABEL;
|
|
26
28
|
const REJECT_LABEL = PLAN_REVIEW_REJECT_LABEL;
|
|
27
29
|
const LEGACY_TWO_CHOICE_LABELS = Object.freeze([PLAN_REVIEW_APPROVE_LABEL, PLAN_REVIEW_REJECT_LABEL]);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
PLAN_REVIEW_APPROVE_MANUAL_LABEL,
|
|
31
|
-
PLAN_REVIEW_APPROVE_LABEL,
|
|
32
|
-
PLAN_REVIEW_REJECT_LABEL,
|
|
33
|
-
]);
|
|
30
|
+
const THREE_CHOICE_LABELS = Object.freeze([PLAN_REVIEW_APPROVE_AUTO_LABEL, PLAN_REVIEW_APPROVE_MANUAL_LABEL, PLAN_REVIEW_REJECT_LABEL]);
|
|
31
|
+
const ANY_CARD_SHAPE_LABELS = Object.freeze([PLAN_REVIEW_APPROVE_AUTO_LABEL, PLAN_REVIEW_APPROVE_MANUAL_LABEL, PLAN_REVIEW_APPROVE_LABEL, PLAN_REVIEW_REJECT_LABEL]);
|
|
34
32
|
export function planReviewDecisionFromAnswer(answer, shownLabels = LEGACY_TWO_CHOICE_LABELS) {
|
|
35
33
|
const { choice } = readPlanReviewAnswer(answer, shownLabels);
|
|
36
34
|
if (choice === 'dismissed')
|
|
@@ -100,7 +98,7 @@ export function notePlanReviewAnsweredIfDecisive(questionId, answer) {
|
|
|
100
98
|
notePlanReviewAnsweredIfDecisiveFor(DEFAULT_SESSION_KEY, questionId, answer);
|
|
101
99
|
}
|
|
102
100
|
function notePlanReviewAnsweredIfDecisiveFor(sessionKey, questionId, answer) {
|
|
103
|
-
if (planReviewDecisionFromAnswer(answer ?? { answers: [] },
|
|
101
|
+
if (planReviewDecisionFromAnswer(answer ?? { answers: [] }, planReviewShownLabelsOf(questionId) ?? ANY_CARD_SHAPE_LABELS) === 'dismissed')
|
|
104
102
|
return;
|
|
105
103
|
notePlanReviewAnsweredFor(sessionKey, questionId);
|
|
106
104
|
const taskId = typeof questionId === 'string' ? taskIdFromPlanReviewQuestionId(questionId) : undefined;
|
|
@@ -275,7 +273,7 @@ function ownElementsOf(v, max) {
|
|
|
275
273
|
const n = Math.min(v.length, max);
|
|
276
274
|
const out = [];
|
|
277
275
|
for (let i = 0; i < n; i++)
|
|
278
|
-
out
|
|
276
|
+
appendOwnElement(out, readOwnDataValue(v, String(i)));
|
|
279
277
|
return out;
|
|
280
278
|
}
|
|
281
279
|
function offeredModeFromLabels(card) {
|
|
@@ -332,6 +330,33 @@ export function planReviewOfferedModeOf(card) {
|
|
|
332
330
|
return 'unknown';
|
|
333
331
|
}
|
|
334
332
|
}
|
|
333
|
+
export function planReviewShownLabelsOf(questionId) {
|
|
334
|
+
try {
|
|
335
|
+
if (typeof questionId !== 'string')
|
|
336
|
+
return undefined;
|
|
337
|
+
const recorded = offeredModeByQuestionId.get(questionId);
|
|
338
|
+
if (recorded !== undefined)
|
|
339
|
+
return recorded ? THREE_CHOICE_LABELS : LEGACY_TWO_CHOICE_LABELS;
|
|
340
|
+
for (const t of armedPlanReviewTaskIds) {
|
|
341
|
+
if (planReviewQuestionId(t) === questionId)
|
|
342
|
+
return offerModeAfterByTask.get(t) === true ? THREE_CHOICE_LABELS : LEGACY_TWO_CHOICE_LABELS;
|
|
343
|
+
}
|
|
344
|
+
if (taskIdFromPlanReviewQuestionId(questionId) === undefined)
|
|
345
|
+
return undefined;
|
|
346
|
+
return questionId.includes(REOPEN_ID_TAIL) ? LEGACY_TWO_CHOICE_LABELS : undefined;
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return undefined;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
export function planReviewAnswerChoiceOf(questionId, answer) {
|
|
353
|
+
const shown = planReviewShownLabelsOf(questionId);
|
|
354
|
+
return shown === undefined ? 'dismissed' : planReviewChoiceFromAnswer(answer, shown);
|
|
355
|
+
}
|
|
356
|
+
export function planReviewAnswerDecisionOf(questionId, answer) {
|
|
357
|
+
const shown = planReviewShownLabelsOf(questionId);
|
|
358
|
+
return shown === undefined ? 'dismissed' : planReviewDecisionFromAnswer(answer, shown);
|
|
359
|
+
}
|
|
335
360
|
export function armPlanReviewApproval(result, sessionKey, opts) {
|
|
336
361
|
let armedTaskId;
|
|
337
362
|
try {
|
|
@@ -377,10 +402,9 @@ export function armPlanReviewApproval(result, sessionKey, opts) {
|
|
|
377
402
|
offerModeAfterByTask.delete(taskId);
|
|
378
403
|
const questionId = planReviewQuestionId(taskId);
|
|
379
404
|
const unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
|
|
405
|
+
const choice = planReviewAnswerChoiceOf(questionId, answer);
|
|
380
406
|
unregister();
|
|
381
407
|
armedPlanReviewTaskIds.delete(taskId);
|
|
382
|
-
const shown = planReviewCardOptions(offerModeAfterByTask.get(taskId) === true).map(o => o.label);
|
|
383
|
-
const choice = planReviewChoiceFromAnswer(answer, shown);
|
|
384
408
|
if (choice === 'dismissed') {
|
|
385
409
|
notePlanReviewUserDismissalFor(DEFAULT_SESSION_KEY, taskId, opts?.readGateInstanceKeys, questionId);
|
|
386
410
|
return { ok: true };
|
|
@@ -457,42 +481,21 @@ function usablePlanReviewWireClient(client) {
|
|
|
457
481
|
return clientHasVerbs(client, [['assistant', 'planReview'], ['runs', 'get']]);
|
|
458
482
|
}
|
|
459
483
|
const PLAN_REVIEW_INJECTED_REPULL_TIMEOUT_MS = 15_000;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
let planReviewLedgerClock = 0;
|
|
463
|
-
let decideDispatchSeq = 0;
|
|
464
|
-
function planReviewOpsOf(taskId) {
|
|
465
|
-
return planReviewDecisionOps.filter((op) => op.taskId === taskId);
|
|
466
|
-
}
|
|
467
|
-
function settlePlanReviewDecisionOp(op, by) {
|
|
468
|
-
if (op.settledAt !== null)
|
|
469
|
-
return;
|
|
470
|
-
op.settledAt = ++planReviewLedgerClock;
|
|
471
|
-
op.settler = by;
|
|
472
|
-
}
|
|
473
|
-
function pushPlanReviewDecisionOp(op) {
|
|
474
|
-
planReviewDecisionOps.push(op);
|
|
475
|
-
while (planReviewDecisionOps.length > MAX_PLAN_REVIEW_DECISION_OPS) {
|
|
476
|
-
let victim = planReviewDecisionOps.findIndex((o) => o.settledAt !== null && !o.ownCallOpen);
|
|
477
|
-
if (victim < 0)
|
|
478
|
-
victim = planReviewDecisionOps.findIndex((o) => o !== op && o.phase === 'handed');
|
|
479
|
-
if (victim < 0)
|
|
480
|
-
break;
|
|
481
|
-
planReviewDecisionOps.splice(victim, 1);
|
|
482
|
-
}
|
|
484
|
+
function planReviewLedgerKeys(taskId) {
|
|
485
|
+
return taskId === '' ? [planDecisionKey('')] : decisionLedgerKeysOf({ taskId, planTaskId: taskId });
|
|
483
486
|
}
|
|
484
|
-
function
|
|
485
|
-
|
|
486
|
-
if (i >= 0)
|
|
487
|
-
planReviewDecisionOps.splice(i, 1);
|
|
487
|
+
function planReviewOpsOf(taskId) {
|
|
488
|
+
return decisionOpsWithKey('plan_review', planDecisionKey(taskId));
|
|
488
489
|
}
|
|
490
|
+
let decideDispatchSeq = 0;
|
|
489
491
|
function claimablePlanReviewDecisionOp(taskId) {
|
|
490
|
-
const
|
|
492
|
+
const ops = planReviewOpsOf(taskId);
|
|
493
|
+
const open = ops.find((o) => o.phase === 'handed' && o.settledAt === null);
|
|
491
494
|
if (open !== undefined)
|
|
492
495
|
return open;
|
|
493
496
|
let leftBehind;
|
|
494
|
-
for (const o of
|
|
495
|
-
if (o.
|
|
497
|
+
for (const o of ops) {
|
|
498
|
+
if (o.phase !== 'handed' || o.settler !== 'gate_left')
|
|
496
499
|
continue;
|
|
497
500
|
if (leftBehind === undefined || o.handedAt > leftBehind.handedAt)
|
|
498
501
|
leftBehind = o;
|
|
@@ -502,62 +505,47 @@ function claimablePlanReviewDecisionOp(taskId) {
|
|
|
502
505
|
export function notePlanReviewDecisionHandedOver(taskId) {
|
|
503
506
|
if (typeof taskId !== 'string' || taskId === '')
|
|
504
507
|
return null;
|
|
505
|
-
if (
|
|
508
|
+
if (planReviewOpsOf(taskId).some((op) => op.settledAt === null))
|
|
506
509
|
return null;
|
|
507
|
-
const op =
|
|
508
|
-
pushPlanReviewDecisionOp(op);
|
|
510
|
+
const op = openDecisionOp('plan_review', planReviewLedgerKeys(taskId), 'handed', false);
|
|
509
511
|
return {
|
|
510
512
|
settle: () => {
|
|
511
513
|
if (op.phase !== 'handed')
|
|
512
514
|
return;
|
|
513
|
-
|
|
515
|
+
settleDecisionOp(op, 'host');
|
|
514
516
|
},
|
|
515
517
|
revoke: () => {
|
|
516
518
|
if (op.phase !== 'handed' || op.settledAt !== null)
|
|
517
519
|
return;
|
|
518
|
-
|
|
520
|
+
dropDecisionOp(op);
|
|
519
521
|
},
|
|
520
522
|
};
|
|
521
523
|
}
|
|
522
524
|
export function planReviewPendingReadMark() {
|
|
523
|
-
return
|
|
525
|
+
return decisionReadMark();
|
|
524
526
|
}
|
|
525
527
|
export function planReviewDecisionInFlight(taskId, pendingReadStartedAt) {
|
|
526
528
|
if (typeof taskId !== 'string' || taskId === '')
|
|
527
529
|
return false;
|
|
528
|
-
|
|
529
|
-
return planReviewDecisionOps.some((op) => op.taskId === taskId && (op.settledAt === null || (mark !== undefined && op.settledAt > mark && !op.notApplied)));
|
|
530
|
+
return decisionKeyInFlight(planDecisionKey(taskId), readMarkOf(pendingReadStartedAt));
|
|
530
531
|
}
|
|
531
532
|
export function notePlanReviewDecisionNotApplied(taskId) {
|
|
532
533
|
if (typeof taskId !== 'string' || taskId === '')
|
|
533
534
|
return;
|
|
534
|
-
|
|
535
|
-
if (ops.some((op) => op.settledAt === null))
|
|
536
|
-
return;
|
|
537
|
-
let latest;
|
|
538
|
-
for (const op of ops)
|
|
539
|
-
if (latest === undefined || op.handedAt > latest.handedAt)
|
|
540
|
-
latest = op;
|
|
541
|
-
if (latest !== undefined)
|
|
542
|
-
latest.notApplied = true;
|
|
535
|
+
markLatestDecisionNotApplied('plan_review', planDecisionKey(taskId));
|
|
543
536
|
}
|
|
544
537
|
export function notePlanReviewGateLeft(taskId) {
|
|
545
538
|
if (typeof taskId !== 'string' || taskId === '')
|
|
546
539
|
return;
|
|
547
|
-
|
|
548
|
-
settlePlanReviewDecisionOp(op, 'gate_left');
|
|
540
|
+
settleDecisionOpsOnGateLeft('plan_review', planDecisionKey(taskId));
|
|
549
541
|
}
|
|
550
542
|
export function latestPlanReviewDecisionMark(taskId) {
|
|
551
543
|
if (typeof taskId !== 'string' || taskId === '')
|
|
552
544
|
return null;
|
|
553
|
-
|
|
554
|
-
for (const op of planReviewOpsOf(taskId))
|
|
555
|
-
if (mark === null || op.handedAt > mark)
|
|
556
|
-
mark = op.handedAt;
|
|
557
|
-
return mark;
|
|
545
|
+
return latestDecisionHandedMark('plan_review', planDecisionKey(taskId));
|
|
558
546
|
}
|
|
559
547
|
export function __resetPlanReviewDecisionLatchForTests() {
|
|
560
|
-
|
|
548
|
+
__resetDecisionLedgerForTests('plan_review');
|
|
561
549
|
}
|
|
562
550
|
export async function decidePlanReview(taskId, decision, permissionModeAfter, opts) {
|
|
563
551
|
return decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, parkedGateIdentityOf(opts));
|
|
@@ -574,22 +562,22 @@ function planReviewSettledVerdict(r) {
|
|
|
574
562
|
const status = r.postStatus ?? r.bodyStatus;
|
|
575
563
|
const gateMoved = r.gateBefore !== undefined && r.gateAfter !== undefined && r.gateAfter !== r.gateBefore;
|
|
576
564
|
if (r.reparked)
|
|
577
|
-
return status !== 'completed' && !gateMoved ?
|
|
565
|
+
return status !== 'completed' && !gateMoved ? 'still_parked' : 'unconfirmed';
|
|
578
566
|
if (status === 'completed')
|
|
579
|
-
return
|
|
567
|
+
return 'took_effect';
|
|
580
568
|
const newGateHasCard = () => {
|
|
581
569
|
const leg = durableDecideLegOf({ gateKind: r.gateKindAfter ?? null });
|
|
582
570
|
return leg === 'approval' || leg === 'plan_review';
|
|
583
571
|
};
|
|
584
572
|
if (status === 'suspended' && r.postStatus === 'suspended' && newGateHasCard())
|
|
585
|
-
return
|
|
573
|
+
return 'advanced';
|
|
586
574
|
if (status === 'needs_review' && r.postStatus === 'needs_review' && r.gateBefore !== undefined && r.gateAfter !== undefined) {
|
|
587
575
|
if (r.gateAfter === r.gateBefore)
|
|
588
|
-
return
|
|
576
|
+
return 'still_parked';
|
|
589
577
|
if (newGateHasCard())
|
|
590
|
-
return
|
|
578
|
+
return 'advanced';
|
|
591
579
|
}
|
|
592
|
-
return
|
|
580
|
+
return 'unconfirmed';
|
|
593
581
|
}
|
|
594
582
|
function bodyWordOf(body, key) {
|
|
595
583
|
try {
|
|
@@ -609,14 +597,13 @@ function bodySaysReparked(body) {
|
|
|
609
597
|
}
|
|
610
598
|
}
|
|
611
599
|
async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, gateBefore) {
|
|
612
|
-
if (typeof taskId === 'string' &&
|
|
600
|
+
if (typeof taskId === 'string' && planReviewOpsOf(taskId).some((op) => op.phase === 'posting')) {
|
|
613
601
|
hostLog('error', `planReviewWire: decidePlanReview(${decision}) for task ${taskId} REFUSED — a decision for this task is already in flight (duplicate delivery latched)`);
|
|
614
602
|
return;
|
|
615
603
|
}
|
|
616
|
-
let op = claimablePlanReviewDecisionOp(taskId);
|
|
604
|
+
let op = typeof taskId === 'string' ? claimablePlanReviewDecisionOp(taskId) : undefined;
|
|
617
605
|
if (op === undefined) {
|
|
618
|
-
op =
|
|
619
|
-
pushPlanReviewDecisionOp(op);
|
|
606
|
+
op = openDecisionOp('plan_review', planReviewLedgerKeys(typeof taskId === 'string' ? taskId : String(taskId)), 'posting', true);
|
|
620
607
|
}
|
|
621
608
|
else {
|
|
622
609
|
if (op.settler === 'gate_left') {
|
|
@@ -635,7 +622,7 @@ async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts,
|
|
|
635
622
|
const settle = (notApplied) => {
|
|
636
623
|
if (notApplied)
|
|
637
624
|
mine.notApplied = true;
|
|
638
|
-
|
|
625
|
+
settleDecisionOp(mine, 'package');
|
|
639
626
|
};
|
|
640
627
|
const dispatchNo = ++decideDispatchSeq;
|
|
641
628
|
hostLog('debug', `planReviewWire: decidePlanReview dispatch #${dispatchNo} task=${taskId} decision=${decision} mode=${permissionModeAfter ?? '-'}`);
|
|
@@ -644,7 +631,7 @@ async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts,
|
|
|
644
631
|
}
|
|
645
632
|
finally {
|
|
646
633
|
releaseLatch();
|
|
647
|
-
|
|
634
|
+
settleDecisionOp(mine, 'package');
|
|
648
635
|
mine.ownCallOpen = false;
|
|
649
636
|
}
|
|
650
637
|
}
|
|
@@ -665,7 +652,6 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
665
652
|
let outcome;
|
|
666
653
|
let effect = 'unconfirmed';
|
|
667
654
|
let stillParkedCause;
|
|
668
|
-
let stillParkedProven = false;
|
|
669
655
|
let statusSeen;
|
|
670
656
|
const wire = opts?.wire;
|
|
671
657
|
const resolved = engineWireFor(clientOnlyView(wire), DEFAULT_SESSION_KEY, usablePlanReviewWireClient);
|
|
@@ -708,7 +694,8 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
708
694
|
}
|
|
709
695
|
catch (e1) {
|
|
710
696
|
const conflict = e1;
|
|
711
|
-
|
|
697
|
+
const defaultConflict = mode === 'default' && conflict?.status === 400 && conflict?.errorCode === REQUEST_FIELD_CONFLICT;
|
|
698
|
+
if (defaultConflict && !directFailureVerdictOf(e1, directSafetyStopOf(e1)).yields) {
|
|
712
699
|
hostLog('debug', 'planReviewWire: permissionModeAfter "default" refused as not applicable — re-sending the approval without the key (same meaning)');
|
|
713
700
|
body = await sendOnce(undefined, () => client.assistant.planReview(taskId, reason !== undefined ? { decision, reason } : { decision }));
|
|
714
701
|
}
|
|
@@ -749,9 +736,7 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
749
736
|
const bodyStatus = bodyWordOf(body, 'status');
|
|
750
737
|
const effective = postStatus ?? bodyStatus;
|
|
751
738
|
statusSeen = effective;
|
|
752
|
-
|
|
753
|
-
effect = verdict.effect;
|
|
754
|
-
stillParkedProven = verdict.proven;
|
|
739
|
+
effect = planReviewSettledVerdict({ postStatus, bodyStatus, reparked: bodySaysReparked(body), gateBefore, gateAfter, gateKindAfter });
|
|
755
740
|
const code = bodyWordOf(body, 'errorCode');
|
|
756
741
|
if (effect === 'still_parked' && postStatus === 'needs_review' && !bodySaysReparked(body)) {
|
|
757
742
|
outcome =
|
|
@@ -797,14 +782,13 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
797
782
|
const noAnswer = typeof status === 'number' || typeof e !== 'object' ? null : noAnswerKindOf(e);
|
|
798
783
|
if (status === 400 && refusedCode === REQUEST_FIELD_CONFLICT && permissionModeAfter === 'acceptEdits') {
|
|
799
784
|
hostLog('debug', `planReviewWire: ${decision} + acceptEdits refused (request.field_conflict) — NOT re-sent with a different mode`);
|
|
800
|
-
effect = 'still_parked';
|
|
801
|
-
stillParkedProven = true;
|
|
785
|
+
effect = decision === 'approve' ? 'still_parked' : 'not_applied';
|
|
802
786
|
outcome =
|
|
803
787
|
decision === 'approve'
|
|
804
788
|
? 'The plan approval was NOT applied: the engine refused "auto-accept edits" for this task (it was not started read-only in plan mode, so that option does not apply). ' +
|
|
805
789
|
'Nothing changed engine-side — the plan is still waiting for review. Tell the user plainly, and that approving with "manually approve edits" will go through.'
|
|
806
790
|
: `The plan ${decision} was NOT applied: the engine refused the post-approval permission mode that was sent with it (request.field_conflict). ` +
|
|
807
|
-
'
|
|
791
|
+
'This request changed nothing engine-side. Tell the user plainly that the decision did not go through.';
|
|
808
792
|
}
|
|
809
793
|
else if (status === 404 && refusedCode === 'not_found.plan_review') {
|
|
810
794
|
hostLog('debug', `planReviewWire: ${decision} → 404 not_found.plan_review (no pending plan review any more — an earlier decision likely settled it)`);
|
|
@@ -817,7 +801,6 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
817
801
|
const cu = checkpointUnsupportedVersionFromError(e);
|
|
818
802
|
hostLog('debug', `planReviewWire: ${decision} → 409 checkpoint.unsupported_version (the server cannot continue this parked review in its stored form; still pending)`);
|
|
819
803
|
effect = 'still_parked';
|
|
820
|
-
stillParkedProven = true;
|
|
821
804
|
stillParkedCause = 'stored_form_unsupported';
|
|
822
805
|
outcome = `This ${decision} was not applied. ${checkpointUnsupportedVersionContent(cu, { parkKind: 'plan_review', runId: taskId })}`;
|
|
823
806
|
}
|
|
@@ -858,9 +841,9 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
858
841
|
const tail = planReviewOutcomeTail(taskId, decision, effect, stillParkedCause);
|
|
859
842
|
const prompt = `<plan-review-outcome>\n${outcome}\n${tail}\n</plan-review-outcome>`;
|
|
860
843
|
const onOutcome = opts?.onOutcome;
|
|
861
|
-
settle(effect === 'not_sent' ||
|
|
844
|
+
settle(effect === 'not_sent' || effect === 'still_parked');
|
|
862
845
|
try {
|
|
863
|
-
const delivered = enqueuePlanReviewOutcome(prompt, { taskId, dispatchNo, decision, effect });
|
|
846
|
+
const delivered = enqueuePlanReviewOutcome(prompt, { taskId, dispatchNo, decision, effect, ...(effect === 'still_parked' && stillParkedCause !== undefined ? { cause: stillParkedCause } : {}) });
|
|
864
847
|
if (!delivered) {
|
|
865
848
|
if (onOutcome !== undefined) {
|
|
866
849
|
hostLog('debug', `planReviewWire: outcome queue port not installed for task ${taskId} — outcome handed to the host's onOutcome callback only`);
|
|
@@ -875,7 +858,17 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
875
858
|
}
|
|
876
859
|
if (onOutcome !== undefined) {
|
|
877
860
|
try {
|
|
878
|
-
onOutcome({
|
|
861
|
+
onOutcome({
|
|
862
|
+
taskId,
|
|
863
|
+
dispatchNo,
|
|
864
|
+
decision,
|
|
865
|
+
effect,
|
|
866
|
+
...(effect === 'still_parked' && stillParkedCause !== undefined ? { cause: stillParkedCause } : {}),
|
|
867
|
+
detail: outcome,
|
|
868
|
+
tail,
|
|
869
|
+
prompt,
|
|
870
|
+
...(statusSeen !== undefined ? { status: statusSeen } : {}),
|
|
871
|
+
});
|
|
879
872
|
}
|
|
880
873
|
catch (e) {
|
|
881
874
|
hostLog('debug', `planReviewWire: onOutcome callback threw for task ${taskId} (ignored): ${String(e)}`);
|
|
@@ -912,10 +905,10 @@ function joinReopenFlight(flight, taskId, receiptMs) {
|
|
|
912
905
|
abortableSleep(Math.max(0, receiptMs), ac.signal).then(() => false),
|
|
913
906
|
]).then((presented) => {
|
|
914
907
|
ac.abort();
|
|
915
|
-
return presented ? { reopened: true, firstSight: false } :
|
|
908
|
+
return presented ? { reopened: true, firstSight: false } : refusedReopen('not_presented');
|
|
916
909
|
}, () => {
|
|
917
910
|
ac.abort();
|
|
918
|
-
return
|
|
911
|
+
return refusedReopen('not_presented');
|
|
919
912
|
});
|
|
920
913
|
}
|
|
921
914
|
function mintPlanReviewReopen(taskId, opts, sessionKey, receiptMs) {
|
|
@@ -955,10 +948,10 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
|
|
|
955
948
|
const markBefore = dismissalEntryFor(sessionKey, taskId);
|
|
956
949
|
const settleOnReceipt = (receipt, firstSight) => receipt.then((presented) => {
|
|
957
950
|
if (!presented)
|
|
958
|
-
return
|
|
951
|
+
return refusedReopen('not_presented');
|
|
959
952
|
revokePlanReviewUserDismissal(sessionKey, taskId, markBefore);
|
|
960
953
|
return { reopened: true, firstSight };
|
|
961
|
-
}, () => (
|
|
954
|
+
}, () => refusedReopen('not_presented'));
|
|
962
955
|
const canonicalId = planReviewQuestionId(taskId);
|
|
963
956
|
const armedKey = planReviewArmedKeyFor(sessionKey, taskId);
|
|
964
957
|
const firstSight = !wasGateArmedFor(sessionKey, armedKey);
|
|
@@ -992,7 +985,7 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
|
|
|
992
985
|
if (activeReopenResponders.get(activeKey)?.questionId === questionId) {
|
|
993
986
|
activeReopenResponders.delete(activeKey);
|
|
994
987
|
}
|
|
995
|
-
const choice =
|
|
988
|
+
const choice = planReviewAnswerChoiceOf(questionId, answer);
|
|
996
989
|
if (choice === 'dismissed') {
|
|
997
990
|
notePlanReviewUserDismissalFor(sessionKey, taskId, opts?.readGateInstanceKeys, questionId);
|
|
998
991
|
return { ok: true };
|
|
@@ -1017,6 +1010,9 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
|
|
|
1017
1010
|
publishQuestionFrameFor(sessionKey, planReviewQuestionFrame(questionId, REOPEN_QUESTION, false, true));
|
|
1018
1011
|
return settleOnReceipt(receipt, firstSight);
|
|
1019
1012
|
}
|
|
1013
|
+
function refusedReopen(cause) {
|
|
1014
|
+
return { reopened: false, _sema_reopenRefusal: cause };
|
|
1015
|
+
}
|
|
1020
1016
|
function noPresentationSurfaceVerdict(taskId, sessionKey) {
|
|
1021
1017
|
const verdict = { reopened: false, _sema_noPresentationSurface: true };
|
|
1022
1018
|
hostLog('debug', `planReviewWire: reopen for task ${taskId} refused — nothing is subscribed to question frames for session ` +
|
|
@@ -1039,7 +1035,7 @@ async function reopenAfterDismissalCheck(taskId, opts, sessionKey, receiptMs, ma
|
|
|
1039
1035
|
}
|
|
1040
1036
|
}
|
|
1041
1037
|
}
|
|
1042
|
-
const ledgerSaysInFlight =
|
|
1038
|
+
const ledgerSaysInFlight = decisionInFlightOf({ gate: 'plan_review', taskId }, recheckReadStart);
|
|
1043
1039
|
if (ledgerSaysInFlight) {
|
|
1044
1040
|
hostLog('debug', `planReviewWire: reopen for task ${taskId} refused after the dismissal check — a decision for this task went out while the check was reading`);
|
|
1045
1041
|
return { reopened: false, _sema_decisionInFlight: true };
|
|
@@ -1088,24 +1084,26 @@ async function staleDismissalVerdict(current, sessionKey, taskId, receiptMs) {
|
|
|
1088
1084
|
const windowEnd = abortableSleep(Math.max(0, receiptMs), ac.signal).then(() => false);
|
|
1089
1085
|
try {
|
|
1090
1086
|
let entry = current;
|
|
1087
|
+
let lastWaitPresented;
|
|
1091
1088
|
for (let round = 0; round < 8; round++) {
|
|
1092
1089
|
if (entry?.kind === 'decided')
|
|
1093
1090
|
return { reopened: false, _sema_decisionInFlight: true };
|
|
1094
1091
|
if (entry?.kind === 'dismissed')
|
|
1095
1092
|
return { reopened: false, dismissedByUser: true };
|
|
1096
1093
|
if (entry?.kind !== 'reopened' || entry.onScreen === undefined)
|
|
1097
|
-
return
|
|
1094
|
+
return refusedReopen(entry === undefined && lastWaitPresented === false ? 'not_presented' : 'gate_record_gone');
|
|
1098
1095
|
const onScreen = await Promise.race([
|
|
1099
1096
|
entry.onScreen.then((v) => v === true, () => false),
|
|
1100
1097
|
windowEnd,
|
|
1101
1098
|
]);
|
|
1102
1099
|
const now = dismissalEntryFor(sessionKey, taskId);
|
|
1103
1100
|
if (now === entry) {
|
|
1104
|
-
return onScreen ? { reopened: true, firstSight: !wasGateArmedFor(sessionKey, planReviewArmedKeyFor(sessionKey, taskId)) } :
|
|
1101
|
+
return onScreen ? { reopened: true, firstSight: !wasGateArmedFor(sessionKey, planReviewArmedKeyFor(sessionKey, taskId)) } : refusedReopen('not_presented');
|
|
1105
1102
|
}
|
|
1103
|
+
lastWaitPresented = onScreen;
|
|
1106
1104
|
entry = now;
|
|
1107
1105
|
}
|
|
1108
|
-
return
|
|
1106
|
+
return refusedReopen('gate_record_gone');
|
|
1109
1107
|
}
|
|
1110
1108
|
finally {
|
|
1111
1109
|
ac.abort();
|
|
@@ -1115,25 +1113,25 @@ export function reopenPlanReviewCard(taskId, opts) {
|
|
|
1115
1113
|
const receiptMs = opts?.presentationReceiptMs;
|
|
1116
1114
|
if (typeof receiptMs !== 'number' || Number.isNaN(receiptMs)) {
|
|
1117
1115
|
hostLog('debug', `planReviewWire: reopen for task ${String(taskId)} refused — presentationReceiptMs is required (a number of milliseconds); the synchronous form was retired in 0.98.0`);
|
|
1118
|
-
return Promise.resolve(
|
|
1116
|
+
return Promise.resolve(refusedReopen('invalid_call'));
|
|
1119
1117
|
}
|
|
1120
1118
|
try {
|
|
1121
1119
|
if (typeof taskId !== 'string' || taskId.length === 0) {
|
|
1122
|
-
return Promise.resolve(
|
|
1120
|
+
return Promise.resolve(refusedReopen('invalid_call'));
|
|
1123
1121
|
}
|
|
1124
1122
|
const injected = opts;
|
|
1125
1123
|
if (opts?.mintFreshQuestionId === false && (injected?.deliverDecision !== undefined || injected?.wire !== undefined || injected?.onOutcome !== undefined)) {
|
|
1126
1124
|
hostLog('error', `planReviewWire: plan_review reopen for task ${taskId} refused — mintFreshQuestionId:false reuses the armed card's responder and its delivery, ` +
|
|
1127
1125
|
'so deliverDecision / wire / onOutcome cannot be given with it; drop mintFreshQuestionId:false to deliver through the injected path');
|
|
1128
|
-
return Promise.resolve(
|
|
1126
|
+
return Promise.resolve(refusedReopen('invalid_call'));
|
|
1129
1127
|
}
|
|
1130
1128
|
const readStart = typeof opts.pendingReadStartedAt === 'number' && Number.isFinite(opts.pendingReadStartedAt) ? opts.pendingReadStartedAt : undefined;
|
|
1131
|
-
if (
|
|
1129
|
+
if (decisionInFlightOf({ gate: 'plan_review', taskId }, readStart)) {
|
|
1132
1130
|
hostLog('debug', `planReviewWire: reopen for task ${taskId} refused — a decision for this task is in flight (its answer is still being delivered)`);
|
|
1133
1131
|
const refused = { reopened: false, _sema_decisionInFlight: true };
|
|
1134
1132
|
return Promise.resolve(refused);
|
|
1135
1133
|
}
|
|
1136
|
-
const guardStartedAt =
|
|
1134
|
+
const guardStartedAt = decisionReadMark();
|
|
1137
1135
|
const recheckReadStart = readStart === undefined ? guardStartedAt : Math.min(readStart, guardStartedAt);
|
|
1138
1136
|
const sessionKey = opts.sessionKey ?? DEFAULT_SESSION_KEY;
|
|
1139
1137
|
if (!hasQuestionOverlayFor(sessionKey)) {
|
|
@@ -1144,7 +1142,7 @@ export function reopenPlanReviewCard(taskId, opts) {
|
|
|
1144
1142
|
'而缺省决断投递口(decidePlanReview)今天固定打默认槽的 baseUrl/token/principal。' +
|
|
1145
1143
|
'整条链转 keyed 之前,非默认槽要重开请自带 deliverDecision(按本槽投递);' +
|
|
1146
1144
|
'此处拒绝而不是照发 —— 照发会把这条会话的决断发到另一个槽上。');
|
|
1147
|
-
return Promise.resolve(
|
|
1145
|
+
return Promise.resolve(refusedReopen('no_delivery_path'));
|
|
1148
1146
|
}
|
|
1149
1147
|
const trigger = opts.trigger === undefined ? undefined : opts.trigger === 'user' ? 'user' : 'automatic';
|
|
1150
1148
|
if (trigger === 'automatic') {
|
|
@@ -1155,6 +1153,6 @@ export function reopenPlanReviewCard(taskId, opts) {
|
|
|
1155
1153
|
return mintPlanReviewReopen(taskId, opts, sessionKey, receiptMs);
|
|
1156
1154
|
}
|
|
1157
1155
|
catch {
|
|
1158
|
-
return Promise.resolve(
|
|
1156
|
+
return Promise.resolve(refusedReopen('internal_error'));
|
|
1159
1157
|
}
|
|
1160
1158
|
}
|
|
@@ -26,6 +26,7 @@ export declare function resumeRunningNoUiGuidance(i: {
|
|
|
26
26
|
taskId: string;
|
|
27
27
|
sessionId?: string | null;
|
|
28
28
|
}): string;
|
|
29
|
-
export declare function resumeAttachReplayDisclosure(taskId: string): string;
|
|
29
|
+
export declare function resumeAttachReplayDisclosure(taskId: string, lane?: CardSentenceLane): string;
|
|
30
|
+
export type CardSentenceLane = 'interactive' | 'print' | 'utility';
|
|
30
31
|
export declare function resumeRunningCancelConfirmedRow(taskId: string): string;
|
|
31
|
-
export declare function resumeRunningCancelUnconfirmedRow(taskId: string): string;
|
|
32
|
+
export declare function resumeRunningCancelUnconfirmedRow(taskId: string, lane?: CardSentenceLane): string;
|
|
@@ -62,22 +62,28 @@ export function resumeRunningNoUiGuidance(i) {
|
|
|
62
62
|
`${T} background=do nothing — run ${i.taskId} keeps executing on the engine; this client does not list it (read it with GET /v1/runs/${i.taskId})`,
|
|
63
63
|
].join('\n');
|
|
64
64
|
}
|
|
65
|
-
export function resumeAttachReplayDisclosure(taskId) {
|
|
65
|
+
export function resumeAttachReplayDisclosure(taskId, lane) {
|
|
66
66
|
return (`sema: attaching to run ${taskId} — sema is replaying it from the engine's ledger, so anything from that ` +
|
|
67
67
|
`turn already shown above will appear again below. There is no resume marker for a run that outlived its shell. ` +
|
|
68
|
-
`The replayed turns are not billed into this session's cost again either —
|
|
69
|
-
|
|
68
|
+
`The replayed turns are not billed into this session's cost again either — ` +
|
|
69
|
+
(interactiveCardLane(lane)
|
|
70
|
+
? `the engine's own record of run ${taskId} is the authority on what that run really spent.`
|
|
71
|
+
: `the engine's own record (GET /v1/runs/${taskId}) is the authority on what that run really spent.`));
|
|
70
72
|
}
|
|
71
|
-
function cancelRow(taskId, confirmed) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
`
|
|
73
|
+
function cancelRow(taskId, confirmed, lane) {
|
|
74
|
+
if (confirmed)
|
|
75
|
+
return `The engine accepted the cancel for run ${taskId} on your request. A cancel finishes on the engine's side, so that run may need a moment to stop.`;
|
|
76
|
+
return (`sema: the cancel for run ${taskId} did not come back confirmed, so that run may still be executing. ` +
|
|
77
|
+
(interactiveCardLane(lane)
|
|
78
|
+
? `This screen does not list it — its real state lives on the engine, under run ${taskId}, so do not assume this session is free.`
|
|
79
|
+
: `This screen does not list it — read its real state on the engine (GET /v1/runs/${taskId}) before assuming this session is free.`));
|
|
80
|
+
}
|
|
81
|
+
function interactiveCardLane(lane) {
|
|
82
|
+
return lane !== 'print' && lane !== 'utility';
|
|
77
83
|
}
|
|
78
84
|
export function resumeRunningCancelConfirmedRow(taskId) {
|
|
79
85
|
return cancelRow(taskId, true);
|
|
80
86
|
}
|
|
81
|
-
export function resumeRunningCancelUnconfirmedRow(taskId) {
|
|
82
|
-
return cancelRow(taskId, false);
|
|
87
|
+
export function resumeRunningCancelUnconfirmedRow(taskId, lane) {
|
|
88
|
+
return cancelRow(taskId, false, lane);
|
|
83
89
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { SessionPermissionRules } from '@sema-agent/sdk';
|
|
2
2
|
import type { ToolRosterView } from '../toolRoster.js';
|
|
3
|
+
import type { SessionRulesNamespaceFormsReading } from '../sessionRulesNamespaceFormsCapability.js';
|
|
4
|
+
import type { UiLanguage } from '../env/uiLanguage.js';
|
|
3
5
|
import type { SessionRuleInertReason } from './sessionPolicyWire.js';
|
|
4
|
-
export type SessionPolicyWithheldWhy = 'ask_no_bucket' | 'qualified_deny' | 'peer_wide' | 'wildcard' | 'not_a_tool_name' | 'legacy_tool_name' | 'not_in_roster';
|
|
6
|
+
export type SessionPolicyWithheldWhy = 'ask_no_bucket' | 'qualified_deny' | 'peer_wide' | 'wildcard' | 'not_a_tool_name' | 'legacy_tool_name' | 'not_in_roster' | 'namespace_covering_unconfirmed';
|
|
5
7
|
export declare const SESSION_POLICY_WITHHELD_WHY: readonly SessionPolicyWithheldWhy[];
|
|
6
8
|
export interface SessionPolicyWithheldRule {
|
|
7
9
|
readonly rule: string;
|
|
@@ -16,7 +18,8 @@ export interface SessionPolicyDeliverability {
|
|
|
16
18
|
}
|
|
17
19
|
export interface SessionPolicyDeliverableOptions {
|
|
18
20
|
readonly roster?: ToolRosterView;
|
|
21
|
+
readonly namespaceForms?: SessionRulesNamespaceFormsReading;
|
|
19
22
|
}
|
|
20
23
|
export declare function sessionPolicyDeliverable(behavior: 'deny' | 'ask', rules: readonly string[], opts?: SessionPolicyDeliverableOptions): SessionPolicyDeliverability;
|
|
21
|
-
export declare function sessionPolicyWithheldNotice(why: SessionPolicyWithheldWhy): string;
|
|
24
|
+
export declare function sessionPolicyWithheldNotice(why: SessionPolicyWithheldWhy, lang?: UiLanguage): string;
|
|
22
25
|
export declare function legacyToolNameFailureNoteOf(code: string | undefined): string | undefined;
|