@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { permissionModeField } from './permissionWireCaps.js';
|
|
2
2
|
import { permissionModeAdmitted } from './permissionModesCapability.js';
|
|
3
3
|
import { hostEnv } from './hostEnv.js';
|
|
4
|
-
import {
|
|
4
|
+
import { flagString, flagTrue } from './flagInput.js';
|
|
5
5
|
import { PERMISSION_MODE_WORDS } from './taskRequestWords.js';
|
|
6
6
|
import { readOwnDataValue } from './ownKey.js';
|
|
7
7
|
export const HEADLESS_PERMISSION_MODE_ENV = 'SEMA_HEADLESS_PERMISSION_MODE';
|
|
@@ -12,33 +12,29 @@ export function normalizeShellPermissionModeForWire(mode) {
|
|
|
12
12
|
return undefined;
|
|
13
13
|
return SHELL_INTERNAL_MODE_TO_WIRE.get(mode) ?? mode;
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
const flag =
|
|
17
|
-
if (flag
|
|
18
|
-
return flag
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (a === '--')
|
|
22
|
-
break;
|
|
23
|
-
if (a === '--dangerously-skip-permissions')
|
|
24
|
-
return 'bypassPermissions';
|
|
25
|
-
}
|
|
15
|
+
function permissionModeOfFlags(flags) {
|
|
16
|
+
const flag = flagString(flags, 'flag');
|
|
17
|
+
if (flag !== undefined)
|
|
18
|
+
return flag;
|
|
19
|
+
if (flagTrue(flags, 'dangerouslySkipPermissions'))
|
|
20
|
+
return 'bypassPermissions';
|
|
26
21
|
return undefined;
|
|
27
22
|
}
|
|
28
23
|
let warnedInvalidEnv = false;
|
|
29
|
-
export function resolveHeadlessPermissionMode(
|
|
30
|
-
const flagMode =
|
|
24
|
+
export function resolveHeadlessPermissionMode(flags, env = hostEnv(), permissionModes) {
|
|
25
|
+
const flagMode = permissionModeOfFlags(flags);
|
|
31
26
|
if (flagMode !== undefined) {
|
|
32
27
|
const snap = flagMode === 'dontAsk' ? dontAskSnapshot(permissionModes) : undefined;
|
|
33
28
|
const normalized = normalizeShellPermissionModeForWire(flagMode);
|
|
34
29
|
const projected = permissionModeField(normalized, { stampDefault: true, permissionModes: snap });
|
|
35
30
|
return { fields: projected.permissionMode !== undefined ? projected : permissionModeField('default', { stampDefault: true }), source: 'flag' };
|
|
36
31
|
}
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
32
|
+
const knob = readHeadlessPermissionModeKnob(env);
|
|
33
|
+
if (knob.kind === 'absent') {
|
|
39
34
|
return { fields: permissionModeField('default', { stampDefault: true }), source: 'default' };
|
|
40
35
|
}
|
|
41
|
-
if (
|
|
36
|
+
if (knob.kind === 'word') {
|
|
37
|
+
const raw = knob.word;
|
|
42
38
|
const snap = raw === 'dontAsk' ? dontAskSnapshot(permissionModes) : undefined;
|
|
43
39
|
const resolution = {
|
|
44
40
|
fields: permissionModeField(raw, { stampDefault: true, permissionModes: snap }),
|
|
@@ -46,7 +42,7 @@ export function resolveHeadlessPermissionMode(argv, env = hostEnv(), permissionM
|
|
|
46
42
|
};
|
|
47
43
|
if (raw === 'dontAsk' && resolution.fields.permissionMode !== 'dontAsk' && !warnedInvalidEnv) {
|
|
48
44
|
warnedInvalidEnv = true;
|
|
49
|
-
resolution.warning =
|
|
45
|
+
resolution.warning = headlessDontAskDowngradeWarning(permissionModes);
|
|
50
46
|
}
|
|
51
47
|
return resolution;
|
|
52
48
|
}
|
|
@@ -56,10 +52,25 @@ export function resolveHeadlessPermissionMode(argv, env = hostEnv(), permissionM
|
|
|
56
52
|
};
|
|
57
53
|
if (!warnedInvalidEnv) {
|
|
58
54
|
warnedInvalidEnv = true;
|
|
59
|
-
resolution.warning =
|
|
55
|
+
resolution.warning = knob.warning;
|
|
60
56
|
}
|
|
61
57
|
return resolution;
|
|
62
58
|
}
|
|
59
|
+
export function readHeadlessPermissionModeKnob(env = hostEnv()) {
|
|
60
|
+
const raw = env[HEADLESS_PERMISSION_MODE_ENV]?.trim();
|
|
61
|
+
if (raw === undefined || raw === '')
|
|
62
|
+
return Object.freeze({ kind: 'absent' });
|
|
63
|
+
if (HEADLESS_PERMISSION_WIRE_MODES.includes(raw))
|
|
64
|
+
return Object.freeze({ kind: 'word', word: raw });
|
|
65
|
+
return Object.freeze({
|
|
66
|
+
kind: 'invalid',
|
|
67
|
+
raw,
|
|
68
|
+
warning: `sema: ${HEADLESS_PERMISSION_MODE_ENV}="${raw}" is not a recognized permission mode (expected one of: ${HEADLESS_PERMISSION_WIRE_MODES.join(', ')}) — ignoring it, this run keeps the default permission behavior`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function headlessDontAskDowngradeWarning(permissionModes) {
|
|
72
|
+
return `sema: ${HEADLESS_PERMISSION_MODE_ENV}="dontAsk" is only sent once this client knows the engine accepts that mode, and ${dontAskWithheldClause(permissionModes)} — this run uses "default"`;
|
|
73
|
+
}
|
|
63
74
|
function dontAskSnapshot(reading) {
|
|
64
75
|
return permissionModeAdmitted(reading, 'dontAsk') ? { kind: 'present', modes: Object.freeze(['dontAsk']) } : undefined;
|
|
65
76
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { appendOwnElement } from '../ownKey.js';
|
|
2
|
+
import { slotPresenceOf } from '../wireFailureShape.js';
|
|
1
3
|
import { CORE_ALLOW_RULE_MEMBERS } from '../generated/engineFactTables.js';
|
|
2
|
-
import { quoteUntrustedForSentence } from '../displayUntrusted.js';
|
|
4
|
+
import { displayUntrusted, quoteUntrustedForSentence } from '../displayUntrusted.js';
|
|
3
5
|
import { msg, renderMessage } from '../i18n/translate.js';
|
|
4
6
|
const KNOWN_MEMBERS = new Set(CORE_ALLOW_RULE_MEMBERS);
|
|
5
7
|
function freezeMember(m) {
|
|
@@ -25,7 +27,7 @@ function readMemberRecord(r) {
|
|
|
25
27
|
let ok = true;
|
|
26
28
|
for (let i = 0; i < length; i++) {
|
|
27
29
|
const d = Object.getOwnPropertyDescriptor(rawEntries, i);
|
|
28
|
-
if (d === undefined || !('value'
|
|
30
|
+
if (d === undefined || !Object.hasOwn(d, 'value')) {
|
|
29
31
|
ok = false;
|
|
30
32
|
break;
|
|
31
33
|
}
|
|
@@ -34,7 +36,7 @@ function readMemberRecord(r) {
|
|
|
34
36
|
ok = false;
|
|
35
37
|
break;
|
|
36
38
|
}
|
|
37
|
-
out
|
|
39
|
+
appendOwnElement(out, e);
|
|
38
40
|
}
|
|
39
41
|
if (ok && rawEntries.length === length)
|
|
40
42
|
entries = Object.freeze(out);
|
|
@@ -92,7 +94,7 @@ export function retiredAllowRuleShadowKeyPresent(carrier, leg) {
|
|
|
92
94
|
const host = leg === 'row' ? keyValue(carrier, 'riskDescriptor') : carrier;
|
|
93
95
|
if (typeof host !== 'object' || host === null)
|
|
94
96
|
return false;
|
|
95
|
-
return RETIRED_SHADOW_KEY[leg]
|
|
97
|
+
return slotPresenceOf(host, RETIRED_SHADOW_KEY[leg]) !== 'absent';
|
|
96
98
|
}
|
|
97
99
|
catch {
|
|
98
100
|
return true;
|
|
@@ -100,7 +102,7 @@ export function retiredAllowRuleShadowKeyPresent(carrier, leg) {
|
|
|
100
102
|
}
|
|
101
103
|
function readMemberAt(arr, i) {
|
|
102
104
|
const d = Object.getOwnPropertyDescriptor(arr, i);
|
|
103
|
-
return d !== undefined && 'value'
|
|
105
|
+
return d !== undefined && Object.hasOwn(d, 'value') ? readMemberRecord(d.value) : freezeMember({ known: false, malformed: true });
|
|
104
106
|
}
|
|
105
107
|
export function readAllowRuleShadowFromWire(carrier, leg) {
|
|
106
108
|
try {
|
|
@@ -133,7 +135,7 @@ function readStampedValue(raw) {
|
|
|
133
135
|
for (let i = 0; i < length; i++) {
|
|
134
136
|
const r = readMemberAt(members, i);
|
|
135
137
|
const d = Object.getOwnPropertyDescriptor(members, i);
|
|
136
|
-
const was = d !== undefined && 'value'
|
|
138
|
+
const was = d !== undefined && Object.hasOwn(d, 'value') && typeof d.value === 'object' && d.value !== null && d.value.malformed === true;
|
|
137
139
|
out.push(was && r.malformed !== true ? freezeMember({ ...r, malformed: true }) : r);
|
|
138
140
|
}
|
|
139
141
|
if (members.length !== length)
|
|
@@ -207,7 +209,7 @@ export function allowRuleShadowSentence(card, lang) {
|
|
|
207
209
|
const single = singlePersistedEntry(shadow);
|
|
208
210
|
if (single !== undefined)
|
|
209
211
|
return renderMessage(msg('approval.card.shadow.single', { entry: single }), lang);
|
|
210
|
-
return renderMessage(msg('approval.card.shadow.several', { members: shadow.members.map((m) => memberPhrase(m, lang)).join(' · ') }), lang);
|
|
212
|
+
return renderMessage(msg('approval.card.shadow.several', { members: displayUntrusted(shadow.members.map((m) => memberPhrase(m, lang)).join(' · ')) }), lang);
|
|
211
213
|
}
|
|
212
214
|
catch {
|
|
213
215
|
return renderMessage(msg('approval.card.shadow.unreadable'), lang);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CORE_TOOL_APPROVAL_CARDS } from '../generated/engineFactTables.js';
|
|
1
2
|
import type { ApprovalCardRequest } from './toolApprovalWire.js';
|
|
2
3
|
export declare function readRequiresRealApproval(carrier: object | null | undefined): boolean;
|
|
3
4
|
export interface ApprovalWindowKeys {
|
|
@@ -13,3 +14,5 @@ export interface ApprovalWindowReadOpts {
|
|
|
13
14
|
}
|
|
14
15
|
export declare function approvalWindowKeysOf(carrier: object | null | undefined, opts?: ApprovalWindowReadOpts | null): Readonly<ApprovalWindowKeys>;
|
|
15
16
|
export declare function probeCauseRowsOf(card: Pick<ApprovalCardRequest, 'probeCause'> | null | undefined): readonly string[] | undefined;
|
|
17
|
+
export type ApprovalCardWord = (typeof CORE_TOOL_APPROVAL_CARDS)[number];
|
|
18
|
+
export declare function readApprovalCardWord(carrier: unknown): ApprovalCardWord | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CORE_TOOL_APPROVAL_CARDS } from '../generated/engineFactTables.js';
|
|
1
2
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
2
3
|
import { guardedRead, readOwnDataValue } from '../ownKey.js';
|
|
3
4
|
export function readRequiresRealApproval(carrier) {
|
|
@@ -152,3 +153,19 @@ export function probeCauseRowsOf(card) {
|
|
|
152
153
|
return undefined;
|
|
153
154
|
}
|
|
154
155
|
}
|
|
156
|
+
const _approvalCardWordPins = [true, true];
|
|
157
|
+
void _approvalCardWordPins;
|
|
158
|
+
const APPROVAL_CARD_WORD_SET = new Set(CORE_TOOL_APPROVAL_CARDS);
|
|
159
|
+
export function readApprovalCardWord(carrier) {
|
|
160
|
+
try {
|
|
161
|
+
if (typeof carrier !== 'object' || carrier === null)
|
|
162
|
+
return undefined;
|
|
163
|
+
const d = Object.getOwnPropertyDescriptor(carrier, 'approvalCard');
|
|
164
|
+
if (d === undefined || !Object.hasOwn(d, 'value'))
|
|
165
|
+
return undefined;
|
|
166
|
+
return APPROVAL_CARD_WORD_SET.has(d.value) ? d.value : undefined;
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -104,8 +104,8 @@ export function approvalCardReasons(card, opts, lang) {
|
|
|
104
104
|
for (const r of raw) {
|
|
105
105
|
if (r.text === undefined)
|
|
106
106
|
continue;
|
|
107
|
-
const text =
|
|
108
|
-
if (text === '' || seen.has(text))
|
|
107
|
+
const text = r.text;
|
|
108
|
+
if (text.trim() === '' || seen.has(text))
|
|
109
109
|
continue;
|
|
110
110
|
seen.add(text);
|
|
111
111
|
lines.push(Object.freeze({ source: r.source, text }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
function ownData(o, key) {
|
|
2
2
|
const d = Object.getOwnPropertyDescriptor(o, key);
|
|
3
|
-
return d !== undefined && 'value'
|
|
3
|
+
return d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
|
|
4
4
|
}
|
|
5
5
|
export function approvalCompleteParked(frame) {
|
|
6
6
|
try {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type AnswerCapture, type TopCauseReading, type TopLocalCodeReading, type UnansweredCapture } from '../engineWireFor.js';
|
|
2
|
+
import { type AttributionLadderState, type AttributionLadderStep } from './attributionLadder.js';
|
|
3
|
+
import { type RefusalCarrier, type SafetyStopHead } from './hitlBridge.js';
|
|
4
|
+
export declare const PARKING_WAIT_CAP_MS = 5000;
|
|
5
|
+
export interface DeliveryTiming {
|
|
6
|
+
readonly delays?: readonly number[];
|
|
7
|
+
readonly budgetMs?: number;
|
|
8
|
+
readonly parkingDelayMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function setDeliveryTimingForTests(t?: DeliveryTiming): void;
|
|
11
|
+
export interface DeliveryTimingReading {
|
|
12
|
+
readonly delays: readonly number[];
|
|
13
|
+
readonly budgetMs: number;
|
|
14
|
+
readonly parkingDelayMs: number | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare function deliveryTiming(): DeliveryTimingReading;
|
|
17
|
+
export type TransportClass = 'aborted' | 'transport' | 'server_5xx' | 'verdict' | 'local_error';
|
|
18
|
+
export interface TransportReading {
|
|
19
|
+
readonly cls: TransportClass;
|
|
20
|
+
readonly answered?: AnswerCapture;
|
|
21
|
+
readonly unanswered?: UnansweredCapture;
|
|
22
|
+
readonly carrierReads?: readonly {
|
|
23
|
+
readonly thrown: object;
|
|
24
|
+
readonly read: RefusalCarrier;
|
|
25
|
+
}[];
|
|
26
|
+
readonly topLocalCode?: TopLocalCodeReading;
|
|
27
|
+
readonly bindingMismatchWrapper?: true;
|
|
28
|
+
readonly topCause?: TopCauseReading;
|
|
29
|
+
readonly safetyStop?: true;
|
|
30
|
+
}
|
|
31
|
+
export declare function transportReadingOf(e: {} | null | undefined, signal: AbortSignal | undefined): TransportReading;
|
|
32
|
+
export declare function settledTransportReadingOf(e: {} | null | undefined, signal: AbortSignal | undefined, tally: SendTally): TransportReading;
|
|
33
|
+
export declare function deliveryReadingOf(thrown: {} | null | undefined, tally: SendTally): TransportReading | undefined;
|
|
34
|
+
export declare function transportClassOf(e: {} | null | undefined, signal: AbortSignal | undefined): TransportClass;
|
|
35
|
+
export interface SendTally {
|
|
36
|
+
attempts: number;
|
|
37
|
+
retried: boolean;
|
|
38
|
+
readonly startedAt: number;
|
|
39
|
+
lastThrown: {
|
|
40
|
+
readonly thrown: {} | null | undefined;
|
|
41
|
+
readonly reading: TransportReading;
|
|
42
|
+
} | undefined;
|
|
43
|
+
}
|
|
44
|
+
export declare function newSendTally(): SendTally;
|
|
45
|
+
export declare function budgetSpent(tally: SendTally, extraMs: number): boolean;
|
|
46
|
+
export declare function isAborted(signal: AbortSignal | undefined): boolean;
|
|
47
|
+
export declare function sleepFor(ms: number, signal: AbortSignal | undefined): Promise<void>;
|
|
48
|
+
export declare function withTransportRetry<T>(send: (signal: AbortSignal | undefined) => Promise<T>, signal: AbortSignal | undefined, tally: SendTally, deadlineOnFirst?: boolean): Promise<T>;
|
|
49
|
+
export interface SettledFailureReading {
|
|
50
|
+
readonly thrown: {} | null | undefined;
|
|
51
|
+
readonly reading: TransportReading;
|
|
52
|
+
}
|
|
53
|
+
export declare function directFailureReadingOf(e: {} | null | undefined, triaged: TransportReading, topHead: SafetyStopHead): SettledFailureReading;
|
|
54
|
+
export interface ApprovalParkingFacts {
|
|
55
|
+
readonly approvalId: string;
|
|
56
|
+
readonly retryAfterMs?: number;
|
|
57
|
+
}
|
|
58
|
+
export declare function approvalParkingRetryWait(view: ApprovalParkingFacts, tally: SendTally, signal: AbortSignal | undefined): number | undefined;
|
|
59
|
+
export type ApprovalDelivery = {
|
|
60
|
+
readonly kind: 'answered';
|
|
61
|
+
readonly raw: {} | null | undefined;
|
|
62
|
+
readonly parkingRetried?: true;
|
|
63
|
+
} | {
|
|
64
|
+
readonly kind: 'thrown';
|
|
65
|
+
readonly error: {} | null | undefined;
|
|
66
|
+
readonly reading: TransportReading;
|
|
67
|
+
readonly transportExhausted: boolean;
|
|
68
|
+
readonly afterRetry: boolean;
|
|
69
|
+
readonly parkingRetried?: true;
|
|
70
|
+
};
|
|
71
|
+
export interface ApprovalDeliveryInput<B extends {
|
|
72
|
+
settledBy?: unknown;
|
|
73
|
+
decidedBy?: unknown;
|
|
74
|
+
}> {
|
|
75
|
+
readonly approvalId: string;
|
|
76
|
+
readonly body: B;
|
|
77
|
+
readonly send: (body: B, signal: AbortSignal | undefined) => Promise<{} | null | undefined | void>;
|
|
78
|
+
readonly signal: AbortSignal | undefined;
|
|
79
|
+
readonly tally: SendTally;
|
|
80
|
+
readonly ladder: AttributionLadderState;
|
|
81
|
+
readonly onLadderStep?: (step: AttributionLadderStep) => void;
|
|
82
|
+
readonly parkingOf: (raw: {} | null | undefined) => ApprovalParkingFacts | undefined;
|
|
83
|
+
}
|
|
84
|
+
export declare function deliverApprovalDecision<B extends {
|
|
85
|
+
settledBy?: unknown;
|
|
86
|
+
decidedBy?: unknown;
|
|
87
|
+
}>(input: ApprovalDeliveryInput<B>): Promise<ApprovalDelivery>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { abortableSleep } from '../abortableSleep.js';
|
|
2
|
+
import { classifyTurnWireError } from '../wireErrorTriage.js';
|
|
3
|
+
import { ownReadingSlot, triageReadingOf } from '../engineWireFor.js';
|
|
4
|
+
import { isSlotCarrier, readThrownSlot, THROWN_SLOT_UNREADABLE } from '../wireFailureShape.js';
|
|
5
|
+
import { deliverWithAttributionLadder, localCodeReadOf, topCauseReadOf } from './attributionLadder.js';
|
|
6
|
+
import { GATE_FAILURE_CODES, refusalCarrierOf, safetyStopHeadOf } from './hitlBridge.js';
|
|
7
|
+
const RETRY_DELAYS_MS = Object.freeze([500, 1_000, 2_000]);
|
|
8
|
+
const RETRY_BUDGET_MS = 8_000;
|
|
9
|
+
export const PARKING_WAIT_CAP_MS = 5_000;
|
|
10
|
+
let timingOverride;
|
|
11
|
+
export function setDeliveryTimingForTests(t) {
|
|
12
|
+
timingOverride = t;
|
|
13
|
+
}
|
|
14
|
+
export function deliveryTiming() {
|
|
15
|
+
return { delays: timingOverride?.delays ?? RETRY_DELAYS_MS, budgetMs: timingOverride?.budgetMs ?? RETRY_BUDGET_MS, parkingDelayMs: timingOverride?.parkingDelayMs };
|
|
16
|
+
}
|
|
17
|
+
function isAbortShaped(e) {
|
|
18
|
+
const name = readThrownSlot(e, 'name');
|
|
19
|
+
return name === 'TimeoutError' || name === 'AbortError';
|
|
20
|
+
}
|
|
21
|
+
export function transportReadingOf(e, signal) {
|
|
22
|
+
const reading = triageReadingOf(classifyTurnWireError(e));
|
|
23
|
+
const answered = ownReadingSlot(reading, 'answer');
|
|
24
|
+
const unanswered = ownReadingSlot(reading, 'unanswered');
|
|
25
|
+
const topLocalCode = ownReadingSlot(reading, 'topLocalCode');
|
|
26
|
+
const topCause = ownReadingSlot(reading, 'topCause');
|
|
27
|
+
const topFacts = { ...(topLocalCode !== undefined ? { topLocalCode } : {}), ...(topCause !== undefined ? { topCause } : {}) };
|
|
28
|
+
const layer = answered !== undefined && answered !== THROWN_SLOT_UNREADABLE ? { answered, ...topFacts } : unanswered !== undefined ? { unanswered, ...topFacts } : topFacts;
|
|
29
|
+
if (signal?.aborted === true)
|
|
30
|
+
return { cls: 'aborted', ...layer };
|
|
31
|
+
if (reading === undefined || answered === THROWN_SLOT_UNREADABLE)
|
|
32
|
+
return { cls: 'local_error', ...topFacts };
|
|
33
|
+
if (answered !== undefined)
|
|
34
|
+
return { cls: answered.status === 501 ? 'verdict' : answered.status >= 500 ? 'server_5xx' : 'verdict', ...layer };
|
|
35
|
+
return { cls: reading.transport || isAbortShaped(e) ? 'transport' : 'local_error', ...layer };
|
|
36
|
+
}
|
|
37
|
+
export function settledTransportReadingOf(e, signal, tally) {
|
|
38
|
+
const last = ownReadingSlot(tally, 'lastThrown');
|
|
39
|
+
if (last === undefined || last.thrown !== e)
|
|
40
|
+
return transportReadingOf(e, signal);
|
|
41
|
+
if (signal?.aborted === true)
|
|
42
|
+
return { ...last.reading, cls: 'aborted' };
|
|
43
|
+
return last.reading;
|
|
44
|
+
}
|
|
45
|
+
export function deliveryReadingOf(thrown, tally) {
|
|
46
|
+
const last = ownReadingSlot(tally, 'lastThrown');
|
|
47
|
+
return last !== undefined && last.thrown === thrown ? last.reading : undefined;
|
|
48
|
+
}
|
|
49
|
+
export function transportClassOf(e, signal) {
|
|
50
|
+
return transportReadingOf(e, signal).cls;
|
|
51
|
+
}
|
|
52
|
+
export function newSendTally() {
|
|
53
|
+
return { attempts: 0, retried: false, startedAt: Date.now(), lastThrown: undefined };
|
|
54
|
+
}
|
|
55
|
+
function attemptSignal(withDeadline, caller, startedAt, budgetMs) {
|
|
56
|
+
if (!withDeadline)
|
|
57
|
+
return caller;
|
|
58
|
+
const deadline = AbortSignal.timeout(Math.max(1, budgetMs - (Date.now() - startedAt)));
|
|
59
|
+
if (caller === undefined)
|
|
60
|
+
return deadline;
|
|
61
|
+
if (typeof AbortSignal.any === 'function')
|
|
62
|
+
return AbortSignal.any([caller, deadline]);
|
|
63
|
+
const ac = new AbortController();
|
|
64
|
+
const abort = (s) => ac.abort(s.reason);
|
|
65
|
+
if (caller.aborted)
|
|
66
|
+
abort(caller);
|
|
67
|
+
else
|
|
68
|
+
caller.addEventListener('abort', () => abort(caller), { once: true });
|
|
69
|
+
deadline.addEventListener('abort', () => abort(deadline), { once: true });
|
|
70
|
+
return ac.signal;
|
|
71
|
+
}
|
|
72
|
+
export function budgetSpent(tally, extraMs) {
|
|
73
|
+
return Date.now() - tally.startedAt + extraMs >= deliveryTiming().budgetMs;
|
|
74
|
+
}
|
|
75
|
+
export function isAborted(signal) {
|
|
76
|
+
return signal?.aborted === true;
|
|
77
|
+
}
|
|
78
|
+
export function sleepFor(ms, signal) {
|
|
79
|
+
return abortableSleep(ms, signal ?? new AbortController().signal);
|
|
80
|
+
}
|
|
81
|
+
export async function withTransportRetry(send, signal, tally, deadlineOnFirst = false) {
|
|
82
|
+
const { delays, budgetMs } = deliveryTiming();
|
|
83
|
+
const startedAt = tally.startedAt;
|
|
84
|
+
for (let attempt = 1;; attempt++) {
|
|
85
|
+
tally.attempts++;
|
|
86
|
+
try {
|
|
87
|
+
return await send(attemptSignal(attempt > 1 || deadlineOnFirst, signal, startedAt, budgetMs));
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
const reading = transportReadingOf(e, signal);
|
|
91
|
+
const cls = reading.cls;
|
|
92
|
+
const delay = delays[attempt - 1] ?? 0;
|
|
93
|
+
const heads = localStopHeadsOf(e, reading);
|
|
94
|
+
const retriable = (cls === 'transport' || cls === 'server_5xx') && heads.safetyStop !== true;
|
|
95
|
+
const overBudget = Date.now() - startedAt + delay >= budgetMs;
|
|
96
|
+
if (!retriable || attempt > delays.length || overBudget)
|
|
97
|
+
throw answeredError(settledReadingOf(e, reading, heads), tally);
|
|
98
|
+
tally.retried = true;
|
|
99
|
+
await sleepFor(delay, signal);
|
|
100
|
+
if (signal?.aborted === true || Date.now() - startedAt >= budgetMs)
|
|
101
|
+
throw answeredError(settledReadingOf(e, reading, heads), tally);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function answeredError(settled, tally) {
|
|
106
|
+
tally.lastThrown = settled;
|
|
107
|
+
return settled.thrown;
|
|
108
|
+
}
|
|
109
|
+
function isLocalClosedCode(v) {
|
|
110
|
+
return typeof v === 'string' && GATE_FAILURE_CODES.includes(v);
|
|
111
|
+
}
|
|
112
|
+
function localStopHeadsOf(top, reading, known) {
|
|
113
|
+
const answered = ownReadingSlot(reading, 'answered')?.layer;
|
|
114
|
+
const deep = answered !== undefined && answered !== top ? answered : undefined;
|
|
115
|
+
const topCode = isSlotCarrier(top) ? localCodeReadOf(reading, top) : undefined;
|
|
116
|
+
const topHead = known ?? (!isSlotCarrier(top) ? undefined : topCode === undefined ? safetyStopHeadOf(top) : isLocalClosedCode(topCode.value) ? safetyStopHeadOf(top, topCode) : undefined);
|
|
117
|
+
const deepCode = deep !== undefined ? localCodeReadOf(reading, deep) : undefined;
|
|
118
|
+
const layerHead = deep !== undefined && deepCode !== undefined && isLocalClosedCode(deepCode.value) ? safetyStopHeadOf(deep, deepCode) : undefined;
|
|
119
|
+
const safetyStop = topHead?.local !== undefined || layerHead?.local !== undefined;
|
|
120
|
+
return Object.freeze({ ...(safetyStop ? { safetyStop: true } : {}), ...(topHead !== undefined ? { top: topHead } : {}), ...(layerHead !== undefined ? { layer: layerHead } : {}) });
|
|
121
|
+
}
|
|
122
|
+
function settledReadingOf(e, reading, heads) {
|
|
123
|
+
const top = e;
|
|
124
|
+
const layer = ownReadingSlot(reading, 'answered')?.layer;
|
|
125
|
+
const wrapper = isSlotCarrier(top) ? refusalCarrierOf(top, localCodeReadOf(reading, top), false, topCauseReadOf(reading, top), heads.top) : undefined;
|
|
126
|
+
const thrown = layer === undefined ? top : layer;
|
|
127
|
+
const reads = [];
|
|
128
|
+
if (wrapper !== undefined && isSlotCarrier(top))
|
|
129
|
+
reads.push(Object.freeze({ thrown: top, read: wrapper }));
|
|
130
|
+
if (layer !== undefined && layer !== top)
|
|
131
|
+
reads.push(Object.freeze({ thrown: layer, read: refusalCarrierOf(layer, localCodeReadOf(reading, layer), true, undefined, heads.layer) }));
|
|
132
|
+
const bindingMismatchWrapper = layer !== undefined && layer !== top && wrapper !== undefined && ownReadingSlot(wrapper, 'local') === 'binding_mismatch';
|
|
133
|
+
const safetyStop = heads.safetyStop === true;
|
|
134
|
+
const settled = reads.length > 0 || bindingMismatchWrapper || safetyStop
|
|
135
|
+
? { ...reading, ...(reads.length > 0 ? { carrierReads: Object.freeze(reads) } : {}), ...(bindingMismatchWrapper ? { bindingMismatchWrapper: true } : {}), ...(safetyStop ? { safetyStop: true } : {}) }
|
|
136
|
+
: reading;
|
|
137
|
+
return { thrown, reading: settled };
|
|
138
|
+
}
|
|
139
|
+
export function directFailureReadingOf(e, triaged, topHead) {
|
|
140
|
+
return settledReadingOf(e, triaged, localStopHeadsOf(e, triaged, topHead));
|
|
141
|
+
}
|
|
142
|
+
export function approvalParkingRetryWait(view, tally, signal) {
|
|
143
|
+
const w = ownReadingSlot(view, 'retryAfterMs');
|
|
144
|
+
if (typeof w !== 'number' || !Number.isFinite(w) || w < 0)
|
|
145
|
+
return undefined;
|
|
146
|
+
if (w > PARKING_WAIT_CAP_MS)
|
|
147
|
+
return undefined;
|
|
148
|
+
if (isAborted(signal) || budgetSpent(tally, w))
|
|
149
|
+
return undefined;
|
|
150
|
+
return w;
|
|
151
|
+
}
|
|
152
|
+
function thrownFacts(e, signal, tally) {
|
|
153
|
+
const reading = settledTransportReadingOf(e, signal, tally);
|
|
154
|
+
return { reading, transportExhausted: reading.cls === 'transport' && tally.retried, afterRetry: tally.retried };
|
|
155
|
+
}
|
|
156
|
+
export async function deliverApprovalDecision(input) {
|
|
157
|
+
const { signal, tally } = input;
|
|
158
|
+
let last = input.body;
|
|
159
|
+
let raw;
|
|
160
|
+
try {
|
|
161
|
+
raw = (await deliverWithAttributionLadder(input.body, (b) => {
|
|
162
|
+
last = b;
|
|
163
|
+
return withTransportRetry((sig) => input.send(b, sig), signal, tally);
|
|
164
|
+
}, signal, input.ladder, input.onLadderStep, { kind: 'delivered', readingOf: (thrown) => deliveryReadingOf(thrown, tally) }));
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
return { kind: 'thrown', error: e, ...thrownFacts(e, signal, tally) };
|
|
168
|
+
}
|
|
169
|
+
let parking;
|
|
170
|
+
try {
|
|
171
|
+
parking = input.parkingOf(raw);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
parking = undefined;
|
|
175
|
+
}
|
|
176
|
+
if (parking === undefined || parking.approvalId !== input.approvalId)
|
|
177
|
+
return { kind: 'answered', raw };
|
|
178
|
+
const wait = approvalParkingRetryWait(parking, tally, signal);
|
|
179
|
+
if (wait === undefined)
|
|
180
|
+
return { kind: 'answered', raw };
|
|
181
|
+
await sleepFor(wait, signal);
|
|
182
|
+
if (isAborted(signal) || budgetSpent(tally, 0))
|
|
183
|
+
return { kind: 'answered', raw };
|
|
184
|
+
tally.retried = false;
|
|
185
|
+
const resent = last;
|
|
186
|
+
try {
|
|
187
|
+
const raw2 = (await withTransportRetry((sig) => input.send(resent, sig), signal, tally, true));
|
|
188
|
+
return { kind: 'answered', raw: raw2, parkingRetried: true };
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
return { kind: 'thrown', error: e, ...thrownFacts(e, signal, tally), parkingRetried: true };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApprovalHolderIdentity } from './toolApprovalWire.js';
|
|
2
2
|
import type { ApprovalResolution, ApprovalResolutionLane } from './approvalResolution.js';
|
|
3
|
+
import { type DecisionLedgerOp } from './decisionLedger.js';
|
|
3
4
|
export declare const APPROVAL_SETTLED_HOWS: readonly ["answered", "interrupted", "closed_by_engine"];
|
|
4
5
|
export type ApprovalSettledHow = (typeof APPROVAL_SETTLED_HOWS)[number];
|
|
5
6
|
export declare const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
@@ -29,6 +30,7 @@ export interface LiveCardHold {
|
|
|
29
30
|
readonly cardSignal: AbortSignal;
|
|
30
31
|
readonly interrupt: () => void;
|
|
31
32
|
trailing?: Promise<boolean>;
|
|
33
|
+
ledgerOp?: DecisionLedgerOp;
|
|
32
34
|
}
|
|
33
35
|
export interface HostCardHold {
|
|
34
36
|
readonly lane: 'host';
|
|
@@ -61,6 +63,17 @@ export interface HostApprovalCardHold {
|
|
|
61
63
|
sending(): void;
|
|
62
64
|
release(settled?: 'answered' | 'interrupted'): void;
|
|
63
65
|
}
|
|
66
|
+
export declare function hostHoldIsActive(handle: HostApprovalCardHold): boolean;
|
|
67
|
+
export declare function takeHostHoldLedgerOp(handle: HostApprovalCardHold): DecisionLedgerOp | undefined;
|
|
68
|
+
export type ApprovalHoldAttempt = {
|
|
69
|
+
readonly kind: 'settled';
|
|
70
|
+
} | {
|
|
71
|
+
readonly kind: 'busy';
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: 'held';
|
|
74
|
+
readonly hold: HostApprovalCardHold;
|
|
75
|
+
};
|
|
76
|
+
export declare function tryHoldApprovalNow(who: HoldIdentity, signal: AbortSignal | undefined): ApprovalHoldAttempt;
|
|
64
77
|
export type ApprovalCardClaim = {
|
|
65
78
|
readonly kind: 'held';
|
|
66
79
|
readonly hold: HostApprovalCardHold;
|
|
@@ -93,4 +106,5 @@ export declare function settledLiveCardOutcome(approvalId: string): ApprovalReso
|
|
|
93
106
|
export declare function liveCardHoldOf(key: string): LiveCardHold | undefined;
|
|
94
107
|
export declare function holdLiveCard(identity: LiveCardIdentity, callerSignal: AbortSignal | undefined, present: (hold: LiveCardHold) => Promise<ApprovalResolution>): Promise<ApprovalResolution>;
|
|
95
108
|
export declare function joinLiveCard(hold: LiveCardHold, signal: AbortSignal | undefined): Promise<ApprovalResolution>;
|
|
109
|
+
export declare function enterLiveRespondPhase(hold: LiveCardHold): void;
|
|
96
110
|
export declare function supersedeLiveCard(key: string, parked: boolean): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hostLog } from '../host.js';
|
|
2
2
|
import { liveFrameCallKey } from './gateIdentity.js';
|
|
3
3
|
import { decideReceiptReopen, readDecideReceipt } from '../decideReceipt.js';
|
|
4
|
+
import { closeDecisionOp, decisionLedgerKeysOf, openDecisionOp, settleDecisionOp } from './decisionLedger.js';
|
|
4
5
|
export const APPROVAL_SETTLED_HOWS = Object.freeze(['answered', 'interrupted', 'closed_by_engine']);
|
|
5
6
|
export const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
6
7
|
const nonEmpty = (v) => typeof v === 'string' && v !== '';
|
|
@@ -110,11 +111,16 @@ function holdHostCard(identity, signal) {
|
|
|
110
111
|
h.inFlight.set(key, hold);
|
|
111
112
|
let done = false;
|
|
112
113
|
let stopFollowing = () => { };
|
|
114
|
+
let ledgerOp;
|
|
113
115
|
const release = (settled) => {
|
|
114
116
|
if (done)
|
|
115
117
|
return;
|
|
116
118
|
done = true;
|
|
117
119
|
stopFollowing();
|
|
120
|
+
if (ledgerOp !== undefined) {
|
|
121
|
+
settleDecisionOp(ledgerOp, 'host');
|
|
122
|
+
ledgerOp.ownCallOpen = false;
|
|
123
|
+
}
|
|
118
124
|
const how = settled === 'answered' || settled === 'interrupted' ? settled : undefined;
|
|
119
125
|
if (how !== undefined && nonEmpty(frozen.approvalId))
|
|
120
126
|
noteSettled(frozen.approvalId, how, false, how === 'interrupted' ? interruptedThere('decide') : nothingSentHere('decide'), true);
|
|
@@ -127,6 +133,8 @@ function holdHostCard(identity, signal) {
|
|
|
127
133
|
sending: () => {
|
|
128
134
|
if (done)
|
|
129
135
|
return;
|
|
136
|
+
if (hold.phase !== 'respond')
|
|
137
|
+
ledgerOp = openDecisionOp('tool_approval', ledgerKeysOfHold(frozen), 'handed', true);
|
|
130
138
|
hold.phase = 'respond';
|
|
131
139
|
stopFollowing();
|
|
132
140
|
},
|
|
@@ -136,8 +144,31 @@ function holdHostCard(identity, signal) {
|
|
|
136
144
|
if (!done && hold.phase === 'card')
|
|
137
145
|
release();
|
|
138
146
|
});
|
|
147
|
+
hostHoldControls.set(handle, {
|
|
148
|
+
active: () => !done && h.inFlight.get(key) === hold,
|
|
149
|
+
takeLedgerOp: () => {
|
|
150
|
+
const op = ledgerOp;
|
|
151
|
+
ledgerOp = undefined;
|
|
152
|
+
return op;
|
|
153
|
+
},
|
|
154
|
+
});
|
|
139
155
|
return handle;
|
|
140
156
|
}
|
|
157
|
+
const hostHoldControls = new WeakMap();
|
|
158
|
+
export function hostHoldIsActive(handle) {
|
|
159
|
+
return hostHoldControls.get(handle)?.active() === true;
|
|
160
|
+
}
|
|
161
|
+
export function takeHostHoldLedgerOp(handle) {
|
|
162
|
+
return hostHoldControls.get(handle)?.takeLedgerOp();
|
|
163
|
+
}
|
|
164
|
+
export function tryHoldApprovalNow(who, signal) {
|
|
165
|
+
const entry = settledApprovalOf(who.approvalId);
|
|
166
|
+
if (entry !== undefined && settledForDurableLane(entry))
|
|
167
|
+
return Object.freeze({ kind: 'settled' });
|
|
168
|
+
if (approvalHoldFor(who) !== undefined)
|
|
169
|
+
return Object.freeze({ kind: 'busy' });
|
|
170
|
+
return Object.freeze({ kind: 'held', hold: holdHostCard(who, signal) });
|
|
171
|
+
}
|
|
141
172
|
function callerSignalAborted(signal) {
|
|
142
173
|
if (signal === undefined || signal === null)
|
|
143
174
|
return false;
|
|
@@ -254,6 +285,8 @@ export function holdLiveCard(identity, callerSignal, present) {
|
|
|
254
285
|
const hold = { lane: 'live', identity: Object.freeze({ ...identity }), outcome, phase: 'card', cardSignal: cut.signal, interrupt };
|
|
255
286
|
h.inFlight.set(key, hold);
|
|
256
287
|
const release = () => {
|
|
288
|
+
if (hold.ledgerOp !== undefined)
|
|
289
|
+
closeDecisionOp(hold.ledgerOp, 'package');
|
|
257
290
|
if (h.inFlight.get(key) === hold)
|
|
258
291
|
h.inFlight.delete(key);
|
|
259
292
|
};
|
|
@@ -320,6 +353,14 @@ function followCallerSignal(signal, onAbort) {
|
|
|
320
353
|
}
|
|
321
354
|
};
|
|
322
355
|
}
|
|
356
|
+
function ledgerKeysOfHold(identity) {
|
|
357
|
+
return decisionLedgerKeysOf({ taskId: identity.taskId, approvalId: identity.approvalId, callId: identity.toolCallId });
|
|
358
|
+
}
|
|
359
|
+
export function enterLiveRespondPhase(hold) {
|
|
360
|
+
if (hold.ledgerOp === undefined)
|
|
361
|
+
hold.ledgerOp = openDecisionOp('tool_approval', ledgerKeysOfHold(hold.identity), 'posting', true);
|
|
362
|
+
hold.phase = 'respond';
|
|
363
|
+
}
|
|
323
364
|
export function supersedeLiveCard(key, parked) {
|
|
324
365
|
const hold = liveCardHoldOf(key);
|
|
325
366
|
if (hold === undefined || hold.phase !== 'card' || hold.superseded !== undefined)
|
|
@@ -3,6 +3,7 @@ import { type HitlSafetyCode } from './hitlBridge.js';
|
|
|
3
3
|
import type { AskAnsweredOutput } from './gateLedger.js';
|
|
4
4
|
import type { ApprovalDenySettledBy, ToolApprovalRespondAckView, ToolApprovalRespondDecision, ToolApprovalRespondParkingView } from './toolApprovalWire.js';
|
|
5
5
|
import { type DecisionRefusalReading, type RefusalRouteContext } from './decisionRefusal.js';
|
|
6
|
+
import { type DeliveredReading, type LadderSafetyStop } from './attributionLadder.js';
|
|
6
7
|
export declare const APPROVAL_RESOLUTION_LANES: readonly ["respond", "decide", "ask"];
|
|
7
8
|
export type ApprovalResolutionLane = (typeof APPROVAL_RESOLUTION_LANES)[number];
|
|
8
9
|
export declare const APPROVAL_NOT_SENT_CAUSES: readonly ["retracted", "edit_refused", "no_pending", "wrong_gate", "fetch_failed", "no_input", "card_unavailable", "safety_stop"];
|
|
@@ -55,7 +56,17 @@ export interface DecisionFailureMint {
|
|
|
55
56
|
readonly gatedCallId?: string | undefined;
|
|
56
57
|
readonly detail?: string | undefined;
|
|
57
58
|
readonly attributionCarried?: boolean | undefined;
|
|
59
|
+
readonly transportExhausted?: boolean | undefined;
|
|
60
|
+
readonly afterRetry?: boolean | undefined;
|
|
61
|
+
readonly delivered?: DeliveredReading | undefined;
|
|
62
|
+
readonly directStop?: LadderSafetyStop | undefined;
|
|
58
63
|
}
|
|
59
64
|
export declare function resolutionOfDecisionFailure(e: {} | null | undefined, m: DecisionFailureMint): ApprovalResolution;
|
|
65
|
+
export declare function directSafetyStopOf(e: {} | null | undefined): LadderSafetyStop | undefined;
|
|
66
|
+
export interface DirectFailureVerdict {
|
|
67
|
+
readonly yields: boolean;
|
|
68
|
+
readonly directStop?: LadderSafetyStop;
|
|
69
|
+
}
|
|
70
|
+
export declare function directFailureVerdictOf(e: {} | null | undefined, stop: LadderSafetyStop | undefined): DirectFailureVerdict;
|
|
60
71
|
export declare function joinedResolution(r: ApprovalResolution, gatedCallId?: string): ApprovalResolution;
|
|
61
72
|
export {};
|