@sema-agent/client-core 0.93.1 → 0.95.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 +554 -0
- package/README.md +89 -55
- package/dist/adapt/arms.js +13 -11
- package/dist/adapt/panelTasks.js +4 -10
- package/dist/adapt/toolCards.js +2 -2
- package/dist/adapt/wireShapes.js +3 -8
- package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
- package/dist/adapter/activeRunSelfHeal.js +20 -12
- package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
- package/dist/adapter/downstream/terminalToSdkResult.js +13 -6
- package/dist/adapter/runStream.js +2 -1
- package/dist/adapter/types.d.ts +7 -0
- package/dist/adapter/types.js +15 -0
- package/dist/agentSession/backgroundView.js +5 -1
- package/dist/agentSession/engineAgentRegistryRead.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +5 -3
- package/dist/agentsWireCaps.d.ts +17 -0
- package/dist/agentsWireCaps.js +111 -1
- package/dist/approvalDecidedByCapability.d.ts +0 -1
- package/dist/approvalDecidedByCapability.js +2 -7
- package/dist/approvalReachWire.d.ts +18 -0
- package/dist/approvalReachWire.js +58 -0
- package/dist/approvalsStreamLiveCapability.d.ts +0 -1
- package/dist/approvalsStreamLiveCapability.js +15 -14
- package/dist/atMostOnce.d.ts +8 -0
- package/dist/atMostOnce.js +36 -0
- package/dist/attachmentSeatCapability.d.ts +0 -1
- package/dist/attachmentSeatCapability.js +0 -3
- package/dist/attachmentsWireCaps.js +11 -6
- package/dist/bashExitReading.d.ts +10 -0
- package/dist/bashExitReading.js +12 -0
- package/dist/callerCwdCapability.d.ts +15 -0
- package/dist/callerCwdCapability.js +42 -0
- package/dist/centerWiringCapability.d.ts +1 -3
- package/dist/centerWiringCapability.js +18 -21
- package/dist/classifierStatus.js +4 -4
- package/dist/cloudConfigWireCaps.js +43 -21
- package/dist/compensations.js +1 -1
- package/dist/controlRouter.js +3 -10
- package/dist/coreValuePorts.d.ts +64 -1
- package/dist/coreValuePorts.js +30 -0
- package/dist/cycleOrder.d.ts +15 -0
- package/dist/cycleOrder.js +45 -0
- package/dist/decideFailureNote.js +4 -1
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/decideReceipt.js +41 -13
- package/dist/declared/supportFloorDeclared.d.ts +1 -0
- package/dist/declared/supportFloorDeclared.js +5 -0
- package/dist/detachWire.d.ts +1 -4
- package/dist/detachWire.js +1 -1
- package/dist/deviceExecutorManagementCapability.d.ts +0 -1
- package/dist/deviceExecutorManagementCapability.js +36 -40
- package/dist/deviceFlowPolling.d.ts +5 -0
- package/dist/deviceFlowPolling.js +28 -0
- package/dist/deviceRebind.d.ts +88 -0
- package/dist/deviceRebind.js +242 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +963 -30
- package/dist/engineAgentAbsence.d.ts +2 -2
- package/dist/engineAgentPanelStore.d.ts +8 -18
- package/dist/engineAgentPanelStore.js +19 -537
- package/dist/engineCapReader.d.ts +6 -6
- package/dist/engineCapReader.js +30 -43
- package/dist/engineCapsCache.d.ts +7 -2
- package/dist/engineCapsCache.js +64 -26
- package/dist/engineCredentialRequirement.d.ts +9 -0
- package/dist/engineCredentialRequirement.js +23 -0
- package/dist/engineEnvSourcing.d.ts +53 -0
- package/dist/engineEnvSourcing.js +81 -0
- package/dist/engineErrorCodes.d.ts +19 -4
- package/dist/engineErrorCodes.js +39 -21
- package/dist/engineIdentity.js +2 -0
- package/dist/engineNoticeCodes.d.ts +22 -2
- package/dist/engineNoticeCodes.js +73 -6
- package/dist/engineRefusedToolName.d.ts +1 -0
- package/dist/engineRefusedToolName.js +8 -0
- package/dist/engineWireSdk.js +2 -2
- package/dist/executionLaneCapability.d.ts +2 -3
- package/dist/executionLaneCapability.js +28 -28
- package/dist/fileHistoryCaptureCapability.d.ts +0 -1
- package/dist/fileHistoryCaptureCapability.js +13 -12
- package/dist/fileHistoryLegNotice.d.ts +14 -2
- package/dist/fileHistoryLegNotice.js +101 -15
- package/dist/fleet/fleetLedger.d.ts +2 -0
- package/dist/fleet/fleetLedger.js +74 -52
- package/dist/fleet/fleetProjection.d.ts +0 -3
- package/dist/fleet/fleetProjection.js +9 -16
- package/dist/fleetAgentPanelProjection.d.ts +4 -17
- package/dist/fleetAgentPanelProjection.js +7 -197
- package/dist/fleetAgentRowLike.d.ts +16 -0
- package/dist/fleetAgentRowLike.js +1 -0
- package/dist/gateOutcome.d.ts +2 -1
- package/dist/gateOutcome.js +33 -18
- package/dist/gateVocabulary.js +1 -1
- package/dist/generated/engineAskFaceTables.d.ts +3 -0
- package/dist/generated/engineAskFaceTables.js +12 -0
- package/dist/generated/engineFactTables.d.ts +4 -2
- package/dist/generated/engineFactTables.js +13 -0
- package/dist/generated/engineNoticeTables.d.ts +5 -0
- package/dist/generated/engineNoticeTables.js +7 -0
- package/dist/generated/sdkFactTables.d.ts +5 -0
- package/dist/generated/sdkFactTables.js +34 -0
- package/dist/generated/settingsSchemaFns.d.ts +10 -0
- package/dist/generated/settingsSchemaFns.js +22 -0
- package/dist/generated/settingsSchemaTables.d.ts +3 -0
- package/dist/generated/settingsSchemaTables.js +3 -0
- package/dist/headlessPermissionModeWire.d.ts +2 -2
- package/dist/headlessPermissionModeWire.js +11 -21
- package/dist/headlessReconnectWire.js +49 -20
- package/dist/hitl/allowRuleShadow.d.ts +1 -1
- package/dist/hitl/allowRuleShadow.js +49 -8
- package/dist/hitl/approvalCompleteParked.d.ts +1 -0
- package/dist/hitl/approvalCompleteParked.js +14 -0
- package/dist/hitl/approvalEndingCause.d.ts +5 -0
- package/dist/hitl/approvalEndingCause.js +61 -0
- package/dist/hitl/approvalHolds.d.ts +46 -0
- package/dist/hitl/approvalHolds.js +140 -0
- package/dist/hitl/approvalOutcomeNote.js +2 -1
- package/dist/hitl/approvalResolution.js +9 -1
- package/dist/hitl/approvalsFeed.js +23 -6
- package/dist/hitl/askGateWire.d.ts +2 -1
- package/dist/hitl/askGateWire.js +29 -1
- package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
- package/dist/hitl/automaticAnswerVerdict.js +71 -23
- package/dist/hitl/crashConverged.js +2 -0
- package/dist/hitl/decisionConflict.d.ts +3 -0
- package/dist/hitl/decisionConflict.js +43 -0
- package/dist/hitl/decisionRefusal.d.ts +23 -0
- package/dist/hitl/decisionRefusal.js +88 -0
- package/dist/hitl/frameRouter.d.ts +10 -0
- package/dist/hitl/frameRouter.js +71 -32
- package/dist/hitl/gateLedger.d.ts +8 -0
- package/dist/hitl/gateLedger.js +38 -0
- package/dist/hitl/hitlBridge.d.ts +14 -3
- package/dist/hitl/hitlBridge.js +75 -62
- package/dist/hitl/hitlHostSurface.d.ts +3 -0
- package/dist/hitl/hitlHostSurface.js +17 -15
- package/dist/hitl/livePendingAsk.d.ts +16 -6
- package/dist/hitl/livePendingAsk.js +36 -4
- package/dist/hitl/localAllowRule.js +2 -1
- package/dist/hitl/noAllowCause.d.ts +9 -0
- package/dist/hitl/noAllowCause.js +26 -0
- package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
- package/dist/hitl/parkExpiryJudgements.js +46 -0
- package/dist/hitl/parkResolver.d.ts +3 -7
- package/dist/hitl/parkResolver.js +55 -28
- package/dist/hitl/parkRowBirthWait.js +2 -1
- package/dist/hitl/persistedRulesWire.d.ts +6 -1
- package/dist/hitl/persistedRulesWire.js +16 -4
- package/dist/hitl/planReviewWire.d.ts +2 -3
- package/dist/hitl/planReviewWire.js +86 -39
- package/dist/hitl/replayedApproval.d.ts +8 -0
- package/dist/hitl/replayedApproval.js +125 -10
- package/dist/hitl/resumeRunningCard.d.ts +2 -0
- package/dist/hitl/resumeRunningCard.js +15 -4
- package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
- package/dist/hitl/sessionPolicyDeliverable.js +3 -8
- package/dist/hitl/sessionPolicyWire.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +50 -5
- package/dist/hitl/toolApprovalWire.js +368 -56
- package/dist/hooksWireCaps.js +38 -6
- package/dist/host.d.ts +5 -0
- package/dist/host.js +3 -1
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +25 -0
- package/dist/humanTurnRead.d.ts +15 -1
- package/dist/humanTurnRead.js +28 -2
- package/dist/index.d.ts +45 -14
- package/dist/index.js +33 -12
- package/dist/interactiveInterrupt.d.ts +8 -0
- package/dist/interactiveInterrupt.js +54 -0
- package/dist/limitsWire.d.ts +5 -1
- package/dist/limitsWire.js +51 -13
- package/dist/liveModelCatalog.d.ts +109 -0
- package/dist/liveModelCatalog.js +344 -18
- package/dist/mcpEngineLeg.d.ts +25 -0
- package/dist/mcpEngineLeg.js +71 -15
- package/dist/mcpPanel.js +2 -1
- package/dist/mcpProbeCapability.d.ts +0 -1
- package/dist/mcpProbeCapability.js +13 -12
- package/dist/mcpReconnect.d.ts +1 -3
- package/dist/mcpReconnect.js +20 -10
- package/dist/memoryComplianceCapability.d.ts +0 -1
- package/dist/memoryComplianceCapability.js +14 -13
- package/dist/memoryOriginCapability.d.ts +0 -1
- package/dist/memoryOriginCapability.js +14 -13
- package/dist/memoryVerbsWire.d.ts +1 -1
- package/dist/memoryVerbsWire.js +4 -0
- package/dist/model/liveCatalogShape.d.ts +14 -0
- package/dist/model/liveCatalogShape.js +71 -0
- package/dist/model/modelSupplyRules.d.ts +1 -0
- package/dist/model/modelSupplyRules.js +30 -9
- package/dist/model/modelsPolicy.d.ts +21 -0
- package/dist/model/modelsPolicy.js +90 -0
- package/dist/modelIdentityResolvability.d.ts +4 -2
- package/dist/modelIdentityResolvability.js +25 -5
- package/dist/modelSwitchFallback.d.ts +69 -0
- package/dist/modelSwitchFallback.js +206 -0
- package/dist/notifications.js +12 -11
- package/dist/outputStyleSeatCapability.d.ts +15 -0
- package/dist/outputStyleSeatCapability.js +42 -0
- package/dist/ownKey.d.ts +7 -0
- package/dist/ownKey.js +58 -0
- package/dist/panelReduce.d.ts +114 -0
- package/dist/panelReduce.js +1135 -0
- package/dist/panelStateHolder.d.ts +17 -0
- package/dist/panelStateHolder.js +201 -0
- package/dist/peerLaneCapability.d.ts +0 -1
- package/dist/peerLaneCapability.js +15 -14
- package/dist/permissionModesCapability.d.ts +0 -1
- package/dist/permissionModesCapability.js +5 -10
- package/dist/permissionRuleIssue.js +1 -1
- package/dist/permissionRulesWriteCapability.d.ts +0 -1
- package/dist/permissionRulesWriteCapability.js +15 -14
- package/dist/permissionsAllowGrantCapability.d.ts +2 -1
- package/dist/permissionsAllowGrantCapability.js +35 -19
- package/dist/permissionsDeclaration.d.ts +16 -1
- package/dist/permissionsDeclaration.js +142 -15
- package/dist/printToolResultFrame.js +2 -10
- package/dist/promptDelivery.js +0 -8
- package/dist/protocolSegment.d.ts +1 -0
- package/dist/protocolSegment.js +13 -1
- package/dist/request/taskRequest.d.ts +11 -3
- package/dist/request/taskRequest.js +13 -1
- package/dist/resultFrameKeys.d.ts +4 -0
- package/dist/resultFrameKeys.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +18 -1
- package/dist/resumeRefusalCopy.js +132 -31
- package/dist/retryStatus.js +6 -4
- package/dist/rewindArchiveCapability.d.ts +2 -1
- package/dist/rewindArchiveCapability.js +28 -15
- package/dist/rewindEngineAction.d.ts +21 -0
- package/dist/rewindEngineAction.js +36 -0
- package/dist/rewindWireCaps.d.ts +2 -1
- package/dist/rewindWireCaps.js +1 -0
- package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
- package/dist/runCancelContext.js +2 -1
- package/dist/runTerminal.d.ts +0 -11
- package/dist/runTerminal.js +4 -27
- package/dist/sdkRegistryTransit.d.ts +2 -1
- package/dist/sdkRegistryTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +0 -1
- package/dist/sealedKeyCapability.js +19 -20
- package/dist/seatContract.d.ts +85 -28
- package/dist/seatContract.js +512 -148
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +11 -0
- package/dist/sessionMemoryErase.d.ts +1 -1
- package/dist/sessionMemoryErase.js +6 -1
- package/dist/sessionMemoryStatus.js +3 -2
- package/dist/sessionPolicyCapability.d.ts +0 -1
- package/dist/sessionPolicyCapability.js +14 -13
- package/dist/sessionReadRedactionCapability.d.ts +15 -0
- package/dist/sessionReadRedactionCapability.js +42 -0
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
- package/dist/sessionSyncFileHistoryCapability.js +13 -12
- package/dist/skillToolListsCapability.d.ts +0 -1
- package/dist/skillToolListsCapability.js +13 -12
- package/dist/skillsWireCaps.d.ts +4 -0
- package/dist/skillsWireCaps.js +66 -1
- package/dist/sqlEngineCapability.d.ts +0 -1
- package/dist/sqlEngineCapability.js +21 -21
- package/dist/steerPriorityCapability.d.ts +0 -1
- package/dist/steerPriorityCapability.js +18 -19
- package/dist/storePostureCapability.d.ts +1 -1
- package/dist/storePostureCapability.js +16 -16
- package/dist/streamDrainingLegs.d.ts +6 -0
- package/dist/streamDrainingLegs.js +23 -0
- package/dist/subagent/agentStateDetail.d.ts +1 -0
- package/dist/subagent/agentStateDetail.js +41 -0
- package/dist/subagent/engineCompactWire.d.ts +15 -0
- package/dist/subagent/engineCompactWire.js +82 -45
- package/dist/subagent/engineDelegatedPrompt.js +10 -6
- package/dist/subagent/engineSubagentOutput.d.ts +0 -1
- package/dist/subagent/engineSubagentOutput.js +5 -20
- package/dist/subagent/engineSubagentTail.d.ts +0 -1
- package/dist/subagent/engineSubagentTail.js +7 -32
- package/dist/subagentContentStore.js +3 -3
- package/dist/supportFloor.js +2 -5
- package/dist/taskRequestWords.d.ts +2 -4
- package/dist/taskRequestWords.js +3 -2
- package/dist/terminalStatuses.d.ts +30 -0
- package/dist/terminalStatuses.js +67 -0
- package/dist/toolResult.d.ts +5 -0
- package/dist/toolResult.js +88 -36
- package/dist/types/engineState.d.ts +2 -1
- package/dist/usageAnalytics.d.ts +146 -0
- package/dist/usageAnalytics.js +311 -0
- package/dist/userAttachmentEnvelope.d.ts +22 -1
- package/dist/userAttachmentEnvelope.js +90 -2
- package/dist/userInvokedSkillsCapability.d.ts +0 -1
- package/dist/userInvokedSkillsCapability.js +13 -12
- package/dist/webSearchBackendCapability.d.ts +0 -1
- package/dist/webSearchBackendCapability.js +20 -19
- package/dist/webSearchWireCaps.js +3 -11
- package/dist/wireErrorTriage.d.ts +11 -0
- package/dist/wireErrorTriage.js +35 -0
- package/dist/wireFailureShape.d.ts +10 -0
- package/dist/wireFailureShape.js +72 -5
- package/dist/wireRefusalCopy.d.ts +6 -1
- package/dist/wireRefusalCopy.js +23 -25
- package/dist/wiringInstructionsAttribution.d.ts +10 -0
- package/dist/wiringInstructionsAttribution.js +67 -0
- package/dist/workflowClient.js +19 -2
- package/dist/workflowsJournalCapability.d.ts +0 -1
- package/dist/workflowsJournalCapability.js +13 -12
- package/dist/writeProtectionCapability.d.ts +0 -1
- package/dist/writeProtectionCapability.js +26 -26
- package/docs/INTEGRATION-CLIENTS.md +1733 -52
- package/package.json +5 -5
- package/dist/askSurvivesStandingAnswer.d.ts +0 -13
- package/dist/askSurvivesStandingAnswer.js +0 -53
- package/dist/engineCapsGenerationGuard.d.ts +0 -4
- package/dist/engineCapsGenerationGuard.js +0 -19
- package/dist/hitl/askSurvivesPosture.d.ts +0 -20
- package/dist/hitl/askSurvivesPosture.js +0 -48
- package/dist/panelRunningHistory.d.ts +0 -22
- package/dist/panelRunningHistory.js +0 -82
- package/dist/registryConflict.d.ts +0 -3
- package/dist/registryConflict.js +0 -44
- /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { APPROVAL_BINDING_MISMATCH, CHECKPOINT_UNSUPPORTED_VERSION, RESUME_OUTCOME_INVALID } from '../engineErrorCodes.js';
|
|
2
|
+
import { readRefusalField } from '../wireFailureShape.js';
|
|
3
|
+
const BINDING_SEAT_FIELDS = new Set(['boundCallId', 'boundInputHash']);
|
|
4
|
+
const ANSWER_FIELD = 'answer';
|
|
5
|
+
const BINDING_MISMATCH_ERROR_NAME = 'ApprovalBindingMismatchError';
|
|
6
|
+
export function decisionConflictOf(err) {
|
|
7
|
+
if (typeof err !== 'object' || err === null)
|
|
8
|
+
return undefined;
|
|
9
|
+
let code;
|
|
10
|
+
let name;
|
|
11
|
+
try {
|
|
12
|
+
code = err.errorCode;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
code = undefined;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
name = err.name;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
name = undefined;
|
|
22
|
+
}
|
|
23
|
+
if (code === CHECKPOINT_UNSUPPORTED_VERSION)
|
|
24
|
+
return 'format_version';
|
|
25
|
+
const bindingFamily = code === APPROVAL_BINDING_MISMATCH || (code === undefined && name === BINDING_MISMATCH_ERROR_NAME);
|
|
26
|
+
if (!bindingFamily && code !== RESUME_OUTCOME_INVALID)
|
|
27
|
+
return undefined;
|
|
28
|
+
let field;
|
|
29
|
+
try {
|
|
30
|
+
field = readRefusalField(err);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
field = undefined;
|
|
34
|
+
}
|
|
35
|
+
if (code === RESUME_OUTCOME_INVALID)
|
|
36
|
+
return field === ANSWER_FIELD ? 'answer_invalid' : undefined;
|
|
37
|
+
if (field === ANSWER_FIELD)
|
|
38
|
+
return 'answer_invalid';
|
|
39
|
+
if (field === undefined)
|
|
40
|
+
return 'row_integrity';
|
|
41
|
+
return BINDING_SEAT_FIELDS.has(field) ? 'binding_mismatch' : undefined;
|
|
42
|
+
}
|
|
43
|
+
export const DECISION_ANSWER_INVALID_CONTENT = 'The engine rejected the answer itself because it does not fit the question that was asked · Nothing was decided and the question is still waiting · Correct the answer and send it again';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DecisionRefusalConflict } from './decisionConflict.js';
|
|
2
|
+
export type DecisionRefusalStanding = 'settled-elsewhere' | 'ambiguous' | 'refused-pending';
|
|
3
|
+
export type { DecisionRefusalConflict } from './decisionConflict.js';
|
|
4
|
+
export declare function decisionRefusalSaysAskGone(err: unknown): boolean;
|
|
5
|
+
export interface DecisionRefusalClassified {
|
|
6
|
+
readonly standing: DecisionRefusalStanding;
|
|
7
|
+
readonly status: number;
|
|
8
|
+
readonly errorCode?: string;
|
|
9
|
+
readonly transient?: true;
|
|
10
|
+
readonly conflict?: DecisionRefusalConflict;
|
|
11
|
+
}
|
|
12
|
+
export declare function classifyDecisionRefusal(err: unknown): DecisionRefusalClassified | undefined;
|
|
13
|
+
export type LiveAskPendingReading = 'pending' | 'not_pending' | 'unknown';
|
|
14
|
+
export declare function liveAskPendingReading(envelope: unknown, approvalId: string): LiveAskPendingReading;
|
|
15
|
+
export declare function decisionRefusalClosesOut(refusal: DecisionRefusalClassified | undefined, pending: LiveAskPendingReading): boolean;
|
|
16
|
+
export type UndeliverableDecisionEnd = 'run-stopped' | 'run-unconfirmed' | 'turn-stopped';
|
|
17
|
+
export interface UndeliverableDecisionFacts {
|
|
18
|
+
readonly status: number;
|
|
19
|
+
readonly errorCode?: string;
|
|
20
|
+
readonly end: UndeliverableDecisionEnd;
|
|
21
|
+
readonly runId?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function undeliverableDecisionContent(facts: UndeliverableDecisionFacts): string;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
2
|
+
import { notPendingCauseSaysEnded } from './approvalEndingCause.js';
|
|
3
|
+
import { decisionConflictOf } from './decisionConflict.js';
|
|
4
|
+
import { readLivePendingRows } from './livePendingAsk.js';
|
|
5
|
+
import { readToolApprovalRespondRefusal } from './toolApprovalWire.js';
|
|
6
|
+
const ASK_DECIDED_CODE = 'conflict.ask_decided';
|
|
7
|
+
const TRANSIENT_STATUSES = new Set([408, 425, 429, 502, 503, 504]);
|
|
8
|
+
const DISPLAYABLE_CODE = /^[A-Za-z0-9._:-]{1,64}$/;
|
|
9
|
+
export function decisionRefusalSaysAskGone(err) {
|
|
10
|
+
try {
|
|
11
|
+
if (typeof err === 'object' && err !== null && 'code' in err) {
|
|
12
|
+
const code = err.code;
|
|
13
|
+
if (code === 'no_pending')
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
const c = classifyDecisionRefusal(err);
|
|
17
|
+
if (c?.standing !== 'settled-elsewhere')
|
|
18
|
+
return false;
|
|
19
|
+
return c.status !== 404 || (typeof err === 'object' && err !== null && notPendingCauseSaysEnded(err));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function classifyDecisionRefusal(err) {
|
|
26
|
+
const r = readToolApprovalRespondRefusal(err);
|
|
27
|
+
const status = r?.status;
|
|
28
|
+
if (status === undefined || !Number.isInteger(status) || status < 400 || status > 599)
|
|
29
|
+
return undefined;
|
|
30
|
+
const code = r?.errorCode;
|
|
31
|
+
const errorCode = code !== undefined && DISPLAYABLE_CODE.test(code) ? code : undefined;
|
|
32
|
+
const standing = status === 404 || status === 410 || (status === 409 && code === ASK_DECIDED_CODE)
|
|
33
|
+
? 'settled-elsewhere'
|
|
34
|
+
: status >= 500 && status !== 501
|
|
35
|
+
? 'ambiguous'
|
|
36
|
+
: 'refused-pending';
|
|
37
|
+
const transient = TRANSIENT_STATUSES.has(status) || (typeof err === 'object' && err !== null && refusalSaysStillPending(err));
|
|
38
|
+
const conflict = status === 409 ? decisionConflictOf(err) : undefined;
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
standing,
|
|
41
|
+
status,
|
|
42
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
43
|
+
...(transient ? { transient: true } : {}),
|
|
44
|
+
...(conflict !== undefined ? { conflict } : {}),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function liveAskPendingReading(envelope, approvalId) {
|
|
48
|
+
if (typeof approvalId !== 'string' || approvalId === '')
|
|
49
|
+
return 'unknown';
|
|
50
|
+
try {
|
|
51
|
+
const reading = readLivePendingRows(envelope);
|
|
52
|
+
if (reading.kind !== 'present')
|
|
53
|
+
return 'unknown';
|
|
54
|
+
if (reading.rows.some((row) => row.approvalId === approvalId))
|
|
55
|
+
return 'pending';
|
|
56
|
+
return reading.dropped === 0 ? 'not_pending' : 'unknown';
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return 'unknown';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function decisionRefusalClosesOut(refusal, pending) {
|
|
63
|
+
if (pending !== 'pending' || typeof refusal !== 'object' || refusal === null)
|
|
64
|
+
return false;
|
|
65
|
+
try {
|
|
66
|
+
const standing = refusal.standing;
|
|
67
|
+
if (refusal.transient === true)
|
|
68
|
+
return false;
|
|
69
|
+
return standing === 'ambiguous' || standing === 'refused-pending';
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function undeliverableDecisionContent(facts) {
|
|
76
|
+
const code = typeof facts.errorCode === 'string' && DISPLAYABLE_CODE.test(facts.errorCode) ? ` ${facts.errorCode}` : '';
|
|
77
|
+
const head = `The engine refused the approval decision this client sent (HTTP ${String(facts.status)}${code}), so the call it asked about could not be answered from here and did not run`;
|
|
78
|
+
const runId = typeof facts.runId === 'string' && DISPLAYABLE_CODE.test(facts.runId) ? ` ${facts.runId}` : '';
|
|
79
|
+
switch (facts.end) {
|
|
80
|
+
case 'run-stopped':
|
|
81
|
+
return `${head}; the run was stopped instead of being left waiting for the approval window to close. Update the client, or run the task in an interactive session and answer the approval there.`;
|
|
82
|
+
case 'run-unconfirmed':
|
|
83
|
+
return `${head}; this client stopped waiting, but the engine did not confirm that it stopped the run${runId}, so that approval may stay open until its window closes. Update the client, or run the task in an interactive session and answer the approval there.`;
|
|
84
|
+
case 'turn-stopped':
|
|
85
|
+
default:
|
|
86
|
+
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.`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -2,9 +2,19 @@ import type { AgentEvent } from '@sema-agent/sdk';
|
|
|
2
2
|
import type { DecideOperationObserver, HitlClientLike } from './hitlBridge.js';
|
|
3
3
|
import { type RespondToolApprovalFn, type ToolApprovalFrame, type ToolApprovalFrameLaneOpts, type ToolApprovalFrameOutcome } from './toolApprovalWire.js';
|
|
4
4
|
import type { GateLedger } from './gateLedger.js';
|
|
5
|
+
import type { NoAllowCause } from './noAllowCause.js';
|
|
5
6
|
import { type ReplayedApprovalDisposition } from './replayedApproval.js';
|
|
6
7
|
export declare const HITL_REJECT_MESSAGE = "The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.";
|
|
7
8
|
export declare const HITL_POLICY_DENY_MESSAGE: string;
|
|
9
|
+
export type PolicyDenyLane = 'no_approval_ui' | 'dont_ask';
|
|
10
|
+
export interface PolicyDenyReasonFacts {
|
|
11
|
+
readonly lane: PolicyDenyLane;
|
|
12
|
+
readonly toolName: string;
|
|
13
|
+
readonly cause?: NoAllowCause;
|
|
14
|
+
readonly allowRuleFlag?: string;
|
|
15
|
+
readonly budgetSetting?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function policyDenyReason(facts: PolicyDenyReasonFacts): string;
|
|
8
18
|
export declare const HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE = "[Request interrupted by user for tool use]";
|
|
9
19
|
export declare const ENGINE_ABORT_TOOL_RESULT = "Operation aborted";
|
|
10
20
|
export declare function toolEndOutputText(output: unknown): string | undefined;
|
package/dist/hitl/frameRouter.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { hostLog } from '../host.js';
|
|
2
|
+
import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
|
|
2
3
|
import { isToolApprovalGate, toolNameIsFsWrite, toolNameIsShellExec, isToolApprovalFrame, isFromSubagent, surfaceToolApprovalFrameAndRespond, } from './toolApprovalWire.js';
|
|
3
4
|
import { classifierDenyFromToolEnd } from '../classifierVerdictWire.js';
|
|
4
5
|
import { GATE_PARKED_ERROR_CODE } from '../engineErrorCodes.js';
|
|
5
6
|
import { readRunTerminal, runTerminalCode, runTerminalGateKind, runTerminalGateToolName } from '../runTerminal.js';
|
|
6
7
|
import { surfaceForCurrentSession, surfaceReplayedApprovalListUnreadable } from './hitlHostSurface.js';
|
|
8
|
+
import { liveCardAnsweredHow, liveCardHoldOf, supersedeLiveCard } from './approvalHolds.js';
|
|
9
|
+
import { approvalCompleteParked } from './approvalCompleteParked.js';
|
|
10
|
+
import { liveFrameCallKey } from './gateIdentity.js';
|
|
7
11
|
import { SEMA_DENIAL_KIND_KEY, hasLedgerPositionKey } from './gateLedger.js';
|
|
8
|
-
import { replayedApprovalDisposition } from './replayedApproval.js';
|
|
12
|
+
import { replayedApprovalDisposition, settledApprovalDisposition } from './replayedApproval.js';
|
|
9
13
|
import { settleWithinDeadline } from '../abortableSleep.js';
|
|
10
14
|
import { ccToolDenialKindForSettledBy } from '../gateVocabulary.js';
|
|
11
15
|
import { REJECT_MESSAGE } from '../adapt/wireShapes.js';
|
|
@@ -14,6 +18,38 @@ export const HITL_REJECT_MESSAGE = REJECT_MESSAGE;
|
|
|
14
18
|
export const HITL_POLICY_DENY_MESSAGE = 'Permission for this tool use was denied: it requires interactive approval, and permission prompts are ' +
|
|
15
19
|
'not available in this session. The action was NOT performed. Do not claim it succeeded, and do not retry ' +
|
|
16
20
|
'it in this session \u2014 report the limitation to the user, or suggest an alternative.';
|
|
21
|
+
const SENTENCE_TOOL_NAME = /^[A-Za-z0-9_][A-Za-z0-9_.:@-]{0,199}$/;
|
|
22
|
+
export function policyDenyReason(facts) {
|
|
23
|
+
const one = typeof facts.toolName === 'string' && SENTENCE_TOOL_NAME.test(facts.toolName) ? `this one "${facts.toolName}" call` : 'this one call';
|
|
24
|
+
const flag = typeof facts.allowRuleFlag === 'string' && SENTENCE_TOOL_NAME.test(facts.allowRuleFlag.replace(/^--?/, '')) ? ` (or ${facts.allowRuleFlag})` : '';
|
|
25
|
+
const budgetKnob = typeof facts.budgetSetting === 'string' && SENTENCE_TOOL_NAME.test(facts.budgetSetting) ? facts.budgetSetting : undefined;
|
|
26
|
+
const cause = facts.cause === 'no_allow_rule' || facts.cause === 'ask_rule' || facts.cause === 'budget' ? facts.cause : 'other';
|
|
27
|
+
if (facts.lane === 'dont_ask') {
|
|
28
|
+
const mode = 'denied by the dontAsk permission mode';
|
|
29
|
+
switch (cause) {
|
|
30
|
+
case 'no_allow_rule':
|
|
31
|
+
return `${mode}: ${one} needed approval, no permission rule allowed it, and this mode refuses anything that would ask — calls that need no approval still run; an allow rule in settings${flag} can approve calls like this ahead of time`;
|
|
32
|
+
case 'ask_rule':
|
|
33
|
+
return `${mode}: an ask rule matched ${one}, and this mode refuses anything that would ask (an ask rule outranks allow rules) — narrow or remove that ask rule, or use another permission mode to answer it`;
|
|
34
|
+
case 'budget':
|
|
35
|
+
return `${mode}: ${one} needed approval, and this session's automatic-approval budget is used up, so saved rules no longer approve calls${budgetKnob !== undefined ? ` — raise ${budgetKnob} before launch to change the cap` : ''}`;
|
|
36
|
+
default:
|
|
37
|
+
return `${mode}: ${one} needed a person's approval that saved permission rules cannot approve here (the engine or your deployment requires a person for it, or it could not be checked against your rules), and this mode refuses anything that would ask — use another permission mode to answer it`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const lane = 'no approval UI on this lane';
|
|
41
|
+
const tail = 'nobody can be asked here, so only this call was refused — calls that need no approval still run';
|
|
42
|
+
switch (cause) {
|
|
43
|
+
case 'no_allow_rule':
|
|
44
|
+
return `${lane}: ${one} needed a person's approval, no permission rule answered it, and ${tail}; a matching allow rule in settings${flag} can approve calls like this ahead of time`;
|
|
45
|
+
case 'ask_rule':
|
|
46
|
+
return `${lane}: an ask rule matched ${one}, so it needed a person's answer, and ${tail}; an ask rule outranks allow rules, so narrow or remove that ask rule, or run the task interactively to answer it`;
|
|
47
|
+
case 'budget':
|
|
48
|
+
return `${lane}: ${one} needed a person's approval, and this session's automatic-approval budget is used up, so saved rules no longer approve calls; ${tail}${budgetKnob !== undefined ? `; raise ${budgetKnob} before launch to change the cap` : ''}`;
|
|
49
|
+
default:
|
|
50
|
+
return `${lane}: ${one} needed a person's approval, and saved permission rules cannot approve it here (the engine or your deployment requires a person for it, or it could not be checked against your rules); ${tail}; run the task interactively to answer it`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
17
53
|
function denyOutputForRender(attribution) {
|
|
18
54
|
if (attribution?.settledBy !== 'policy')
|
|
19
55
|
return HITL_REJECT_MESSAGE;
|
|
@@ -234,32 +270,32 @@ const TOOL_END_ARMS = [
|
|
|
234
270
|
}
|
|
235
271
|
async function routeToolApprovalFrame(ev, ctx) {
|
|
236
272
|
const { led, deps } = ctx;
|
|
237
|
-
if (ev.type === 'tool_approval_complete')
|
|
273
|
+
if (ev.type === 'tool_approval_complete') {
|
|
274
|
+
const id = ev.approvalId;
|
|
275
|
+
if (typeof id === 'string' && id !== '' && supersedeLiveCard(liveFrameCallKey(id), approvalCompleteParked(ev))) {
|
|
276
|
+
hostLog('debug', `liveHitlAskWire: tool_approval_complete for ${id} arrived while its card was waiting — card withdrawn (nothing will be sent from it)`);
|
|
277
|
+
}
|
|
278
|
+
if (typeof id === 'string' && id !== '')
|
|
279
|
+
led.noteApprovalSettled(id, 'closed_by_engine');
|
|
238
280
|
return { kind: 'skip' };
|
|
281
|
+
}
|
|
239
282
|
if (!deps.respondToolApproval) {
|
|
240
283
|
hostLog('debug', `liveHitlAskWire: tool_approval frame ${ev.approvalId} but no respond wire — engine self-settles (TTL deny)`);
|
|
241
284
|
return { kind: 'skip' };
|
|
242
285
|
}
|
|
243
|
-
|
|
244
|
-
|
|
286
|
+
const settledHere = settledApprovalDisposition(ev, led.settledApprovals());
|
|
287
|
+
if (settledHere !== undefined || (hasLedgerPositionKey(ev) && !led.preambleApprovals().has(ev.approvalId))) {
|
|
288
|
+
const disposition = settledHere ?? (await judgeLedgerApprovalFrame(ev, ctx));
|
|
245
289
|
if (disposition.kind !== 'live') {
|
|
246
|
-
hostLog('debug',
|
|
247
|
-
|
|
248
|
-
|
|
290
|
+
hostLog('debug', disposition.kind === 'decided' && disposition.settled !== undefined
|
|
291
|
+
? `liveHitlAskWire: tool_approval frame ${ev.approvalId} repeats a question already settled on this bridge (${disposition.settled}) — not raised again, no decision sent`
|
|
292
|
+
: `liveHitlAskWire: tool_approval frame ${ev.approvalId} read back from the run event log is ${disposition.kind}` +
|
|
293
|
+
`${disposition.kind === 'unknown' ? ` (${disposition.why})` : disposition.cause !== undefined ? ` (${disposition.cause})` : ''}` +
|
|
294
|
+
' — not raised as a question, no decision sent');
|
|
249
295
|
if (disposition.kind === 'unknown' && ctx.signal?.aborted !== true)
|
|
250
296
|
surfaceReplayedApprovalListUnreadable();
|
|
251
297
|
if (deps.onReplayedApproval !== undefined) {
|
|
252
|
-
|
|
253
|
-
const out = deps.onReplayedApproval(ev, disposition);
|
|
254
|
-
if (out && typeof out.then === 'function') {
|
|
255
|
-
void Promise.resolve(out).catch((e) => {
|
|
256
|
-
hostLog('debug', `liveHitlAskWire: onReplayedApproval rejected: ${String(e).slice(0, 160)}`);
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch (e) {
|
|
261
|
-
hostLog('debug', `liveHitlAskWire: onReplayedApproval threw: ${String(e).slice(0, 160)}`);
|
|
262
|
-
}
|
|
298
|
+
invokeHostCallbackIsolated('liveHitlAskWire: onReplayedApproval', () => deps.onReplayedApproval?.(ev, disposition));
|
|
263
299
|
}
|
|
264
300
|
return { kind: 'skip' };
|
|
265
301
|
}
|
|
@@ -269,20 +305,24 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
269
305
|
const frameCallId = !fromSubagent && typeof ev.toolCallId === 'string' && ev.toolCallId !== '' ? ev.toolCallId : undefined;
|
|
270
306
|
const gatedCallId = fromSubagent ? undefined : frameCallId ?? led.lastPendingFsCall();
|
|
271
307
|
const argsCallId = frameCallId === undefined ? gatedCallId : typeof ev.toolName === 'string' && toolNameIsFsWrite(ev.toolName) ? frameCallId : undefined;
|
|
272
|
-
const
|
|
308
|
+
const runTaskId = ctx.taskId.current;
|
|
309
|
+
const approvalIdAtLaunch = ev.approvalId;
|
|
310
|
+
const launched = surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, argsCallId), ctx.signal, deps.approvalLane, typeof runTaskId === 'string' && runTaskId !== '' ? { taskId: runTaskId } : undefined);
|
|
311
|
+
const hold = liveCardHoldOf(liveFrameCallKey(ev.approvalId));
|
|
312
|
+
const handled = launched.then((outcome) => settleLiveCardOutcome(ev, approvalIdAtLaunch, outcome, ctx, fromSubagent, gatedCallId), (e) => {
|
|
313
|
+
hostLog('debug', `liveHitlAskWire: tool_approval card for ${ev.approvalId} failed: ${String(e).slice(0, 160)}`);
|
|
314
|
+
});
|
|
315
|
+
led.trackLiveCard(() => hold?.phase ?? 'card', handled);
|
|
316
|
+
return { kind: 'skip' };
|
|
317
|
+
}
|
|
318
|
+
function settleLiveCardOutcome(ev, approvalId, outcome, ctx, fromSubagent, gatedCallId) {
|
|
319
|
+
const { led, deps } = ctx;
|
|
273
320
|
const { decision } = outcome;
|
|
321
|
+
const settledHow = liveCardAnsweredHow(outcome);
|
|
322
|
+
if (settledHow !== undefined)
|
|
323
|
+
led.noteApprovalSettled(approvalId, settledHow);
|
|
274
324
|
if (deps.onToolApprovalOutcome !== undefined) {
|
|
275
|
-
|
|
276
|
-
const out = deps.onToolApprovalOutcome(ev, outcome);
|
|
277
|
-
if (out && typeof out.then === 'function') {
|
|
278
|
-
void Promise.resolve(out).catch((e) => {
|
|
279
|
-
hostLog('debug', `liveHitlAskWire: onToolApprovalOutcome rejected: ${String(e).slice(0, 160)}`);
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
catch (e) {
|
|
284
|
-
hostLog('debug', `liveHitlAskWire: onToolApprovalOutcome threw: ${String(e).slice(0, 160)}`);
|
|
285
|
-
}
|
|
325
|
+
invokeHostCallbackIsolated('liveHitlAskWire: onToolApprovalOutcome', () => deps.onToolApprovalOutcome?.(ev, outcome));
|
|
286
326
|
}
|
|
287
327
|
if (decision === 'deny' && !fromSubagent) {
|
|
288
328
|
const attribution = {
|
|
@@ -294,7 +334,6 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
294
334
|
else
|
|
295
335
|
led.armDenyStamp(attribution);
|
|
296
336
|
}
|
|
297
|
-
return { kind: 'skip' };
|
|
298
337
|
}
|
|
299
338
|
const REPLAYED_APPROVAL_LIST_DEADLINE_MS = 3000;
|
|
300
339
|
async function judgeLedgerApprovalFrame(ev, ctx) {
|
|
@@ -318,7 +357,7 @@ async function judgeLedgerApprovalFrame(ev, ctx) {
|
|
|
318
357
|
.finally(release);
|
|
319
358
|
});
|
|
320
359
|
const approvals = got.kind === 'value' ? { read: 'ok', body: got.value } : { read: 'failed' };
|
|
321
|
-
return replayedApprovalDisposition(ev, { preamble: ctx.led.preambleApprovals(), approvals });
|
|
360
|
+
return replayedApprovalDisposition(ev, { preamble: ctx.led.preambleApprovals(), approvals, settled: ctx.led.settledApprovals() });
|
|
322
361
|
}
|
|
323
362
|
function routeToolStart(ev, callId, led) {
|
|
324
363
|
led.noteStart(callId, ev);
|
|
@@ -16,6 +16,9 @@ export interface AskAnsweredOutput {
|
|
|
16
16
|
export declare function durableSeqOf(ev: object): string | undefined;
|
|
17
17
|
export declare function hasLedgerPositionKey(ev: object): boolean;
|
|
18
18
|
export declare const PREAMBLE_APPROVALS_MAX_ENTRIES = 4096;
|
|
19
|
+
export declare const APPROVAL_SETTLED_HOWS: readonly ["answered", "interrupted", "closed_by_engine"];
|
|
20
|
+
export type ApprovalSettledHow = (typeof APPROVAL_SETTLED_HOWS)[number];
|
|
21
|
+
export declare const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
19
22
|
export interface GateLedger {
|
|
20
23
|
noteSeq(ev: AgentEvent): void;
|
|
21
24
|
lastSeq(): string | undefined;
|
|
@@ -23,6 +26,11 @@ export interface GateLedger {
|
|
|
23
26
|
notePreambleApproval(approvalId: string): void;
|
|
24
27
|
preambleApprovals(): ReadonlySet<string>;
|
|
25
28
|
beginStreamSegment(): void;
|
|
29
|
+
noteApprovalSettled(approvalId: string, how: ApprovalSettledHow): void;
|
|
30
|
+
settledApprovals(): ReadonlyMap<string, ApprovalSettledHow>;
|
|
31
|
+
trackLiveCard(phaseOf: () => 'card' | 'respond', handled: Promise<void>): void;
|
|
32
|
+
answeringLiveCards(): Promise<void>[];
|
|
33
|
+
liveCardsSettled(): Promise<void>;
|
|
26
34
|
markStarted(callId: string): boolean;
|
|
27
35
|
noteGatedStart(callId: string, ev: AgentEvent): void;
|
|
28
36
|
gatedStartArgs(): ReadonlyMap<string, unknown>;
|
package/dist/hitl/gateLedger.js
CHANGED
|
@@ -13,6 +13,8 @@ export function hasLedgerPositionKey(ev) {
|
|
|
13
13
|
return (id !== undefined && id !== null) || (seq !== undefined && seq !== null);
|
|
14
14
|
}
|
|
15
15
|
export const PREAMBLE_APPROVALS_MAX_ENTRIES = 4096;
|
|
16
|
+
export const APPROVAL_SETTLED_HOWS = Object.freeze(['answered', 'interrupted', 'closed_by_engine']);
|
|
17
|
+
export const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
16
18
|
export const START_ARGS_MAX_ENTRIES = 256;
|
|
17
19
|
function normalizeDenyAttribution(a) {
|
|
18
20
|
if (a === undefined)
|
|
@@ -88,6 +90,8 @@ export function createGateLedger() {
|
|
|
88
90
|
let denyStampAttribution;
|
|
89
91
|
let seq;
|
|
90
92
|
const preambleApprovalIds = new Set();
|
|
93
|
+
const settledApprovalHows = new Map();
|
|
94
|
+
const liveCards = new Set();
|
|
91
95
|
return {
|
|
92
96
|
noteSeq(ev) {
|
|
93
97
|
const s = durableSeqOf(ev);
|
|
@@ -120,6 +124,40 @@ export function createGateLedger() {
|
|
|
120
124
|
beginStreamSegment() {
|
|
121
125
|
preambleApprovalIds.clear();
|
|
122
126
|
},
|
|
127
|
+
noteApprovalSettled(approvalId, how) {
|
|
128
|
+
if (typeof approvalId !== 'string' || approvalId === '')
|
|
129
|
+
return;
|
|
130
|
+
if (!APPROVAL_SETTLED_HOWS.includes(how))
|
|
131
|
+
return;
|
|
132
|
+
if (settledApprovalHows.has(approvalId))
|
|
133
|
+
return;
|
|
134
|
+
settledApprovalHows.set(approvalId, how);
|
|
135
|
+
while (settledApprovalHows.size > SETTLED_APPROVALS_MAX_ENTRIES) {
|
|
136
|
+
const oldest = settledApprovalHows.keys().next();
|
|
137
|
+
if (oldest.done === true)
|
|
138
|
+
break;
|
|
139
|
+
settledApprovalHows.delete(oldest.value);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
settledApprovals() {
|
|
143
|
+
return settledApprovalHows;
|
|
144
|
+
},
|
|
145
|
+
trackLiveCard(phaseOf, handled) {
|
|
146
|
+
const entry = { phaseOf, handled };
|
|
147
|
+
liveCards.add(entry);
|
|
148
|
+
void handled.then(() => { liveCards.delete(entry); }, () => { liveCards.delete(entry); });
|
|
149
|
+
},
|
|
150
|
+
answeringLiveCards() {
|
|
151
|
+
const out = [];
|
|
152
|
+
for (const e of liveCards)
|
|
153
|
+
if (e.phaseOf() === 'respond')
|
|
154
|
+
out.push(e.handled);
|
|
155
|
+
return out;
|
|
156
|
+
},
|
|
157
|
+
async liveCardsSettled() {
|
|
158
|
+
while (liveCards.size > 0)
|
|
159
|
+
await Promise.allSettled([...liveCards].map((e) => e.handled));
|
|
160
|
+
},
|
|
123
161
|
markStarted(callId) {
|
|
124
162
|
if (startedCalls.has(callId))
|
|
125
163
|
return false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentEvent, ApprovalDecision, ApprovalStaleError, PendingCheckpoint, CheckpointGate, PlanReviewRequest, AssistantTaskStatus } from '@sema-agent/sdk';
|
|
1
|
+
import type { AgentEvent, ApprovalDecidedBy, ApprovalDecision, ApprovalStaleError, PendingCheckpoint, CheckpointGate, PlanReviewRequest, AssistantTaskStatus } from '@sema-agent/sdk';
|
|
2
2
|
import type { PermissionResult } from '@sema-agent/agent-types';
|
|
3
3
|
import type { ApprovalsListEnvelope } from './crashConverged.js';
|
|
4
4
|
import { type SuspendedReopenReading } from './suspendedReopen.js';
|
|
@@ -46,7 +46,8 @@ export interface PlanReviewOutcome {
|
|
|
46
46
|
export declare const PLAN_REVIEW_MODE_AFTER_WORDS: readonly ["default", "acceptEdits"];
|
|
47
47
|
export type PlanReviewModeAfter = (typeof PLAN_REVIEW_MODE_AFTER_WORDS)[number];
|
|
48
48
|
export declare function isPlanReviewModeAfter(v: string | undefined): v is PlanReviewModeAfter;
|
|
49
|
-
export
|
|
49
|
+
export declare const GATE_FAILURE_CODES: readonly ["no_pending", "binding_mismatch", "wrong_gate", "bad_plan_edit", "bad_plan_mode", "empty_answer"];
|
|
50
|
+
export type HitlSafetyCode = (typeof GATE_FAILURE_CODES)[number];
|
|
50
51
|
export type HitlFailureStage = 'fetch' | 'input' | 'card' | 'decide' | 'orchestration';
|
|
51
52
|
export declare const NO_APPROVAL_CARD_PORT_REASON = "no approval card port installed (print/non-REPL mode, or host forgot installApprovalCardPort)";
|
|
52
53
|
export declare const APPROVAL_CARD_PORT_KEY_MISMATCH_REASON = "no approval card port installed for the default session key, but a non-default sessionKey has one \u2014 likely a keyed-install/default-read mismatch (installApprovalCardPortFor vs the zero-arg default-key read), not a missing install";
|
|
@@ -56,15 +57,25 @@ export interface HitlDecideDenyOutcome {
|
|
|
56
57
|
decision: 'deny';
|
|
57
58
|
reason?: string | undefined;
|
|
58
59
|
settledBy?: 'policy' | undefined;
|
|
59
|
-
decidedBy?: 'policy' | undefined;
|
|
60
|
+
decidedBy?: Extract<ApprovalDecidedBy, 'policy'> | undefined;
|
|
60
61
|
}
|
|
61
62
|
export declare class HitlSafetyError extends Error {
|
|
62
63
|
readonly code: HitlSafetyCode;
|
|
63
64
|
constructor(message: string, code: HitlSafetyCode);
|
|
64
65
|
}
|
|
66
|
+
export declare function hitlSafetyCodeOf(e: unknown): HitlSafetyCode | undefined;
|
|
65
67
|
export type GateCurrentPending = Readonly<NonNullable<ApprovalStaleError['currentPending']>>;
|
|
66
68
|
export declare function readDecideCurrentPending(e: unknown): GateCurrentPending | undefined;
|
|
67
69
|
export declare function readWireErrorCode(e: unknown): string | undefined;
|
|
70
|
+
export type WireErrorCodeReading = {
|
|
71
|
+
readonly state: 'code';
|
|
72
|
+
readonly code: string;
|
|
73
|
+
} | {
|
|
74
|
+
readonly state: 'absent';
|
|
75
|
+
} | {
|
|
76
|
+
readonly state: 'unreadable';
|
|
77
|
+
};
|
|
78
|
+
export declare function readWireErrorCodeReading(e: unknown): WireErrorCodeReading;
|
|
68
79
|
export declare function __setDecideTimeoutRetryBudgetForTests(ms?: number): void;
|
|
69
80
|
export declare class DecideTransportRetryExhaustedError extends Error {
|
|
70
81
|
readonly attempts: number;
|