@sema-agent/client-core 0.100.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 +395 -0
- package/README.md +164 -117
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.js +9 -8
- package/dist/adapt.js +7 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +158 -43
- package/dist/agentsWireCaps.d.ts +2 -7
- package/dist/agentsWireCaps.js +1 -2
- 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 +19 -5
- package/dist/cloudConfigWireCaps.js +193 -56
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +5 -3
- 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 +65 -8
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +14 -5
- package/dist/engineErrorCodes.js +27 -6
- 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 +3 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.js +2 -2
- 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/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.js +3 -3
- 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 -3
- package/dist/generated/engineFactTables.js +52 -0
- package/dist/generated/engineNoticeTables.js +12 -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 +54 -0
- package/dist/generated/settingsSchemaFns.js +26 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
- 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 +2 -0
- package/dist/generated/settingsSchemaTables.js +13 -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 +7 -5
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- 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/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +6 -0
- package/dist/hitl/askClassPair.js +30 -3
- 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 +42 -3
- package/dist/hitl/attributionLadder.js +79 -8
- 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/decisionRefusal.d.ts +20 -10
- package/dist/hitl/decisionRefusal.js +99 -54
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +87 -103
- 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 +41 -37
- 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 +59 -30
- 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 +62 -29
- 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 +72 -54
- 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 +73 -17
- package/dist/hostTurnSettings.js +594 -97
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +37 -7
- 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 +184 -2
- package/dist/i18n/messages.en.js +187 -5
- package/dist/i18n/messages.zh.js +197 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +69 -15
- package/dist/index.js +45 -13
- package/dist/inheritEnvCapability.d.ts +3 -1
- package/dist/inheritEnvCapability.js +31 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- 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 +1 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.js +2 -1
- package/dist/mcpWireCaps.d.ts +39 -1
- package/dist/mcpWireCaps.js +254 -50
- 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.js +6 -6
- package/dist/modelIdentityResolvability.d.ts +10 -1
- package/dist/modelIdentityResolvability.js +62 -39
- 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 +11 -0
- package/dist/ownKey.js +164 -3
- package/dist/panelReduce.js +1 -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.js +2 -0
- 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 +92 -53
- package/dist/prepareRefusal.d.ts +3 -2
- package/dist/prepareRefusal.js +27 -9
- 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 +12 -4
- package/dist/request/taskRequest.js +221 -152
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +57 -9
- 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 +4 -0
- package/dist/ruleRefusalSentence.js +9 -3
- 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 +1 -1
- package/dist/sandboxWire.js +4 -6
- package/dist/scenarioRefusal.js +1 -1
- 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 +2 -0
- package/dist/seam.js +2 -2
- package/dist/seatContract.d.ts +46 -1
- package/dist/seatContract.js +49 -19
- 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.js +60 -5
- 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 -0
- package/dist/skillsWireCaps.js +47 -16
- 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/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/turnFailurePresentation.js +27 -90
- 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 +24 -1
- package/dist/wireRefusalCopy.js +253 -32
- 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 +607 -181
- package/package.json +14 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { AgentEvent, ApprovalDecidedBy, ApprovalDecision, ApprovalStaleError, PendingCheckpoint, CheckpointGate, PlanReviewRequest, AssistantTaskStatus } from '@sema-agent/sdk';
|
|
1
|
+
import type { AgentEvent, ApprovalDecidedBy, ApprovalDecision, ApprovalStaleError, PendingCheckpoint, CheckpointGate, PlanReviewRequest, AssistantTaskStatus, QuestionAnswerItem } from '@sema-agent/sdk';
|
|
2
2
|
import type { PermissionResult } from '@sema-agent/agent-types';
|
|
3
|
+
import { type CapturedLocalCode, type CauseSlotRead } from '../engineWireFor.js';
|
|
3
4
|
import type { ApprovalsListEnvelope } from './crashConverged.js';
|
|
4
5
|
import { type SuspendedReopenReading } from './suspendedReopen.js';
|
|
5
6
|
export declare const DEFAULT_DENY_REASON = "The user rejected this tool use";
|
|
@@ -33,11 +34,7 @@ export interface HitlClientLike {
|
|
|
33
34
|
approvals: ApprovalsResourceLike;
|
|
34
35
|
assistant: AssistantResourceLike;
|
|
35
36
|
}
|
|
36
|
-
export
|
|
37
|
-
header: string;
|
|
38
|
-
selected: string[];
|
|
39
|
-
note?: string;
|
|
40
|
-
}
|
|
37
|
+
export type AskAnswer = QuestionAnswerItem;
|
|
41
38
|
export interface PlanReviewOutcome {
|
|
42
39
|
decision: 'approve' | 'edit' | 'reject';
|
|
43
40
|
editedPlan?: string;
|
|
@@ -63,6 +60,21 @@ export declare class HitlSafetyError extends Error {
|
|
|
63
60
|
readonly code: HitlSafetyCode;
|
|
64
61
|
constructor(message: string, code: HitlSafetyCode, options?: ErrorOptions);
|
|
65
62
|
}
|
|
63
|
+
export interface RefusalCarrier {
|
|
64
|
+
readonly local?: HitlSafetyCode;
|
|
65
|
+
readonly carrier: {} | null | undefined;
|
|
66
|
+
}
|
|
67
|
+
export declare function refusalCarrierOf(err: {} | null | undefined, localCodeRead?: {
|
|
68
|
+
readonly value: CapturedLocalCode;
|
|
69
|
+
}, answeredLayer?: boolean, causeRead?: CauseSlotRead, headRead?: SafetyStopHead): RefusalCarrier;
|
|
70
|
+
export declare function safetyStopNamed(err: {} | null | undefined): boolean;
|
|
71
|
+
export interface SafetyStopHead {
|
|
72
|
+
readonly named: boolean;
|
|
73
|
+
readonly local?: HitlSafetyCode;
|
|
74
|
+
}
|
|
75
|
+
export declare function safetyStopHeadOf(err: {} | null | undefined, localCodeRead?: {
|
|
76
|
+
readonly value: CapturedLocalCode;
|
|
77
|
+
}, namedRead?: boolean): SafetyStopHead;
|
|
66
78
|
export declare function hitlSafetyCodeOf(e: unknown): HitlSafetyCode | undefined;
|
|
67
79
|
export type GateCurrentPending = Readonly<NonNullable<ApprovalStaleError['currentPending']>>;
|
|
68
80
|
export declare function readDecideCurrentPending(e: unknown): GateCurrentPending | undefined;
|
package/dist/hitl/hitlBridge.js
CHANGED
|
@@ -3,11 +3,13 @@ import { eventSeq } from '../adapter/types.js';
|
|
|
3
3
|
import { hostLog } from '../host.js';
|
|
4
4
|
import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
|
|
5
5
|
import { abortableSleep } from '../abortableSleep.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { attemptTimeoutOnChain, causeSlotReadOf, transportChainReading } from '../engineWireFor.js';
|
|
7
|
+
import { guardedRead, ownDataField, readOwnDataValue } from '../ownKey.js';
|
|
8
|
+
import { PROTOCOL_ERROR_NAME, isSlotCarrier, protocolErrorNameReading, readBlockedBy, readThrownSlot, thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
|
|
8
9
|
import { APPROVAL_BINDING_MISMATCH, CHECKPOINT_INVALID_OUTCOME, RESUME_POLICY_FOLD_CODE } from '../engineErrorCodes.js';
|
|
9
10
|
import { suspendedReopenOf } from './suspendedReopen.js';
|
|
10
11
|
import { closeDecisionOp, decisionLedgerKeysOf, openDecisionOp } from './decisionLedger.js';
|
|
12
|
+
import { askParkBlockGeneration, noteAskParkDecideSettled } from './askParkAutoReopenBlock.js';
|
|
11
13
|
export const DEFAULT_DENY_REASON = 'The user rejected this tool use';
|
|
12
14
|
export const MAX_DENY_REASON_CHARS = 4096;
|
|
13
15
|
export function denyReasonForWire(reason, tag) {
|
|
@@ -53,6 +55,30 @@ export class HitlSafetyError extends Error {
|
|
|
53
55
|
this.name = 'HitlSafetyError';
|
|
54
56
|
}
|
|
55
57
|
}
|
|
58
|
+
export function refusalCarrierOf(err, localCodeRead, answeredLayer = false, causeRead, headRead) {
|
|
59
|
+
if (!isSlotCarrier(err))
|
|
60
|
+
return { carrier: err };
|
|
61
|
+
const head = headRead ?? safetyStopHeadOf(err, localCodeRead);
|
|
62
|
+
if (!head.named)
|
|
63
|
+
return { carrier: err };
|
|
64
|
+
const read = answeredLayer ? undefined : (causeRead ?? causeSlotReadOf(err));
|
|
65
|
+
const cause = read !== undefined && read.presence === 'present' ? read.value : undefined;
|
|
66
|
+
const carrier = isSlotCarrier(cause) ? cause : err;
|
|
67
|
+
return head.local !== undefined ? { local: head.local, carrier } : { carrier };
|
|
68
|
+
}
|
|
69
|
+
export function safetyStopNamed(err) {
|
|
70
|
+
return isSlotCarrier(err) && guardedRead(() => ownDataField(err, 'name')) === 'HitlSafetyError';
|
|
71
|
+
}
|
|
72
|
+
export function safetyStopHeadOf(err, localCodeRead, namedRead) {
|
|
73
|
+
if (!isSlotCarrier(err))
|
|
74
|
+
return { named: false };
|
|
75
|
+
if (!(namedRead ?? safetyStopNamed(err)))
|
|
76
|
+
return { named: false };
|
|
77
|
+
const own = (k) => guardedRead(() => ownDataField(err, k));
|
|
78
|
+
const code = localCodeRead !== undefined ? localCodeRead.value : own('code');
|
|
79
|
+
const local = typeof code === 'string' && GATE_FAILURE_CODES.includes(code) ? code : undefined;
|
|
80
|
+
return local !== undefined ? { named: true, local } : { named: true };
|
|
81
|
+
}
|
|
56
82
|
export function hitlSafetyCodeOf(e) {
|
|
57
83
|
if (!thrownIsInstanceOf(e, HitlSafetyError))
|
|
58
84
|
return undefined;
|
|
@@ -70,12 +96,12 @@ void _gateCurrentPendingReadonlyPin;
|
|
|
70
96
|
export function readDecideCurrentPending(e) {
|
|
71
97
|
if (e === null || e === undefined)
|
|
72
98
|
return undefined;
|
|
73
|
-
const raw = readThrownSlot(e, 'currentPending');
|
|
99
|
+
const raw = readThrownSlot(e, 'currentPending', 'data');
|
|
74
100
|
if (typeof raw !== 'object' || raw === null)
|
|
75
101
|
return undefined;
|
|
76
|
-
const toolName = readThrownSlot(raw, 'toolName');
|
|
77
|
-
const boundCallId = readThrownSlot(raw, 'boundCallId');
|
|
78
|
-
const boundInputHash = readThrownSlot(raw, 'boundInputHash');
|
|
102
|
+
const toolName = readThrownSlot(raw, 'toolName', 'data');
|
|
103
|
+
const boundCallId = readThrownSlot(raw, 'boundCallId', 'data');
|
|
104
|
+
const boundInputHash = readThrownSlot(raw, 'boundInputHash', 'data');
|
|
79
105
|
if (typeof toolName !== 'string' || toolName.length === 0)
|
|
80
106
|
return undefined;
|
|
81
107
|
if (typeof boundCallId !== 'string' || boundCallId.length === 0)
|
|
@@ -130,36 +156,8 @@ export function __setDecideTimeoutRetryBudgetForTests(ms) {
|
|
|
130
156
|
function decideTimeoutRetryBudgetMs() {
|
|
131
157
|
return decideTimeoutRetryBudgetOverrideMs ?? DECIDE_TIMEOUT_RETRY_TOTAL_BUDGET_MS;
|
|
132
158
|
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
return false;
|
|
136
|
-
if (readThrownSlot(e, 'name') === 'TimeoutError')
|
|
137
|
-
return true;
|
|
138
|
-
return isDecideAttemptTimeout(readThrownSlot(e, 'cause'), depth + 1);
|
|
139
|
-
}
|
|
140
|
-
const TRANSIENT_NETWORK_CODES = new Set([
|
|
141
|
-
'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN',
|
|
142
|
-
'ENETUNREACH', 'EHOSTUNREACH', 'ECONNABORTED',
|
|
143
|
-
'UND_ERR_CONNECT_TIMEOUT', 'UND_ERR_HEADERS_TIMEOUT', 'UND_ERR_BODY_TIMEOUT', 'UND_ERR_SOCKET',
|
|
144
|
-
]);
|
|
145
|
-
function isTransientDecideTransportFailure(e, depth = 0) {
|
|
146
|
-
if (depth > 3 || e === null || typeof e !== 'object')
|
|
147
|
-
return false;
|
|
148
|
-
if (thrownIsInstanceOf(e, HitlSafetyError))
|
|
149
|
-
return false;
|
|
150
|
-
const status = readThrownSlot(e, 'status', 'data');
|
|
151
|
-
if (status === THROWN_SLOT_UNREADABLE || typeof status === 'number')
|
|
152
|
-
return false;
|
|
153
|
-
const name = readThrownSlot(e, 'name');
|
|
154
|
-
if (name === 'TimeoutError' || name === 'AbortError')
|
|
155
|
-
return true;
|
|
156
|
-
const code = readThrownSlot(e, 'code', 'data');
|
|
157
|
-
if (typeof code === 'string' && TRANSIENT_NETWORK_CODES.has(code))
|
|
158
|
-
return true;
|
|
159
|
-
const message = readThrownSlot(e, 'message');
|
|
160
|
-
if (typeof message === 'string' && message.toLowerCase().includes('fetch failed'))
|
|
161
|
-
return true;
|
|
162
|
-
return isTransientDecideTransportFailure(readThrownSlot(e, 'cause'), depth + 1);
|
|
159
|
+
function isTransientDecideTransportFailure(e) {
|
|
160
|
+
return transportChainReading(e, 'retry', (layer) => thrownIsInstanceOf(layer, HitlSafetyError)) === 'transient';
|
|
163
161
|
}
|
|
164
162
|
export class DecideTransportRetryExhaustedError extends Error {
|
|
165
163
|
attempts;
|
|
@@ -199,15 +197,18 @@ class DecideSpan {
|
|
|
199
197
|
}
|
|
200
198
|
this.inFlight++;
|
|
201
199
|
const tally = { attempts: 0 };
|
|
200
|
+
const blockGen = askParkBlockGeneration(identity.sessionId);
|
|
202
201
|
try {
|
|
203
202
|
const r = await send(tally);
|
|
204
203
|
this.ok = true;
|
|
205
204
|
this.retryExhausted = false;
|
|
205
|
+
noteAskParkDecideSettled(identity, blockGen, { ok: true });
|
|
206
206
|
return r;
|
|
207
207
|
}
|
|
208
208
|
catch (e) {
|
|
209
209
|
this.ok = false;
|
|
210
210
|
this.retryExhausted = thrownIsInstanceOf(e, DecideTransportRetryExhaustedError);
|
|
211
|
+
noteAskParkDecideSettled(identity, blockGen, { ok: false, error: e });
|
|
211
212
|
throw e;
|
|
212
213
|
}
|
|
213
214
|
finally {
|
|
@@ -419,6 +420,7 @@ export class HitlBridge {
|
|
|
419
420
|
const tally = { attempts: 0 };
|
|
420
421
|
const identity = this.decideIdentityOf(sessionId, decision);
|
|
421
422
|
const ledgerOp = openDecideLedgerOp(identity);
|
|
423
|
+
const blockGen = askParkBlockGeneration(identity.sessionId);
|
|
422
424
|
if (observer !== undefined)
|
|
423
425
|
notifyDecideObserver(observer, Object.freeze({ ...identity, phase: 'start' }));
|
|
424
426
|
let ok = false;
|
|
@@ -426,10 +428,12 @@ export class HitlBridge {
|
|
|
426
428
|
try {
|
|
427
429
|
const r = await this.decideRawAttempts(sessionId, decision, opts, tally);
|
|
428
430
|
ok = true;
|
|
431
|
+
noteAskParkDecideSettled(identity, blockGen, { ok: true });
|
|
429
432
|
return r;
|
|
430
433
|
}
|
|
431
434
|
catch (e) {
|
|
432
435
|
retryExhausted = thrownIsInstanceOf(e, DecideTransportRetryExhaustedError);
|
|
436
|
+
noteAskParkDecideSettled(identity, blockGen, { ok: false, error: e });
|
|
433
437
|
throw e;
|
|
434
438
|
}
|
|
435
439
|
finally {
|
|
@@ -473,7 +477,7 @@ export class HitlBridge {
|
|
|
473
477
|
throw e;
|
|
474
478
|
if (!isTransientDecideTransportFailure(e) || callerAborted())
|
|
475
479
|
throw e;
|
|
476
|
-
if (
|
|
480
|
+
if (attemptTimeoutOnChain(e)) {
|
|
477
481
|
if (attempts >= DECIDE_TIMEOUT_MIN_ATTEMPTS && Date.now() - startedAt >= decideTimeoutRetryBudgetMs()) {
|
|
478
482
|
throw new DecideTransportRetryExhaustedError(attempts, wireFailureTextsOf(e).reason);
|
|
479
483
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { appendOwnElement } from '../ownKey.js';
|
|
1
2
|
import { readRequiresRealApproval } from './approvalCardReading.js';
|
|
2
3
|
import { THROWN_SLOT_UNREADABLE, readThrownSlot } from '../wireFailureShape.js';
|
|
3
4
|
import { isToolApprovalFrame, surfaceToolApprovalFrameAndRespond, } from './toolApprovalWire.js';
|
|
@@ -14,9 +15,9 @@ function snapshotMembers(raw) {
|
|
|
14
15
|
const out = [];
|
|
15
16
|
for (let i = 0; i < length; i++) {
|
|
16
17
|
const d = Object.getOwnPropertyDescriptor(raw, i);
|
|
17
|
-
if (d === undefined || !('value'
|
|
18
|
+
if (d === undefined || !Object.hasOwn(d, 'value'))
|
|
18
19
|
return undefined;
|
|
19
|
-
out
|
|
20
|
+
appendOwnElement(out, d.value);
|
|
20
21
|
}
|
|
21
22
|
return raw.length === length ? out : undefined;
|
|
22
23
|
}
|
|
@@ -26,7 +27,7 @@ export function readLivePendingRows(body) {
|
|
|
26
27
|
const field = Object.getOwnPropertyDescriptor(body, 'livePending');
|
|
27
28
|
if (field === undefined)
|
|
28
29
|
return 'livePending' in body ? { kind: 'malformed' } : { kind: 'not_reported' };
|
|
29
|
-
if (!('value'
|
|
30
|
+
if (!Object.hasOwn(field, 'value'))
|
|
30
31
|
return { kind: 'malformed' };
|
|
31
32
|
const raw = field.value;
|
|
32
33
|
if (raw === undefined)
|
|
@@ -4,7 +4,7 @@ function ladderSays(ladder, key) {
|
|
|
4
4
|
return false;
|
|
5
5
|
try {
|
|
6
6
|
const d = Object.getOwnPropertyDescriptor(ladder, key);
|
|
7
|
-
return d !== undefined && 'value'
|
|
7
|
+
return d !== undefined && Object.hasOwn(d, 'value') && d.value === true;
|
|
8
8
|
}
|
|
9
9
|
catch {
|
|
10
10
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { putOwnKey, readOwnDataValue } from '../ownKey.js';
|
|
2
2
|
import { HitlBridge, NO_QUESTION_OVERLAY_REASON, findPendingForTask, isNoDecisionSurfaceReason, } from './hitlBridge.js';
|
|
3
|
-
import { approvalResolutionDetail, resolutionOfDecisionFailure } from './approvalResolution.js';
|
|
3
|
+
import { approvalResolutionDetail, directSafetyStopOf, resolutionOfDecisionFailure } from './approvalResolution.js';
|
|
4
4
|
import { readDecisionRefusalAsk } from './decisionRefusal.js';
|
|
5
5
|
import { publishQuestionFrame, registerLocalQuestionResponder, hasQuestionOverlay, } from '../liveQuestionStore.js';
|
|
6
6
|
import { hostLog } from '../host.js';
|
|
@@ -136,9 +136,10 @@ async function surfaceGateAndDecide(deps, taskId, askArgsByCall, signal, parkGat
|
|
|
136
136
|
return { kind: 'decided', ...at, decision: 'deny', ...(declinedReceipt !== undefined ? { receipt: declinedReceipt } : {}) };
|
|
137
137
|
}
|
|
138
138
|
catch (e) {
|
|
139
|
+
const directStop = directSafetyStopOf(e);
|
|
139
140
|
const failureTexts = wireFailureTextsOf(e);
|
|
140
141
|
hostLog('debug', `liveHitlAskWire: decide failed: ${failureTexts.log}`);
|
|
141
|
-
return resolutionOfDecisionFailure(e, { lane: 'ask', route: 'ask_decide', gatedCallId, detail: `decide failed: ${failureTexts.reason}${decideFailureNote(e, attemptedDecision)}
|
|
142
|
+
return resolutionOfDecisionFailure(e, { lane: 'ask', route: 'ask_decide', gatedCallId, detail: `decide failed: ${failureTexts.reason}${decideFailureNote(e, attemptedDecision)}`, ...(directStop !== undefined ? { directStop } : {}) });
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
function argsByCallOf(led) {
|
|
@@ -207,6 +207,7 @@ const PERSISTED_RULE_MATCH_KEYS = Object.freeze({
|
|
|
207
207
|
name_prefix: 'rules.match.namePrefix',
|
|
208
208
|
host: 'rules.match.host',
|
|
209
209
|
subdomain: 'rules.match.subdomain',
|
|
210
|
+
pattern: 'rules.match.pattern',
|
|
210
211
|
});
|
|
211
212
|
export function persistedRuleMatchLabel(ruleOrMatch, lang) {
|
|
212
213
|
const word = typeof ruleOrMatch === 'string' ? ruleOrMatch : ownSlot(ruleOrMatch, 'match');
|
|
@@ -43,6 +43,9 @@ export interface PlanReviewQuestionIdReading {
|
|
|
43
43
|
}
|
|
44
44
|
export declare function planReviewTaskIdFromQuestionId(questionId: {} | null | undefined): PlanReviewQuestionIdReading | undefined;
|
|
45
45
|
export declare function planReviewOfferedModeOf(card: string | PlanReviewCardLike): PlanReviewOfferedMode;
|
|
46
|
+
export declare function planReviewShownLabelsOf(questionId: {} | null | undefined): readonly string[] | undefined;
|
|
47
|
+
export declare function planReviewAnswerChoiceOf(questionId: {} | null | undefined, answer: QuestionAnswer | null | undefined): PlanReviewChoice | 'dismissed';
|
|
48
|
+
export declare function planReviewAnswerDecisionOf(questionId: {} | null | undefined, answer: QuestionAnswer | null | undefined): 'approve' | 'reject' | 'dismissed';
|
|
46
49
|
export interface ArmPlanReviewOptions {
|
|
47
50
|
submittedInPlanMode?: boolean;
|
|
48
51
|
readGateInstanceKeys?: PlanReviewGateInstanceReader;
|
|
@@ -56,6 +59,7 @@ export interface PlanReviewOutcomeMeta {
|
|
|
56
59
|
dispatchNo: number;
|
|
57
60
|
decision: 'approve' | 'reject';
|
|
58
61
|
effect: PlanReviewDecisionEffect;
|
|
62
|
+
cause?: 'stored_form_unsupported';
|
|
59
63
|
}
|
|
60
64
|
export declare function planReviewOutcomeTail(taskId: string, decision: 'approve' | 'reject', effect: PlanReviewDecisionEffect, cause?: 'stored_form_unsupported'): string;
|
|
61
65
|
export type PlanReviewWireClient = {
|
|
@@ -7,10 +7,11 @@ 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';
|
|
14
15
|
import { __resetDecisionLedgerForTests, decisionInFlightOf, decisionKeyInFlight, decisionLedgerKeysOf, decisionOpsWithKey, decisionReadMark, dropDecisionOp, latestDecisionHandedMark, markLatestDecisionNotApplied, openDecisionOp, planDecisionKey, readMarkOf, settleDecisionOp, settleDecisionOpsOnGateLeft, } from './decisionLedger.js';
|
|
15
16
|
import { denyReasonForWire, isPlanReviewModeAfter } from './hitlBridge.js';
|
|
16
17
|
import { planReviewQuestionId, REOPEN_ID_TAIL, taskIdFromPlanReviewQuestionId } from './gateIdentity.js';
|
|
@@ -26,12 +27,8 @@ export const PLAN_REVIEW_APPROVE_MANUAL_LABEL = 'Yes, and manually approve edits
|
|
|
26
27
|
const APPROVE_LABEL = PLAN_REVIEW_APPROVE_LABEL;
|
|
27
28
|
const REJECT_LABEL = PLAN_REVIEW_REJECT_LABEL;
|
|
28
29
|
const LEGACY_TWO_CHOICE_LABELS = Object.freeze([PLAN_REVIEW_APPROVE_LABEL, PLAN_REVIEW_REJECT_LABEL]);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
PLAN_REVIEW_APPROVE_MANUAL_LABEL,
|
|
32
|
-
PLAN_REVIEW_APPROVE_LABEL,
|
|
33
|
-
PLAN_REVIEW_REJECT_LABEL,
|
|
34
|
-
]);
|
|
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]);
|
|
35
32
|
export function planReviewDecisionFromAnswer(answer, shownLabels = LEGACY_TWO_CHOICE_LABELS) {
|
|
36
33
|
const { choice } = readPlanReviewAnswer(answer, shownLabels);
|
|
37
34
|
if (choice === 'dismissed')
|
|
@@ -101,7 +98,7 @@ export function notePlanReviewAnsweredIfDecisive(questionId, answer) {
|
|
|
101
98
|
notePlanReviewAnsweredIfDecisiveFor(DEFAULT_SESSION_KEY, questionId, answer);
|
|
102
99
|
}
|
|
103
100
|
function notePlanReviewAnsweredIfDecisiveFor(sessionKey, questionId, answer) {
|
|
104
|
-
if (planReviewDecisionFromAnswer(answer ?? { answers: [] },
|
|
101
|
+
if (planReviewDecisionFromAnswer(answer ?? { answers: [] }, planReviewShownLabelsOf(questionId) ?? ANY_CARD_SHAPE_LABELS) === 'dismissed')
|
|
105
102
|
return;
|
|
106
103
|
notePlanReviewAnsweredFor(sessionKey, questionId);
|
|
107
104
|
const taskId = typeof questionId === 'string' ? taskIdFromPlanReviewQuestionId(questionId) : undefined;
|
|
@@ -276,7 +273,7 @@ function ownElementsOf(v, max) {
|
|
|
276
273
|
const n = Math.min(v.length, max);
|
|
277
274
|
const out = [];
|
|
278
275
|
for (let i = 0; i < n; i++)
|
|
279
|
-
out
|
|
276
|
+
appendOwnElement(out, readOwnDataValue(v, String(i)));
|
|
280
277
|
return out;
|
|
281
278
|
}
|
|
282
279
|
function offeredModeFromLabels(card) {
|
|
@@ -333,6 +330,33 @@ export function planReviewOfferedModeOf(card) {
|
|
|
333
330
|
return 'unknown';
|
|
334
331
|
}
|
|
335
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
|
+
}
|
|
336
360
|
export function armPlanReviewApproval(result, sessionKey, opts) {
|
|
337
361
|
let armedTaskId;
|
|
338
362
|
try {
|
|
@@ -378,10 +402,9 @@ export function armPlanReviewApproval(result, sessionKey, opts) {
|
|
|
378
402
|
offerModeAfterByTask.delete(taskId);
|
|
379
403
|
const questionId = planReviewQuestionId(taskId);
|
|
380
404
|
const unregister = registerLocalQuestionResponder(questionId, async (_id, answer) => {
|
|
405
|
+
const choice = planReviewAnswerChoiceOf(questionId, answer);
|
|
381
406
|
unregister();
|
|
382
407
|
armedPlanReviewTaskIds.delete(taskId);
|
|
383
|
-
const shown = planReviewCardOptions(offerModeAfterByTask.get(taskId) === true).map(o => o.label);
|
|
384
|
-
const choice = planReviewChoiceFromAnswer(answer, shown);
|
|
385
408
|
if (choice === 'dismissed') {
|
|
386
409
|
notePlanReviewUserDismissalFor(DEFAULT_SESSION_KEY, taskId, opts?.readGateInstanceKeys, questionId);
|
|
387
410
|
return { ok: true };
|
|
@@ -539,22 +562,22 @@ function planReviewSettledVerdict(r) {
|
|
|
539
562
|
const status = r.postStatus ?? r.bodyStatus;
|
|
540
563
|
const gateMoved = r.gateBefore !== undefined && r.gateAfter !== undefined && r.gateAfter !== r.gateBefore;
|
|
541
564
|
if (r.reparked)
|
|
542
|
-
return status !== 'completed' && !gateMoved ?
|
|
565
|
+
return status !== 'completed' && !gateMoved ? 'still_parked' : 'unconfirmed';
|
|
543
566
|
if (status === 'completed')
|
|
544
|
-
return
|
|
567
|
+
return 'took_effect';
|
|
545
568
|
const newGateHasCard = () => {
|
|
546
569
|
const leg = durableDecideLegOf({ gateKind: r.gateKindAfter ?? null });
|
|
547
570
|
return leg === 'approval' || leg === 'plan_review';
|
|
548
571
|
};
|
|
549
572
|
if (status === 'suspended' && r.postStatus === 'suspended' && newGateHasCard())
|
|
550
|
-
return
|
|
573
|
+
return 'advanced';
|
|
551
574
|
if (status === 'needs_review' && r.postStatus === 'needs_review' && r.gateBefore !== undefined && r.gateAfter !== undefined) {
|
|
552
575
|
if (r.gateAfter === r.gateBefore)
|
|
553
|
-
return
|
|
576
|
+
return 'still_parked';
|
|
554
577
|
if (newGateHasCard())
|
|
555
|
-
return
|
|
578
|
+
return 'advanced';
|
|
556
579
|
}
|
|
557
|
-
return
|
|
580
|
+
return 'unconfirmed';
|
|
558
581
|
}
|
|
559
582
|
function bodyWordOf(body, key) {
|
|
560
583
|
try {
|
|
@@ -629,7 +652,6 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
629
652
|
let outcome;
|
|
630
653
|
let effect = 'unconfirmed';
|
|
631
654
|
let stillParkedCause;
|
|
632
|
-
let stillParkedProven = false;
|
|
633
655
|
let statusSeen;
|
|
634
656
|
const wire = opts?.wire;
|
|
635
657
|
const resolved = engineWireFor(clientOnlyView(wire), DEFAULT_SESSION_KEY, usablePlanReviewWireClient);
|
|
@@ -672,7 +694,8 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
672
694
|
}
|
|
673
695
|
catch (e1) {
|
|
674
696
|
const conflict = e1;
|
|
675
|
-
|
|
697
|
+
const defaultConflict = mode === 'default' && conflict?.status === 400 && conflict?.errorCode === REQUEST_FIELD_CONFLICT;
|
|
698
|
+
if (defaultConflict && !directFailureVerdictOf(e1, directSafetyStopOf(e1)).yields) {
|
|
676
699
|
hostLog('debug', 'planReviewWire: permissionModeAfter "default" refused as not applicable — re-sending the approval without the key (same meaning)');
|
|
677
700
|
body = await sendOnce(undefined, () => client.assistant.planReview(taskId, reason !== undefined ? { decision, reason } : { decision }));
|
|
678
701
|
}
|
|
@@ -713,9 +736,7 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
713
736
|
const bodyStatus = bodyWordOf(body, 'status');
|
|
714
737
|
const effective = postStatus ?? bodyStatus;
|
|
715
738
|
statusSeen = effective;
|
|
716
|
-
|
|
717
|
-
effect = verdict.effect;
|
|
718
|
-
stillParkedProven = verdict.proven;
|
|
739
|
+
effect = planReviewSettledVerdict({ postStatus, bodyStatus, reparked: bodySaysReparked(body), gateBefore, gateAfter, gateKindAfter });
|
|
719
740
|
const code = bodyWordOf(body, 'errorCode');
|
|
720
741
|
if (effect === 'still_parked' && postStatus === 'needs_review' && !bodySaysReparked(body)) {
|
|
721
742
|
outcome =
|
|
@@ -761,14 +782,13 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
761
782
|
const noAnswer = typeof status === 'number' || typeof e !== 'object' ? null : noAnswerKindOf(e);
|
|
762
783
|
if (status === 400 && refusedCode === REQUEST_FIELD_CONFLICT && permissionModeAfter === 'acceptEdits') {
|
|
763
784
|
hostLog('debug', `planReviewWire: ${decision} + acceptEdits refused (request.field_conflict) — NOT re-sent with a different mode`);
|
|
764
|
-
effect = 'still_parked';
|
|
765
|
-
stillParkedProven = true;
|
|
785
|
+
effect = decision === 'approve' ? 'still_parked' : 'not_applied';
|
|
766
786
|
outcome =
|
|
767
787
|
decision === 'approve'
|
|
768
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). ' +
|
|
769
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.'
|
|
770
790
|
: `The plan ${decision} was NOT applied: the engine refused the post-approval permission mode that was sent with it (request.field_conflict). ` +
|
|
771
|
-
'
|
|
791
|
+
'This request changed nothing engine-side. Tell the user plainly that the decision did not go through.';
|
|
772
792
|
}
|
|
773
793
|
else if (status === 404 && refusedCode === 'not_found.plan_review') {
|
|
774
794
|
hostLog('debug', `planReviewWire: ${decision} → 404 not_found.plan_review (no pending plan review any more — an earlier decision likely settled it)`);
|
|
@@ -781,7 +801,6 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
781
801
|
const cu = checkpointUnsupportedVersionFromError(e);
|
|
782
802
|
hostLog('debug', `planReviewWire: ${decision} → 409 checkpoint.unsupported_version (the server cannot continue this parked review in its stored form; still pending)`);
|
|
783
803
|
effect = 'still_parked';
|
|
784
|
-
stillParkedProven = true;
|
|
785
804
|
stillParkedCause = 'stored_form_unsupported';
|
|
786
805
|
outcome = `This ${decision} was not applied. ${checkpointUnsupportedVersionContent(cu, { parkKind: 'plan_review', runId: taskId })}`;
|
|
787
806
|
}
|
|
@@ -822,9 +841,9 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
822
841
|
const tail = planReviewOutcomeTail(taskId, decision, effect, stillParkedCause);
|
|
823
842
|
const prompt = `<plan-review-outcome>\n${outcome}\n${tail}\n</plan-review-outcome>`;
|
|
824
843
|
const onOutcome = opts?.onOutcome;
|
|
825
|
-
settle(effect === 'not_sent' ||
|
|
844
|
+
settle(effect === 'not_sent' || effect === 'still_parked');
|
|
826
845
|
try {
|
|
827
|
-
const delivered = enqueuePlanReviewOutcome(prompt, { taskId, dispatchNo, decision, effect });
|
|
846
|
+
const delivered = enqueuePlanReviewOutcome(prompt, { taskId, dispatchNo, decision, effect, ...(effect === 'still_parked' && stillParkedCause !== undefined ? { cause: stillParkedCause } : {}) });
|
|
828
847
|
if (!delivered) {
|
|
829
848
|
if (onOutcome !== undefined) {
|
|
830
849
|
hostLog('debug', `planReviewWire: outcome queue port not installed for task ${taskId} — outcome handed to the host's onOutcome callback only`);
|
|
@@ -839,7 +858,17 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
839
858
|
}
|
|
840
859
|
if (onOutcome !== undefined) {
|
|
841
860
|
try {
|
|
842
|
-
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
|
+
});
|
|
843
872
|
}
|
|
844
873
|
catch (e) {
|
|
845
874
|
hostLog('debug', `planReviewWire: onOutcome callback threw for task ${taskId} (ignored): ${String(e)}`);
|
|
@@ -956,7 +985,7 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
|
|
|
956
985
|
if (activeReopenResponders.get(activeKey)?.questionId === questionId) {
|
|
957
986
|
activeReopenResponders.delete(activeKey);
|
|
958
987
|
}
|
|
959
|
-
const choice =
|
|
988
|
+
const choice = planReviewAnswerChoiceOf(questionId, answer);
|
|
960
989
|
if (choice === 'dismissed') {
|
|
961
990
|
notePlanReviewUserDismissalFor(sessionKey, taskId, opts?.readGateInstanceKeys, questionId);
|
|
962
991
|
return { ok: true };
|
|
@@ -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;
|