@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,25 +1,32 @@
|
|
|
1
|
-
import { ASK_GONE, ASK_GONE_PARKED, RESUME_PREFLIGHT_REJECTED, isDecideAlreadyResolvedCode, isDecideParkMovedCode, refusalRetriableReading, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
1
|
+
import { ASK_GONE, ASK_GONE_PARKED, RESUME_PREFLIGHT_REJECTED, isDecideAlreadyResolvedCode, isDecideParkMovedCode, isDecideRowUnrevivableCode, refusalRetriableReading, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
2
|
+
import { isUiLanguage } from '../env/uiLanguage.js';
|
|
3
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
2
4
|
import { notPendingCauseReading, refusalCauseWordOf } from './approvalEndingCause.js';
|
|
3
|
-
import { GATE_FAILURE_CODES, readDecideCurrentPending, readWireCodes } from './hitlBridge.js';
|
|
5
|
+
import { GATE_FAILURE_CODES, readDecideCurrentPending, readWireCodes, refusalCarrierOf } from './hitlBridge.js';
|
|
4
6
|
import { isAlreadyResolvedGateReason, isCodeClassifiedGateFailure } from './parkResolver.js';
|
|
5
7
|
import { decisionConflictOf } from './decisionConflict.js';
|
|
6
8
|
import { readLivePendingRows } from './livePendingAsk.js';
|
|
7
9
|
import { guardedRead, ownDataField, readOwnDataValue } from '../ownKey.js';
|
|
8
|
-
import { PROTOCOL_ERROR_NAME, isDisplayableWireCode, protocolErrorNameReading, readErrorRecord, readRefusalField } from '../wireFailureShape.js';
|
|
9
|
-
import {
|
|
10
|
+
import { PROTOCOL_ERROR_NAME, THROWN_SLOT_UNREADABLE, isDisplayableWireCode, isSlotCarrier, ownFoldedCodeBitsOf, protocolErrorNameReading, readErrorRecord, readRefusalField, readThrownSlot } from '../wireFailureShape.js';
|
|
11
|
+
import { attributionRefusalOf, carrierReadOf } from './attributionLadder.js';
|
|
12
|
+
import { CODE_UNREADABLE, ownReadingSlot } from '../engineWireFor.js';
|
|
10
13
|
export const ASK_DECIDED_CODE = 'conflict.ask_decided';
|
|
11
14
|
const TRANSIENT_STATUSES = new Set([408, 425, 429, 502, 503, 504]);
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
export { refusalCarrierOf } from './hitlBridge.js';
|
|
16
|
+
const DELIVERED_UNREADABLE = Symbol('delivered-answer-unreadable');
|
|
17
|
+
function deliveredAnswerOf(delivered, carrier) {
|
|
18
|
+
if (delivered === undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
const a = ownReadingSlot(delivered, 'answered') ?? ownReadingSlot(delivered, 'unanswered');
|
|
21
|
+
return a !== undefined && a.layer === carrier ? a : DELIVERED_UNREADABLE;
|
|
22
|
+
}
|
|
23
|
+
const PROTOCOL_NAME_ABSENT = Object.freeze({ state: 'absent' });
|
|
24
|
+
const PROTOCOL_NAME_UNREADABLE = Object.freeze({ state: 'unreadable' });
|
|
25
|
+
function capturedCodeOf(answer) {
|
|
26
|
+
return answer === undefined ? undefined : answer === DELIVERED_UNREADABLE ? CODE_UNREADABLE : answer.code;
|
|
27
|
+
}
|
|
28
|
+
export function notPendingAfterRetry(status, retried) {
|
|
29
|
+
return retried && (status === 404 || status === 410);
|
|
23
30
|
}
|
|
24
31
|
const ROUTE_WORDS = { approval_decide: true, live_respond: true, ask_decide: true, plan_review: true, compact: true };
|
|
25
32
|
const REFUSAL_ROUTES = Object.freeze(Object.keys(ROUTE_WORDS));
|
|
@@ -35,17 +42,19 @@ function routeOf(context) {
|
|
|
35
42
|
return typeof r === 'string' && REFUSAL_ROUTES.includes(r) ? r : undefined;
|
|
36
43
|
}
|
|
37
44
|
function carrierStatus(carrier) {
|
|
38
|
-
const raw =
|
|
45
|
+
const raw = isSlotCarrier(carrier) ? readThrownSlot(carrier, 'status', 'data') : undefined;
|
|
39
46
|
return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;
|
|
40
47
|
}
|
|
41
|
-
function carrierCode(carrier) {
|
|
42
|
-
|
|
48
|
+
function carrierCode(carrier, captured) {
|
|
49
|
+
if (captured !== undefined)
|
|
50
|
+
return captured.state === 'read' ? captured.wire : undefined;
|
|
51
|
+
const raw = isSlotCarrier(carrier) ? readThrownSlot(carrier, 'errorCode', 'data') : undefined;
|
|
43
52
|
return typeof raw === 'string' && raw.length > 0 ? raw : undefined;
|
|
44
53
|
}
|
|
45
|
-
export function refusalDeliveryOf(err, context) {
|
|
46
|
-
const { carrier } = refusalCarrierOf(err);
|
|
47
|
-
const status = carrierStatus(carrier);
|
|
48
|
-
const errorCode = carrierCode(carrier);
|
|
54
|
+
export function refusalDeliveryOf(err, context, answer, read) {
|
|
55
|
+
const { carrier } = read ?? refusalCarrierOf(err);
|
|
56
|
+
const status = answer === undefined ? carrierStatus(carrier) : answer === DELIVERED_UNREADABLE ? undefined : answer.status;
|
|
57
|
+
const errorCode = carrierCode(carrier, capturedCodeOf(answer));
|
|
49
58
|
const facts = { ...(status !== undefined ? { status } : {}), ...(errorCode !== undefined ? { errorCode } : {}) };
|
|
50
59
|
if (status === undefined || !Number.isInteger(status) || status < 400 || status > 599)
|
|
51
60
|
return { delivery: 'no_answer', ...facts };
|
|
@@ -61,6 +70,9 @@ export function decisionRefusalSaysAskGone(err) {
|
|
|
61
70
|
return readDecisionRefusalAsk(err).reading === 'settled';
|
|
62
71
|
}
|
|
63
72
|
const facts = (reading, gateMoved = false, wordingHint = false) => ({ reading, gateMoved, wordingHint });
|
|
73
|
+
const codeUnreadable = () => {
|
|
74
|
+
throw new TypeError('status or errorCode was unreadable when this failure was first read');
|
|
75
|
+
};
|
|
64
76
|
function preflightSettledBitsPresent(carrier) {
|
|
65
77
|
const detail = guardedRead(() => readErrorRecord(carrier, 'detail'));
|
|
66
78
|
if (detail === undefined)
|
|
@@ -96,28 +108,31 @@ function askFactsOfResolution(r) {
|
|
|
96
108
|
return facts('unreadable');
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
|
-
export function readDecisionRefusalAsk(failure) {
|
|
100
|
-
if (
|
|
111
|
+
export function readDecisionRefusalAsk(failure, answer, read) {
|
|
112
|
+
if (!isSlotCarrier(failure))
|
|
101
113
|
return facts('not_settled');
|
|
102
|
-
if (isResolutionShaped(failure))
|
|
114
|
+
if (answer === undefined && isResolutionShaped(failure))
|
|
103
115
|
return askFactsOfResolution(failure);
|
|
104
|
-
const
|
|
116
|
+
const r = read ?? refusalCarrierOf(failure);
|
|
117
|
+
const local = ownReadingSlot(r, 'local');
|
|
118
|
+
const carrier = r.carrier;
|
|
105
119
|
if (local !== undefined)
|
|
106
120
|
return facts(local === 'no_pending' ? 'settled' : 'not_settled');
|
|
107
|
-
if (
|
|
121
|
+
if (!isSlotCarrier(carrier))
|
|
108
122
|
return facts('not_settled');
|
|
109
123
|
let localCode, name, protocolName, errorCode, status, retriable, text;
|
|
110
124
|
try {
|
|
111
125
|
const slot = (key) => ownDataField(carrier, key);
|
|
112
126
|
const closed = (v) => (typeof v === 'string' && GATE_FAILURE_CODES.includes(v) ? v : undefined);
|
|
113
|
-
localCode = closed(slot('code'));
|
|
127
|
+
localCode = closed(answer === undefined ? slot('code') : answer === DELIVERED_UNREADABLE || answer.localCode === THROWN_SLOT_UNREADABLE ? codeUnreadable() : answer.localCode);
|
|
114
128
|
name = slot('name');
|
|
115
|
-
const pn = protocolErrorNameReading(carrier);
|
|
129
|
+
const pn = read !== undefined ? read.protocolName : protocolErrorNameReading(carrier);
|
|
116
130
|
if (pn.state === 'unreadable')
|
|
117
131
|
throw new TypeError('protocol name unreadable');
|
|
118
132
|
protocolName = pn.state === 'named' ? pn.name : undefined;
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
const captured = capturedCodeOf(answer);
|
|
134
|
+
errorCode = captured === undefined ? slot('errorCode') : captured.state === 'read' ? captured.wire : codeUnreadable();
|
|
135
|
+
status = answer === undefined ? slot('status') : answer === DELIVERED_UNREADABLE ? codeUnreadable() : answer.status;
|
|
121
136
|
retriable = refusalRetriableReading(carrier);
|
|
122
137
|
text = String(carrier);
|
|
123
138
|
}
|
|
@@ -152,7 +167,7 @@ export function decisionRefusalAskReading(failure) {
|
|
|
152
167
|
}
|
|
153
168
|
const USELESS_REFUSAL_TEXTS = new Set(['[object Object]', 'null', 'undefined', '']);
|
|
154
169
|
function refusalTextOf(err) {
|
|
155
|
-
const message =
|
|
170
|
+
const message = isSlotCarrier(err) ? guardedRead(() => err.message) : undefined;
|
|
156
171
|
if (typeof message === 'string' && message.length > 0)
|
|
157
172
|
return message;
|
|
158
173
|
if (typeof err === 'string' && err.length > 0)
|
|
@@ -169,27 +184,49 @@ function refusalTextOf(err) {
|
|
|
169
184
|
function isolated(read) {
|
|
170
185
|
return guardedRead(read);
|
|
171
186
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
187
|
+
function wireCodesOfPinned(captured) {
|
|
188
|
+
if (captured.state !== 'read' || captured.wire === undefined)
|
|
189
|
+
return {};
|
|
190
|
+
return { errorCode: captured.wire, ...(captured.blockedBy !== undefined ? { blockedBy: captured.blockedBy } : {}) };
|
|
191
|
+
}
|
|
192
|
+
export function mintDecisionRefusalReading(err, context, attributionCarried, delivered, carried) {
|
|
193
|
+
const carrierRead = carried ?? carrierReadOf(err, delivered);
|
|
194
|
+
const { carrier } = carrierRead;
|
|
195
|
+
const obj = isSlotCarrier(carrier) ? carrier : undefined;
|
|
196
|
+
const answer = deliveredAnswerOf(delivered, carrier);
|
|
197
|
+
const captured = capturedCodeOf(answer);
|
|
198
|
+
const status = answer === undefined ? carrierStatus(carrier) : answer === DELIVERED_UNREADABLE ? undefined : answer.status;
|
|
199
|
+
const wire = captured !== undefined ? wireCodesOfPinned(captured) : obj !== undefined ? isolated(() => readWireCodes(obj)) : undefined;
|
|
200
|
+
const wireBits = ownFoldedCodeBitsOf(wire);
|
|
201
|
+
const errorCode = wireBits.errorCode ?? carrierCode(carrier, captured);
|
|
202
|
+
const blockedBy = wireBits.blockedBy;
|
|
178
203
|
const message = isolated(() => refusalTextOf(carrier));
|
|
179
204
|
const retriable = obj !== undefined && isolated(() => refusalSaysStillPending(obj)) === true;
|
|
180
|
-
const pn = obj !== undefined ? isolated(() => protocolErrorNameReading(obj)) :
|
|
181
|
-
const protocolName = pn
|
|
205
|
+
const pn = obj !== undefined ? (isolated(() => protocolErrorNameReading(obj)) ?? PROTOCOL_NAME_UNREADABLE) : PROTOCOL_NAME_ABSENT;
|
|
206
|
+
const protocolName = pn.state === 'named' ? pn.name : undefined;
|
|
182
207
|
const cause = obj !== undefined ? isolated(() => refusalCauseWordOf(obj)) : undefined;
|
|
183
208
|
const field = obj !== undefined ? isolated(() => readRefusalField(obj)) : undefined;
|
|
184
209
|
const currentPending = obj !== undefined ? isolated(() => readDecideCurrentPending(obj)) : undefined;
|
|
185
|
-
const attribution = attributionCarried
|
|
186
|
-
const ask = readDecisionRefusalAsk(err);
|
|
187
|
-
const delivery = refusalDeliveryOf(err, context);
|
|
188
|
-
const
|
|
210
|
+
const attribution = attributionCarried === undefined ? undefined : isolated(() => attributionRefusalOf(carrierRead, delivered ?? 'carrier', attributionCarried));
|
|
211
|
+
const ask = readDecisionRefusalAsk(err, answer, { ...carrierRead, protocolName: pn });
|
|
212
|
+
const delivery = refusalDeliveryOf(err, context, answer, carrierRead);
|
|
213
|
+
const unknownAfterRetry = guardedRead(() => (typeof context === 'object' && context !== null ? readOwnDataValue(context, 'afterRetry') : undefined)) === true && notPendingAfterRetry(status, true);
|
|
214
|
+
const standing = delivery.delivery === 'no_answer'
|
|
215
|
+
? undefined
|
|
216
|
+
: unknownAfterRetry
|
|
217
|
+
? 'ambiguous'
|
|
218
|
+
: ask.reading === 'settled'
|
|
219
|
+
? 'settled-elsewhere'
|
|
220
|
+
: delivery.delivery === 'refused'
|
|
221
|
+
? 'refused-pending'
|
|
222
|
+
: 'ambiguous';
|
|
189
223
|
const inRange = standing !== undefined && status !== undefined;
|
|
224
|
+
const conflict = inRange && status === 409 && obj !== undefined ? isolated(() => decisionConflictOf(obj, captured, pn)) : undefined;
|
|
225
|
+
const unrecoverable = inRange && status !== undefined && Number.isInteger(status) && status >= 400 && status <= 599 && isDecideRowUnrevivableCode(errorCode);
|
|
190
226
|
const transient = inRange &&
|
|
227
|
+
conflict !== 'grant_changed' &&
|
|
228
|
+
!unrecoverable &&
|
|
191
229
|
(TRANSIENT_STATUSES.has(status) || retriable || (status === 404 && obj !== undefined && isolated(() => notPendingCauseReading(obj)) === 'other_replica'));
|
|
192
|
-
const conflict = inRange && status === 409 && obj !== undefined ? isolated(() => decisionConflictOf(obj)) : undefined;
|
|
193
230
|
return Object.freeze({
|
|
194
231
|
...(status !== undefined ? { status } : {}),
|
|
195
232
|
...(errorCode !== undefined ? { errorCode } : {}),
|
|
@@ -197,7 +234,7 @@ export function mintDecisionRefusalReading(err, context, attributionCarried) {
|
|
|
197
234
|
...(retriable ? { retriable: true } : {}),
|
|
198
235
|
...(protocolName !== undefined ? { protocolName } : {}),
|
|
199
236
|
...(cause !== undefined || field !== undefined ? { extra: Object.freeze({ ...(cause !== undefined ? { cause } : {}), ...(field !== undefined ? { field } : {}) }) } : {}),
|
|
200
|
-
...(
|
|
237
|
+
...(blockedBy !== undefined ? { blockedBy } : {}),
|
|
201
238
|
...(currentPending !== undefined ? { currentPending } : {}),
|
|
202
239
|
...(attribution !== undefined && attribution !== null ? { denyAttributionRefusal: attribution } : {}),
|
|
203
240
|
ask: ask.reading,
|
|
@@ -206,6 +243,7 @@ export function mintDecisionRefusalReading(err, context, attributionCarried) {
|
|
|
206
243
|
...(standing !== undefined ? { standing } : {}),
|
|
207
244
|
...(transient ? { transient: true } : {}),
|
|
208
245
|
...(conflict !== undefined ? { conflict } : {}),
|
|
246
|
+
...(unrecoverable ? { unrecoverable: true } : {}),
|
|
209
247
|
});
|
|
210
248
|
}
|
|
211
249
|
export function readDecisionRefusalReading(err, context) {
|
|
@@ -223,12 +261,14 @@ function classifiedOf(reading) {
|
|
|
223
261
|
const errorCode = typeof code === 'string' && isDisplayableWireCode(code) ? code : undefined;
|
|
224
262
|
const transient = ownDataField(reading, 'transient') === true;
|
|
225
263
|
const conflict = ownDataField(reading, 'conflict');
|
|
264
|
+
const unrecoverable = ownDataField(reading, 'unrecoverable') === true;
|
|
226
265
|
return Object.freeze({
|
|
227
266
|
standing,
|
|
228
267
|
status,
|
|
229
268
|
...(errorCode !== undefined ? { errorCode } : {}),
|
|
230
269
|
...(transient ? { transient: true } : {}),
|
|
231
270
|
...(typeof conflict === 'string' ? { conflict: conflict } : {}),
|
|
271
|
+
...(unrecoverable ? { unrecoverable: true } : {}),
|
|
232
272
|
});
|
|
233
273
|
}
|
|
234
274
|
catch {
|
|
@@ -242,6 +282,9 @@ export function classifyDecisionRefusal(err, context) {
|
|
|
242
282
|
}
|
|
243
283
|
return classifiedOf(mintDecisionRefusalReading(err, context));
|
|
244
284
|
}
|
|
285
|
+
export function classifyDeliveredDecisionRefusal(err, delivered) {
|
|
286
|
+
return classifiedOf(mintDecisionRefusalReading(err, undefined, undefined, delivered));
|
|
287
|
+
}
|
|
245
288
|
export function liveAskPendingReading(envelope, approvalId) {
|
|
246
289
|
if (typeof approvalId !== 'string' || approvalId === '')
|
|
247
290
|
return 'unknown';
|
|
@@ -260,15 +303,14 @@ export function liveAskPendingReading(envelope, approvalId) {
|
|
|
260
303
|
export function decisionRefusalClosesOut(refusal, pending) {
|
|
261
304
|
if (pending !== 'pending' || typeof refusal !== 'object' || refusal === null)
|
|
262
305
|
return false;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
return false;
|
|
267
|
-
return standing === 'ambiguous' || standing === 'refused-pending';
|
|
268
|
-
}
|
|
269
|
-
catch {
|
|
306
|
+
const standing = readThrownSlot(refusal, 'standing', 'data');
|
|
307
|
+
const transient = readThrownSlot(refusal, 'transient', 'data');
|
|
308
|
+
if (transient === true || transient === THROWN_SLOT_UNREADABLE)
|
|
270
309
|
return false;
|
|
271
|
-
|
|
310
|
+
const conflict = readThrownSlot(refusal, 'conflict', 'data');
|
|
311
|
+
if (conflict === 'grant_changed' || conflict === THROWN_SLOT_UNREADABLE)
|
|
312
|
+
return false;
|
|
313
|
+
return standing === 'ambiguous' || standing === 'refused-pending';
|
|
272
314
|
}
|
|
273
315
|
export function undeliverableDecisionContent(facts) {
|
|
274
316
|
const code = typeof facts.errorCode === 'string' && isDisplayableWireCode(facts.errorCode) ? ` ${facts.errorCode}` : '';
|
|
@@ -284,3 +326,6 @@ export function undeliverableDecisionContent(facts) {
|
|
|
284
326
|
return `${head}; this turn was stopped instead of being left waiting. Update the client, or switch to a permission mode that shows you the approval and try again.`;
|
|
285
327
|
}
|
|
286
328
|
}
|
|
329
|
+
export function decideRowUnrevivableNotice(lang) {
|
|
330
|
+
return renderMessage(msg('notice.decide.rowUnrevivable'), isUiLanguage(lang) ? lang : undefined);
|
|
331
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentClient, ElicitResponse } from '@sema-agent/sdk';
|
|
2
|
+
import type { UiLanguage } from '../env/uiLanguage.js';
|
|
2
3
|
import { type AskGoneDetail } from '../decideReceipt.js';
|
|
3
4
|
import type { ApprovalDecidedByReading } from '../approvalDecidedByCapability.js';
|
|
4
5
|
import { type DecisionNoteAudit } from './approvalDecisionNoteAudit.js';
|
|
@@ -65,6 +66,7 @@ interface HitlDecisionOutcomeBase {
|
|
|
65
66
|
readonly attributionDropped?: true;
|
|
66
67
|
readonly attributionRenamed?: true;
|
|
67
68
|
readonly pending?: LiveAskPendingReading;
|
|
69
|
+
readonly parkingRetried?: true;
|
|
68
70
|
}
|
|
69
71
|
export interface HitlDecisionApplied extends HitlDecisionOutcomeBase {
|
|
70
72
|
readonly kind: 'applied';
|
|
@@ -110,4 +112,5 @@ export interface HitlDecisionSendTiming {
|
|
|
110
112
|
export declare function __setHitlDecisionSendTimingForTests(t?: HitlDecisionSendTiming): void;
|
|
111
113
|
export declare function hitlAskIdempotencyKey(askId: string, verdict: 'approve' | 'deny'): string;
|
|
112
114
|
export declare function sendHitlDecision(request: HitlDecisionSendRequest, deps: HitlDecisionSendDeps): Promise<HitlDecisionSendOutcome>;
|
|
115
|
+
export declare function hitlDecisionOutcomeContent(outcome: HitlDecisionSendOutcome, lang?: UiLanguage): string | undefined;
|
|
113
116
|
export {};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { settleWithinDeadline } from '../abortableSleep.js';
|
|
2
2
|
import { hostLog } from '../host.js';
|
|
3
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
3
4
|
import { askGoneFromError } from '../decideReceipt.js';
|
|
4
|
-
import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
|
|
5
|
-
import {
|
|
5
|
+
import { appendOwnElement, guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
|
|
6
|
+
import { effectiveCodeOf, ownReadingSlot } from '../engineWireFor.js';
|
|
6
7
|
import { ASK_DECISION_LANE_DISABLED, ASK_GONE, ASK_GONE_PARKED, ASK_IDEMPOTENCY_CONFLICT, ASK_NOT_FOUND, ASK_PARKING_RETRY } from '../engineErrorCodes.js';
|
|
7
|
-
import { readErrorNumber, readErrorString, readThrownSlot
|
|
8
|
+
import { isSlotCarrier, readErrorNumber, readErrorString, readThrownSlot } from '../wireFailureShape.js';
|
|
8
9
|
import { readDecisionNoteAudit } from './approvalDecisionNoteAudit.js';
|
|
9
|
-
import { deliverWithAttributionLadder } from './attributionLadder.js';
|
|
10
|
-
import {
|
|
10
|
+
import { carrierReadOf, deliverWithAttributionLadder, isLocalSafetyStop } from './attributionLadder.js';
|
|
11
|
+
import { budgetSpent, deliverApprovalDecision, deliveryTiming, isAborted, newSendTally, PARKING_WAIT_CAP_MS, setDeliveryTimingForTests, sleepFor, settledTransportReadingOf, withTransportRetry, deliveryReadingOf, } from './approvalDelivery.js';
|
|
12
|
+
import { ASK_DECIDED_CODE, classifyDeliveredDecisionRefusal, decisionRefusalClosesOut, notPendingAfterRetry } from './decisionRefusal.js';
|
|
11
13
|
import { addDecisionOpKeys, closeDecisionOp, decisionLedgerKeysOf, decisionOpsWithKey, openDecisionOp } from './decisionLedger.js';
|
|
12
14
|
import { hostHoldIsActive, takeHostHoldLedgerOp, tryHoldApprovalNow } from './approvalHolds.js';
|
|
13
15
|
import { answerPayloadFor, decisionAttributionKeyOf, isToolApprovalRespondReplayed, readApprovalDenySettledBy, readToolApprovalRespondAck, readToolApprovalRespondParking, } from './toolApprovalWire.js';
|
|
@@ -15,86 +17,19 @@ export const HITL_DECISION_FAMILIES = Object.freeze(['approval', 'ask', 'elicita
|
|
|
15
17
|
export const HITL_DECISION_NOT_APPLIED_CAUSES = Object.freeze(['gone', 'parked', 'parking', 'lane_disabled', 'refused', 'idempotency_crossed']);
|
|
16
18
|
export const HITL_DECISION_UNCONFIRMED_CAUSES = Object.freeze(['transport', 'server_error', 'local_error', 'aborted', 'gone_after_retry']);
|
|
17
19
|
export const HITL_DECISION_NOT_SENT_CAUSES = Object.freeze(['aborted', 'duplicate_in_flight', 'invalid_request', 'no_verb', 'not_an_answer']);
|
|
18
|
-
const RETRY_DELAYS_MS = Object.freeze([500, 1_000, 2_000]);
|
|
19
|
-
const RETRY_BUDGET_MS = 8_000;
|
|
20
20
|
const PARKING_POLL_MAX = 2;
|
|
21
21
|
const PARKING_POLL_DELAY_MS = 400;
|
|
22
|
-
const PARKING_POLL_WAIT_CAP_MS = 5_000;
|
|
23
22
|
export const HITL_DECISION_READBACK_BUDGET_MS = 4_000;
|
|
24
23
|
const IDEMPOTENCY_KEY_MAX = 255;
|
|
25
|
-
let timingOverride;
|
|
26
24
|
export function __setHitlDecisionSendTimingForTests(t) {
|
|
27
|
-
|
|
25
|
+
setDeliveryTimingForTests(t);
|
|
28
26
|
}
|
|
29
27
|
export function hitlAskIdempotencyKey(askId, verdict) {
|
|
30
28
|
const key = `sema-ask:${askId}:${verdict}`;
|
|
31
29
|
return key.length <= IDEMPOTENCY_KEY_MAX ? key : key.slice(0, IDEMPOTENCY_KEY_MAX);
|
|
32
30
|
}
|
|
33
|
-
function isAbortShaped(e) {
|
|
34
|
-
const name = readThrownSlot(e, 'name');
|
|
35
|
-
return name === 'TimeoutError' || name === 'AbortError';
|
|
36
|
-
}
|
|
37
|
-
function transportClassOf(e, signal) {
|
|
38
|
-
if (signal?.aborted === true)
|
|
39
|
-
return 'aborted';
|
|
40
|
-
const status = typeof e === 'object' && e !== null ? readThrownStatusSlot(e) : undefined;
|
|
41
|
-
if (status === THROWN_SLOT_UNREADABLE)
|
|
42
|
-
return 'local_error';
|
|
43
|
-
if (typeof status === 'number')
|
|
44
|
-
return status === 501 ? 'verdict' : status >= 500 ? 'server_5xx' : 'verdict';
|
|
45
|
-
return isWireTransportError(e) || isAbortShaped(e) ? 'transport' : 'local_error';
|
|
46
|
-
}
|
|
47
|
-
function attemptSignal(attempt, caller, startedAt, budgetMs) {
|
|
48
|
-
if (attempt === 1)
|
|
49
|
-
return caller;
|
|
50
|
-
const deadline = AbortSignal.timeout(Math.max(1, budgetMs - (Date.now() - startedAt)));
|
|
51
|
-
if (caller === undefined)
|
|
52
|
-
return deadline;
|
|
53
|
-
if (typeof AbortSignal.any === 'function')
|
|
54
|
-
return AbortSignal.any([caller, deadline]);
|
|
55
|
-
const ac = new AbortController();
|
|
56
|
-
const abort = (s) => ac.abort(s.reason);
|
|
57
|
-
if (caller.aborted)
|
|
58
|
-
abort(caller);
|
|
59
|
-
else
|
|
60
|
-
caller.addEventListener('abort', () => abort(caller), { once: true });
|
|
61
|
-
deadline.addEventListener('abort', () => abort(deadline), { once: true });
|
|
62
|
-
return ac.signal;
|
|
63
|
-
}
|
|
64
|
-
function budgetSpent(tally, extraMs) {
|
|
65
|
-
return Date.now() - tally.startedAt + extraMs >= (timingOverride?.budgetMs ?? RETRY_BUDGET_MS);
|
|
66
|
-
}
|
|
67
|
-
function isAborted(signal) {
|
|
68
|
-
return signal?.aborted === true;
|
|
69
|
-
}
|
|
70
|
-
function sleepFor(ms, signal) {
|
|
71
|
-
return abortableSleep(ms, signal ?? new AbortController().signal);
|
|
72
|
-
}
|
|
73
|
-
async function withTransportRetry(send, signal, tally) {
|
|
74
|
-
const delays = timingOverride?.delays ?? RETRY_DELAYS_MS;
|
|
75
|
-
const budgetMs = timingOverride?.budgetMs ?? RETRY_BUDGET_MS;
|
|
76
|
-
const startedAt = tally.startedAt;
|
|
77
|
-
for (let attempt = 1;; attempt++) {
|
|
78
|
-
tally.attempts++;
|
|
79
|
-
try {
|
|
80
|
-
return await send(attemptSignal(attempt, signal, startedAt, budgetMs));
|
|
81
|
-
}
|
|
82
|
-
catch (e) {
|
|
83
|
-
const cls = transportClassOf(e, signal);
|
|
84
|
-
const delay = delays[attempt - 1] ?? 0;
|
|
85
|
-
const retriable = cls === 'transport' || cls === 'server_5xx';
|
|
86
|
-
const overBudget = Date.now() - startedAt + delay >= budgetMs;
|
|
87
|
-
if (!retriable || attempt > delays.length || overBudget)
|
|
88
|
-
throw e;
|
|
89
|
-
tally.retried = true;
|
|
90
|
-
await sleepFor(delay, signal);
|
|
91
|
-
if (signal?.aborted === true)
|
|
92
|
-
throw e;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
31
|
function retryAfterMsOf(e) {
|
|
97
|
-
if (
|
|
32
|
+
if (!isSlotCarrier(e))
|
|
98
33
|
return undefined;
|
|
99
34
|
const ms = readErrorNumber(e, 'retryAfterMs');
|
|
100
35
|
if (ms !== undefined && Number.isFinite(ms) && ms >= 0)
|
|
@@ -115,21 +50,32 @@ function actorLabelOf(e) {
|
|
|
115
50
|
function verdictOf(word) {
|
|
116
51
|
return word === 'approve' || word === 'allow' || word === 'allow_session' ? 'approve' : word === 'deny' ? 'deny' : undefined;
|
|
117
52
|
}
|
|
118
|
-
function outcomeOfThrown(e, family, ours, signal, tally, noteCapable) {
|
|
53
|
+
function outcomeOfThrown(e, family, ours, signal, tally, noteCapable, reading = settledTransportReadingOf(e, signal, tally)) {
|
|
119
54
|
const base = { family, attempts: tally.attempts };
|
|
120
|
-
const cls =
|
|
55
|
+
const cls = reading.cls;
|
|
121
56
|
if (cls === 'aborted')
|
|
122
57
|
return { ...base, kind: 'unconfirmed', cause: 'aborted' };
|
|
123
58
|
if (cls === 'transport')
|
|
124
59
|
return { ...base, kind: 'unconfirmed', cause: 'transport' };
|
|
125
60
|
if (cls === 'local_error')
|
|
126
61
|
return { ...base, kind: 'unconfirmed', cause: 'local_error' };
|
|
62
|
+
const answered = ownReadingSlot(reading, 'answered');
|
|
63
|
+
if (answered === undefined)
|
|
64
|
+
return { ...base, kind: 'unconfirmed', cause: 'local_error' };
|
|
65
|
+
return answeredOutcome(answered.layer, answered.status, reading, cls, family, ours, tally, noteCapable, base);
|
|
66
|
+
}
|
|
67
|
+
function answeredOutcome(e, status, reading, cls, family, ours, tally, noteCapable, base) {
|
|
127
68
|
const obj = e;
|
|
128
|
-
const status = readThrownStatusSlot(obj);
|
|
129
69
|
if (cls === 'server_5xx')
|
|
130
70
|
return { ...base, kind: 'unconfirmed', cause: 'server_error', status };
|
|
131
|
-
const
|
|
71
|
+
const answeredCapture = ownReadingSlot(reading, 'answered');
|
|
72
|
+
const code = answeredCapture !== undefined ? effectiveCodeOf(answeredCapture.code) : undefined;
|
|
132
73
|
const at = { ...base, status, ...(code !== undefined ? { errorCode: code } : {}) };
|
|
74
|
+
const retried = family !== 'ask' && tally.retried;
|
|
75
|
+
if (retried && notPendingAfterRetry(status, true))
|
|
76
|
+
return { ...base, kind: 'unconfirmed', cause: 'gone_after_retry', status };
|
|
77
|
+
if (isSafetyStopLayer(e, reading))
|
|
78
|
+
return { ...at, kind: 'not_applied', cause: 'refused', ...refusalOf(e, reading) };
|
|
133
79
|
if (family === 'ask') {
|
|
134
80
|
switch (code) {
|
|
135
81
|
case ASK_DECIDED_CODE: {
|
|
@@ -148,7 +94,7 @@ function outcomeOfThrown(e, family, ours, signal, tally, noteCapable) {
|
|
|
148
94
|
};
|
|
149
95
|
}
|
|
150
96
|
case ASK_IDEMPOTENCY_CONFLICT:
|
|
151
|
-
return { ...at, kind: 'not_applied', cause: 'idempotency_crossed', ...refusalOf(e) };
|
|
97
|
+
return { ...at, kind: 'not_applied', cause: 'idempotency_crossed', ...refusalOf(e, reading) };
|
|
152
98
|
case ASK_GONE_PARKED: {
|
|
153
99
|
const sessionId = readErrorString(obj, 'sessionId');
|
|
154
100
|
return { ...at, kind: 'not_applied', cause: 'parked', ...(sessionId !== undefined ? { sessionId } : {}) };
|
|
@@ -169,15 +115,17 @@ function outcomeOfThrown(e, family, ours, signal, tally, noteCapable) {
|
|
|
169
115
|
break;
|
|
170
116
|
}
|
|
171
117
|
}
|
|
172
|
-
if (status === 404 || status === 410)
|
|
173
|
-
return
|
|
174
|
-
}
|
|
118
|
+
if (status === 404 || status === 410)
|
|
119
|
+
return { ...at, kind: 'not_applied', cause: 'gone' };
|
|
175
120
|
if (status === 501)
|
|
176
121
|
return { ...at, kind: 'not_applied', cause: 'lane_disabled' };
|
|
177
|
-
return { ...at, kind: 'not_applied', cause: 'refused', ...refusalOf(e) };
|
|
122
|
+
return { ...at, kind: 'not_applied', cause: 'refused', ...refusalOf(e, reading) };
|
|
123
|
+
}
|
|
124
|
+
function isSafetyStopLayer(layer, reading) {
|
|
125
|
+
return isLocalSafetyStop(carrierReadOf(layer, reading), reading);
|
|
178
126
|
}
|
|
179
|
-
function refusalOf(e) {
|
|
180
|
-
const r =
|
|
127
|
+
function refusalOf(e, reading) {
|
|
128
|
+
const r = classifyDeliveredDecisionRefusal(e, reading);
|
|
181
129
|
return r !== undefined ? { refusal: r } : {};
|
|
182
130
|
}
|
|
183
131
|
async function sendApprovalFamily(respond, approvalId, answer, ctx) {
|
|
@@ -189,19 +137,29 @@ async function sendApprovalFamily(respond, approvalId, answer, ctx) {
|
|
|
189
137
|
const ladder = { lastCarried: false, dropped: false, renamed: false };
|
|
190
138
|
const ours = verdictOf(payload.decision);
|
|
191
139
|
const extras = bodyFacts(answer, payload, false);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
140
|
+
const delivery = await deliverApprovalDecision({
|
|
141
|
+
approvalId,
|
|
142
|
+
body,
|
|
143
|
+
send: (b, signal) => respond(approvalId, b, signal !== undefined ? { signal } : undefined),
|
|
144
|
+
signal: ctx.signal,
|
|
145
|
+
tally: ctx.tally,
|
|
146
|
+
ladder,
|
|
147
|
+
parkingOf: (raw) => {
|
|
148
|
+
const p = readToolApprovalRespondParking(raw);
|
|
149
|
+
return p?.kind === 'parking' ? p.view : undefined;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
const retriedFact = ownReadingSlot(delivery, 'parkingRetried') === true ? { parkingRetried: true } : {};
|
|
153
|
+
if (delivery.kind === 'thrown')
|
|
154
|
+
return { ...outcomeOfThrown(delivery.error, 'approval', ours, ctx.signal, ctx.tally, ctx.noteCapable), ...extras, ...retriedFact };
|
|
155
|
+
const raw = delivery.raw;
|
|
156
|
+
const facts = { ...extras, ...retriedFact, ...(ladder.dropped ? { attributionDropped: true } : {}), ...(ladder.renamed ? { attributionRenamed: true } : {}) };
|
|
200
157
|
const base = { family: 'approval', attempts: ctx.tally.attempts, ...facts };
|
|
201
158
|
const parking = readToolApprovalRespondParking(raw);
|
|
202
159
|
if (parking !== undefined) {
|
|
203
160
|
const view = parking.kind === 'parking' && parking.view.approvalId === approvalId ? parking.view : undefined;
|
|
204
|
-
|
|
161
|
+
const hint = view !== undefined ? ownReadingSlot(view, 'retryAfterMs') : undefined;
|
|
162
|
+
return { ...base, kind: 'not_applied', cause: 'parking', ...(view !== undefined ? { parking: view, ...(hint !== undefined ? { retryAfterMs: hint } : {}) } : {}) };
|
|
205
163
|
}
|
|
206
164
|
const parsed = readToolApprovalRespondAck(raw);
|
|
207
165
|
if (parsed !== undefined && isToolApprovalRespondReplayed(parsed)) {
|
|
@@ -244,13 +202,13 @@ async function sendAskFamily(respondForFallback, decideAsk, req, ctx) {
|
|
|
244
202
|
const extras = bodyFacts(req.answer, payload, true);
|
|
245
203
|
const ladder = { lastCarried: false, dropped: false, renamed: false };
|
|
246
204
|
let current = body;
|
|
247
|
-
const parkingDelay =
|
|
205
|
+
const parkingDelay = deliveryTiming().parkingDelayMs ?? PARKING_POLL_DELAY_MS;
|
|
248
206
|
for (let poll = 0;; poll++) {
|
|
249
207
|
try {
|
|
250
208
|
const raw = await deliverWithAttributionLadder(current, (b) => {
|
|
251
209
|
current = b;
|
|
252
210
|
return withTransportRetry((signal) => decideAsk(req.taskId, req.askId, b, signal !== undefined ? { signal } : undefined), ctx.signal, ctx.tally);
|
|
253
|
-
}, ctx.signal, ladder);
|
|
211
|
+
}, ctx.signal, ladder, undefined, { kind: 'delivered', readingOf: (thrown) => deliveryReadingOf(thrown, ctx.tally) });
|
|
254
212
|
return {
|
|
255
213
|
family: 'ask',
|
|
256
214
|
attempts: ctx.tally.attempts,
|
|
@@ -262,14 +220,17 @@ async function sendAskFamily(respondForFallback, decideAsk, req, ctx) {
|
|
|
262
220
|
};
|
|
263
221
|
}
|
|
264
222
|
catch (e) {
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
223
|
+
const settled = settledTransportReadingOf(e, ctx.signal, ctx.tally);
|
|
224
|
+
const settledAnswer = ownReadingSlot(settled, 'answered');
|
|
225
|
+
const code = settledAnswer !== undefined ? effectiveCodeOf(settledAnswer.code) : undefined;
|
|
226
|
+
const wait = Math.max(parkingDelay * (poll + 1), retryAfterMsOf(settledAnswer?.layer ?? e) ?? 0);
|
|
227
|
+
const safetyStop = settledAnswer !== undefined && isSafetyStopLayer(settledAnswer.layer, settled);
|
|
228
|
+
if (code === ASK_PARKING_RETRY && !safetyStop && poll < PARKING_POLL_MAX && !isAborted(ctx.signal) && wait <= PARKING_WAIT_CAP_MS && !budgetSpent(ctx.tally, wait)) {
|
|
268
229
|
await sleepFor(wait, ctx.signal);
|
|
269
230
|
if (!isAborted(ctx.signal))
|
|
270
231
|
continue;
|
|
271
232
|
}
|
|
272
|
-
const out = outcomeOfThrown(e, 'ask', verdict, ctx.signal, ctx.tally, ctx.noteCapable);
|
|
233
|
+
const out = outcomeOfThrown(e, 'ask', verdict, ctx.signal, ctx.tally, ctx.noteCapable, settled);
|
|
273
234
|
if (out.kind === 'not_applied' && out.cause === 'lane_disabled' && code === ASK_DECISION_LANE_DISABLED && req.approvalId !== undefined) {
|
|
274
235
|
if (respondForFallback !== undefined && ctx.signal?.aborted !== true) {
|
|
275
236
|
const fb = await sendApprovalFamily(respondForFallback, req.approvalId, req.answer, ctx);
|
|
@@ -303,7 +264,7 @@ function validElicitResponse(r) {
|
|
|
303
264
|
const x = readOwnDataValue(v, String(i));
|
|
304
265
|
if (typeof x !== 'string')
|
|
305
266
|
return undefined;
|
|
306
|
-
copy
|
|
267
|
+
appendOwnElement(copy, x);
|
|
307
268
|
}
|
|
308
269
|
Object.defineProperty(out, k, { value: copy, enumerable: true, writable: true, configurable: true });
|
|
309
270
|
}
|
|
@@ -524,7 +485,7 @@ export async function sendHitlDecision(request, deps) {
|
|
|
524
485
|
const decidedBy = hostField(deps, 'approvalDecidedBy');
|
|
525
486
|
const ctx = {
|
|
526
487
|
signal,
|
|
527
|
-
tally:
|
|
488
|
+
tally: newSendTally(),
|
|
528
489
|
noteCapable: hostField(deps, 'approvalDecisionNoteCapable') === true,
|
|
529
490
|
decidedBy: typeof decidedBy === 'object' && decidedBy !== null ? decidedBy : undefined,
|
|
530
491
|
};
|
|
@@ -577,3 +538,26 @@ export async function sendHitlDecision(request, deps) {
|
|
|
577
538
|
ownHold.release(out.kind === 'applied' || out.kind === 'settled_elsewhere' ? 'answered' : undefined);
|
|
578
539
|
return Object.freeze(out);
|
|
579
540
|
}
|
|
541
|
+
export function hitlDecisionOutcomeContent(outcome, lang) {
|
|
542
|
+
try {
|
|
543
|
+
if (typeof outcome !== 'object' || outcome === null)
|
|
544
|
+
return undefined;
|
|
545
|
+
const kind = readOwnDataValue(outcome, 'kind');
|
|
546
|
+
if (kind === 'settled_elsewhere') {
|
|
547
|
+
if (readOwnDataValue(outcome, 'contrary') !== true)
|
|
548
|
+
return undefined;
|
|
549
|
+
const first = readOwnDataValue(outcome, 'firstDecision');
|
|
550
|
+
if (first === 'deny')
|
|
551
|
+
return renderMessage(msg('approval.decision.settledElsewhereContrary.deniedFirst'), lang);
|
|
552
|
+
if (first === 'approve')
|
|
553
|
+
return renderMessage(msg('approval.decision.settledElsewhereContrary.approvedFirst'), lang);
|
|
554
|
+
return undefined;
|
|
555
|
+
}
|
|
556
|
+
if (kind === 'unconfirmed' && readOwnDataValue(outcome, 'cause') === 'gone_after_retry')
|
|
557
|
+
return renderMessage(msg('approval.decision.unconfirmedAfterRetry'), lang);
|
|
558
|
+
return undefined;
|
|
559
|
+
}
|
|
560
|
+
catch {
|
|
561
|
+
return undefined;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
@@ -70,6 +70,7 @@ export interface FrameRouterCtx {
|
|
|
70
70
|
signal?: AbortSignal | undefined;
|
|
71
71
|
}
|
|
72
72
|
export declare function isAskTool(toolName: string | undefined): boolean;
|
|
73
|
+
export declare function questionCardVerdict(carrier: object | null | undefined): boolean | undefined;
|
|
73
74
|
export declare function parkGateArmOf(gate: unknown): GateKind | null;
|
|
74
75
|
export declare function isHostProgressFrame(ev: AgentEvent): boolean;
|
|
75
76
|
interface HeldFlushInterruptEvidence {
|
package/dist/hitl/frameRouter.js
CHANGED
|
@@ -5,6 +5,8 @@ import { classifierDenyFromToolEnd } from '../classifierVerdictWire.js';
|
|
|
5
5
|
import { toolEndOutputText } from '../toolResultContent.js';
|
|
6
6
|
import { GATE_PARKED_ERROR_CODE } from '../engineErrorCodes.js';
|
|
7
7
|
import { readRunTerminal, runTerminalCode, runTerminalGateKind, runTerminalGateToolName } from '../runTerminal.js';
|
|
8
|
+
import { readApprovalCardWord } from './approvalCardReading.js';
|
|
9
|
+
import { guardedRead, readOwnDataValue } from '../ownKey.js';
|
|
8
10
|
import { parkHeldCallIdOf } from '../engineRowRef.js';
|
|
9
11
|
import { inheritFrameBinding } from '../frameBinding.js';
|
|
10
12
|
import { surfaceForCurrentSession, surfaceReplayedApprovalListUnreadable } from './hitlHostSurface.js';
|
|
@@ -102,6 +104,10 @@ function parkFamilyEvidence(led, gateToolName, gatedCallId) {
|
|
|
102
104
|
return false;
|
|
103
105
|
return gatedCallId === undefined || led.isFsOrShellGatedCall(gatedCallId);
|
|
104
106
|
}
|
|
107
|
+
export function questionCardVerdict(carrier) {
|
|
108
|
+
const word = readApprovalCardWord(carrier);
|
|
109
|
+
return word === undefined ? undefined : word === 'question';
|
|
110
|
+
}
|
|
105
111
|
export function parkGateArmOf(gate) {
|
|
106
112
|
if (gate === null || typeof gate !== 'object')
|
|
107
113
|
return null;
|
|
@@ -117,7 +123,7 @@ export function parkGateArmOf(gate) {
|
|
|
117
123
|
const leg = durableDecideLegOf(typeof kind === 'string' ? { gateKind: kind } : null);
|
|
118
124
|
if (leg !== 'approval' && leg !== 'absent')
|
|
119
125
|
return null;
|
|
120
|
-
if (isAskToolLoose(toolName))
|
|
126
|
+
if (questionCardVerdict(gate) ?? isAskToolLoose(toolName))
|
|
121
127
|
return 'ask';
|
|
122
128
|
if (leg === 'approval')
|
|
123
129
|
return 'fs';
|
|
@@ -147,7 +153,8 @@ function parkGateOf(result) {
|
|
|
147
153
|
if (typeof taskId !== 'string' || taskId.length === 0)
|
|
148
154
|
return null;
|
|
149
155
|
const toolName = runTerminalGateToolName(read);
|
|
150
|
-
const
|
|
156
|
+
const approvalCard = guardedRead(() => readOwnDataValue(read.gate, 'approvalCard'));
|
|
157
|
+
const arm = parkGateArmOf({ kind: runTerminalGateKind(read), toolName, approvalCard });
|
|
151
158
|
return arm === null ? null : { taskId, gate: arm, toolName };
|
|
152
159
|
}
|
|
153
160
|
function parkGatedCallId(src) {
|