@sema-agent/client-core 0.95.0 → 0.97.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 +269 -0
- package/README.md +61 -31
- package/dist/adapt/arms.js +7 -1
- package/dist/adapt/toolCards.d.ts +1 -0
- package/dist/adapt/toolCards.js +16 -3
- package/dist/adapt/wireShapes.js +2 -16
- package/dist/adapter/activeRunSelfHeal.d.ts +4 -2
- package/dist/adapter/activeRunSelfHeal.js +32 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
- package/dist/adapter/downstream/terminalToSdkResult.js +14 -11
- package/dist/adapter/runStream.js +30 -47
- package/dist/agentSession/backgroundView.js +2 -15
- package/dist/agentSession/engineAgentRegistryRead.js +5 -4
- package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
- package/dist/agentsWireCaps.d.ts +1 -1
- package/dist/agentsWireCaps.js +29 -12
- package/dist/approvalDecidedByCapability.d.ts +2 -0
- package/dist/approvalDecidedByCapability.js +0 -1
- package/dist/approvalsStreamLiveCapability.d.ts +2 -0
- package/dist/approvalsStreamLiveCapability.js +3 -2
- package/dist/attachmentSeatCapability.d.ts +2 -0
- package/dist/attachmentSeatCapability.js +0 -1
- package/dist/callerCwdCapability.d.ts +2 -4
- package/dist/callerCwdCapability.js +0 -7
- package/dist/centerWiringCapability.d.ts +2 -4
- package/dist/centerWiringCapability.js +4 -9
- package/dist/classifierVerdictWire.js +4 -16
- package/dist/clientSlice.js +1 -1
- package/dist/cloudConfigWireCaps.d.ts +4 -4
- package/dist/cloudConfigWireCaps.js +241 -85
- package/dist/coreValuePorts.d.ts +11 -7
- package/dist/coreValuePorts.js +5 -8
- package/dist/credentialProvenance.d.ts +28 -0
- package/dist/credentialProvenance.js +76 -0
- package/dist/decideFailureNote.js +3 -1
- package/dist/decideReceipt.js +7 -10
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/deviceExecutorManagementCapability.d.ts +2 -0
- package/dist/deviceExecutorManagementCapability.js +3 -2
- package/dist/displayUntrusted.d.ts +10 -3
- package/dist/displayUntrusted.js +371 -60
- package/dist/engineCapReader.d.ts +8 -2
- package/dist/engineCapReader.js +15 -7
- package/dist/engineCapsCache.d.ts +17 -3
- package/dist/engineCapsCache.js +268 -43
- package/dist/engineDirectory.d.ts +79 -0
- package/dist/engineDirectory.js +186 -0
- package/dist/engineErrorCodes.d.ts +17 -1
- package/dist/engineErrorCodes.js +46 -16
- package/dist/engineNoticeCodes.d.ts +17 -0
- package/dist/engineNoticeCodes.js +54 -1
- package/dist/executionLaneCapability.d.ts +2 -0
- package/dist/executionLaneCapability.js +3 -2
- package/dist/fileHistoryCaptureCapability.d.ts +16 -0
- package/dist/fileHistoryCaptureCapability.js +98 -2
- package/dist/fileHistoryLegNotice.js +4 -0
- package/dist/fleet/bgSubagentRow.d.ts +15 -0
- package/dist/fleet/bgSubagentRow.js +67 -0
- package/dist/fleet/fleetLedger.d.ts +1 -0
- package/dist/fleet/fleetLedger.js +164 -126
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +10 -3
- package/dist/fleetTaskDesc.js +4 -17
- package/dist/gateOutcome.d.ts +12 -1
- package/dist/gateOutcome.js +56 -1
- package/dist/gateVocabulary.d.ts +2 -2
- package/dist/gateVocabulary.js +4 -3
- package/dist/generated/engineAskFaceTables.js +1 -1
- package/dist/generated/engineFactTables.d.ts +5 -3
- package/dist/generated/engineFactTables.js +17 -4
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/sdkFactTables.d.ts +2 -0
- package/dist/generated/sdkFactTables.js +7 -0
- package/dist/generated/settingsSchemaFns.d.ts +3 -0
- package/dist/generated/settingsSchemaFns.js +53 -0
- package/dist/generated/toolNameTables.d.ts +1 -1
- package/dist/generated/toolNameTables.js +1 -42
- package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
- package/dist/hitl/approvalEndingCause.d.ts +2 -0
- package/dist/hitl/approvalEndingCause.js +26 -21
- package/dist/hitl/approvalHolds.d.ts +16 -1
- package/dist/hitl/approvalHolds.js +52 -12
- package/dist/hitl/askGateWire.js +1 -0
- package/dist/hitl/askParkRowRouting.js +1 -1
- package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
- package/dist/hitl/automaticAnswerVerdict.js +13 -10
- package/dist/hitl/decisionConflict.js +4 -5
- package/dist/hitl/decisionRefusal.d.ts +8 -0
- package/dist/hitl/decisionRefusal.js +55 -14
- package/dist/hitl/frameRouter.d.ts +3 -1
- package/dist/hitl/frameRouter.js +58 -39
- package/dist/hitl/gateLedger.d.ts +0 -5
- package/dist/hitl/gateLedger.js +0 -21
- package/dist/hitl/hitlBridge.d.ts +6 -2
- package/dist/hitl/hitlBridge.js +46 -11
- package/dist/hitl/localAllowRule.d.ts +1 -0
- package/dist/hitl/localAllowRule.js +2 -2
- package/dist/hitl/noAllowCause.d.ts +2 -1
- package/dist/hitl/noAllowCause.js +3 -2
- package/dist/hitl/parkResolver.d.ts +1 -0
- package/dist/hitl/parkResolver.js +14 -56
- package/dist/hitl/parkRowBirthWait.d.ts +1 -0
- package/dist/hitl/parkRowBirthWait.js +2 -2
- package/dist/hitl/planReviewWire.d.ts +1 -0
- package/dist/hitl/planReviewWire.js +98 -20
- package/dist/hitl/replayedApproval.d.ts +3 -3
- package/dist/hitl/replayedApproval.js +21 -16
- package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
- package/dist/hitl/sessionPolicyDeliverable.js +17 -17
- package/dist/hitl/sessionPolicyWire.d.ts +2 -0
- package/dist/hitl/sessionPolicyWire.js +15 -3
- package/dist/hitl/standingRows.d.ts +19 -0
- package/dist/hitl/standingRows.js +148 -0
- package/dist/hitl/suspendedReopen.js +2 -1
- package/dist/hitl/toolApprovalWire.d.ts +22 -10
- package/dist/hitl/toolApprovalWire.js +286 -47
- package/dist/hookMatcherVerdict.d.ts +1 -9
- package/dist/hookMatcherVerdict.js +21 -61
- package/dist/hooksWireCaps.js +2 -2
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +6 -0
- package/dist/index.d.ts +26 -12
- package/dist/index.js +20 -10
- package/dist/liveModelCatalog.d.ts +13 -0
- package/dist/liveModelCatalog.js +56 -0
- package/dist/mcpProbeCapability.d.ts +2 -4
- package/dist/mcpProbeCapability.js +3 -8
- package/dist/mcpWireCaps.d.ts +1 -0
- package/dist/mcpWireCaps.js +4 -1
- package/dist/memoryComplianceCapability.d.ts +2 -4
- package/dist/memoryComplianceCapability.js +3 -8
- package/dist/memoryOriginCapability.d.ts +2 -4
- package/dist/memoryOriginCapability.js +3 -8
- package/dist/memorySpecWire.js +2 -2
- package/dist/modelIdentityResolvability.d.ts +2 -2
- package/dist/modelIdentityResolvability.js +14 -5
- package/dist/noticePresentation.d.ts +68 -0
- package/dist/noticePresentation.js +247 -0
- package/dist/outputStyleSeatCapability.d.ts +2 -1
- package/dist/outputStyleSeatCapability.js +0 -4
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +18 -0
- package/dist/peerFrames.js +13 -9
- package/dist/peerLaneCapability.d.ts +2 -0
- package/dist/peerLaneCapability.js +3 -2
- package/dist/permissionModesCapability.d.ts +2 -4
- package/dist/permissionModesCapability.js +0 -7
- package/dist/permissionRuleIssue.js +0 -3
- package/dist/permissionRulesWriteCapability.d.ts +2 -0
- package/dist/permissionRulesWriteCapability.js +3 -2
- package/dist/permissionsAllowGrantCapability.d.ts +2 -0
- package/dist/permissionsAllowGrantCapability.js +4 -2
- package/dist/permissionsDeclaration.d.ts +2 -0
- package/dist/permissionsDeclaration.js +72 -59
- package/dist/printPermissionOutcome.d.ts +12 -0
- package/dist/printPermissionOutcome.js +50 -0
- package/dist/printToolResultFrame.d.ts +1 -0
- package/dist/printToolResultFrame.js +5 -9
- package/dist/promptBlockedCopy.d.ts +5 -0
- package/dist/promptBlockedCopy.js +35 -0
- package/dist/protocolSegment.d.ts +9 -6
- package/dist/protocolSegment.js +31 -21
- package/dist/providerRejection.d.ts +4 -0
- package/dist/providerRejection.js +75 -14
- package/dist/replayBody.d.ts +12 -0
- package/dist/replayBody.js +25 -0
- package/dist/request/taskRequest.d.ts +1 -4
- package/dist/request/taskRequest.js +74 -19
- package/dist/resumeRefusalCopy.js +9 -25
- package/dist/retryStatus.d.ts +9 -1
- package/dist/retryStatus.js +9 -2
- package/dist/rewindArchiveCapability.d.ts +3 -13
- package/dist/rewindArchiveCapability.js +12 -58
- package/dist/rewindArchiveReading.d.ts +17 -0
- package/dist/rewindArchiveReading.js +55 -0
- package/dist/ruleCompileVerdict.d.ts +9 -1
- package/dist/ruleCompileVerdict.js +29 -4
- package/dist/runTerminal.d.ts +48 -5
- package/dist/runTerminal.js +215 -12
- package/dist/sandboxWire.js +13 -0
- package/dist/sdkWireTransit.d.ts +2 -1
- package/dist/sdkWireTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +2 -4
- package/dist/sealedKeyCapability.js +0 -7
- package/dist/seam.js +4 -2
- package/dist/seatContract.d.ts +76 -11
- package/dist/seatContract.js +222 -27
- package/dist/sessionPolicyCapability.d.ts +2 -0
- package/dist/sessionPolicyCapability.js +3 -2
- package/dist/sessionReadRedactionCapability.d.ts +2 -4
- package/dist/sessionReadRedactionCapability.js +0 -7
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +66 -0
- package/dist/sessionSyncFileHistoryCapability.d.ts +2 -1
- package/dist/sessionSyncFileHistoryCapability.js +3 -5
- package/dist/skillToolListsCapability.d.ts +2 -1
- package/dist/skillToolListsCapability.js +3 -5
- package/dist/sqlEngineCapability.d.ts +2 -0
- package/dist/sqlEngineCapability.js +4 -3
- package/dist/steerPriorityCapability.d.ts +2 -1
- package/dist/steerPriorityCapability.js +3 -5
- package/dist/storePostureCapability.d.ts +2 -4
- package/dist/storePostureCapability.js +4 -9
- package/dist/subagent/engineSubagentSteer.js +7 -5
- package/dist/subagentContentStore.js +4 -15
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +13 -9
- package/dist/systemReminderTag.d.ts +1 -0
- package/dist/systemReminderTag.js +8 -0
- package/dist/toolHistoryBadTurn.js +3 -2
- package/dist/toolHistoryMismatch.d.ts +0 -3
- package/dist/toolHistoryMismatch.js +3 -7
- package/dist/toolResult.d.ts +12 -1
- package/dist/toolResult.js +55 -1
- package/dist/toolResultContent.d.ts +2 -0
- package/dist/toolResultContent.js +63 -0
- package/dist/usageAnalytics.js +40 -16
- package/dist/userInvokedSkillsCapability.d.ts +2 -1
- package/dist/userInvokedSkillsCapability.js +3 -5
- package/dist/webSearchBackendCapability.d.ts +2 -0
- package/dist/webSearchBackendCapability.js +3 -2
- package/dist/wireErrorTriage.d.ts +2 -0
- package/dist/wireErrorTriage.js +91 -38
- package/dist/wireFailureShape.d.ts +20 -3
- package/dist/wireFailureShape.js +128 -72
- package/dist/workflowsJournalCapability.d.ts +2 -0
- package/dist/workflowsJournalCapability.js +3 -2
- package/dist/writeProtectionCapability.d.ts +2 -0
- package/dist/writeProtectionCapability.js +3 -2
- package/docs/INTEGRATION-CLIENTS.md +1784 -20
- package/package.json +5 -5
- package/dist/engineRefusedToolName.d.ts +0 -1
- package/dist/engineRefusedToolName.js +0 -8
|
@@ -1,31 +1,29 @@
|
|
|
1
|
-
import { APPROVAL_CARD_PORT_KEY_MISMATCH_REASON, DEFAULT_DENY_REASON, DecideTransportRetryExhaustedError, HitlBridge, NO_APPROVAL_CARD_PORT_REASON, denyReasonForWire, findPendingForTask, hitlSafetyCodeOf, readDecideCurrentPending,
|
|
1
|
+
import { APPROVAL_CARD_PORT_KEY_MISMATCH_REASON, DEFAULT_DENY_REASON, DecideTransportRetryExhaustedError, HitlBridge, NO_APPROVAL_CARD_PORT_REASON, denyReasonForWire, findPendingForTask, hitlSafetyCodeOf, readDecideCurrentPending, readWireCodes, readWireErrorCodeReading, } from './hitlBridge.js';
|
|
2
2
|
import { askParkRowArm } from './askParkRowRouting.js';
|
|
3
|
+
import { parkGateArmOf } from './frameRouter.js';
|
|
4
|
+
import { seatSessionRowOf } from './standingRows.js';
|
|
3
5
|
import { hostLog } from '../host.js';
|
|
4
|
-
import { readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
|
|
6
|
+
import { guardedRead, readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
|
|
5
7
|
import { readAskClassPair } from './askClassPair.js';
|
|
6
8
|
import { readAllowRuleShadowFromWire } from './allowRuleShadow.js';
|
|
7
9
|
import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
8
10
|
import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
|
|
11
|
+
import { CORE_SKILL_TOOL_NAME } from '../generated/toolNameTables.js';
|
|
9
12
|
import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
|
|
10
13
|
import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
|
|
11
14
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
12
|
-
import { approvalDecisionHolds, awaitLiveCardHolder, holdLiveCard, joinLiveCard, liveCardHoldFor, liveCardHoldOf } from './approvalHolds.js';
|
|
15
|
+
import { approvalDecisionHolds, awaitLiveCardHolder, holdLiveCard, joinLiveCard, liveCardHoldFor, liveCardHoldOf, clearSettledApprovals, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
|
|
13
16
|
import { approvalResolutionOf } from './approvalResolution.js';
|
|
14
17
|
import { isApprovalMandateWord } from '../gateVocabulary.js';
|
|
15
18
|
import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
|
|
16
19
|
import { approvalDecidedByAdmitted } from '../approvalDecidedByCapability.js';
|
|
17
20
|
import { decideFailureNote } from '../decideFailureNote.js';
|
|
18
|
-
import { thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
|
|
21
|
+
import { readRefusalField, thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
|
|
22
|
+
import { refusalCauseWordOf } from './approvalEndingCause.js';
|
|
23
|
+
import { readDecisionRefusalAsk } from './decisionRefusal.js';
|
|
19
24
|
import { DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
20
25
|
import { readDecideReceipt } from '../decideReceipt.js';
|
|
21
|
-
import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS, RULE_OFFERS_ABSENCE_REASONS, ASK_ORIGINS,
|
|
22
|
-
export function isFsApprovalGate(gate) {
|
|
23
|
-
if (!gate)
|
|
24
|
-
return false;
|
|
25
|
-
if (gate.kind === 'tool_approval')
|
|
26
|
-
return true;
|
|
27
|
-
return typeof gate.toolName === 'string' && toolNameIsFsWrite(gate.toolName);
|
|
28
|
-
}
|
|
26
|
+
import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS, RULE_OFFERS_ABSENCE_REASONS, ASK_ORIGINS, TOOL_APPROVAL_CARD_WORDS, } from '@sema-agent/sdk';
|
|
29
27
|
export function toolNameIsFsWrite(name) {
|
|
30
28
|
const n = name.replace(/[\s_-]+/g, '').toLowerCase();
|
|
31
29
|
return (n === 'write' || n === 'filewrite' || n === 'edit' || n === 'fileedit' || n === 'multiedit' || n === 'notebookedit');
|
|
@@ -34,9 +32,13 @@ export function toolNameIsShellExec(name) {
|
|
|
34
32
|
return name.replace(/[\s_-]+/g, '').toLowerCase() === 'bash';
|
|
35
33
|
}
|
|
36
34
|
export function isToolApprovalGate(gate) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
return parkGateArmOf(gate) === 'fs';
|
|
36
|
+
}
|
|
37
|
+
function fallbackRowMatcherFor(parkToolName) {
|
|
38
|
+
const family = (toolName) => toolName !== undefined && (toolNameIsFsWrite(toolName) || toolNameIsShellExec(toolName));
|
|
39
|
+
if (parkToolName === undefined || parkToolName === '' || family(parkToolName))
|
|
40
|
+
return family;
|
|
41
|
+
return (toolName) => toolName === parkToolName;
|
|
40
42
|
}
|
|
41
43
|
export function structurallyEqual(a, b) {
|
|
42
44
|
if (a === b)
|
|
@@ -61,7 +63,6 @@ export function structurallyEqual(a, b) {
|
|
|
61
63
|
export { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS };
|
|
62
64
|
export { RULE_OFFERS_ABSENCE_REASONS };
|
|
63
65
|
export const ASK_ORIGIN_WORDS = ASK_ORIGINS;
|
|
64
|
-
export const APPROVAL_MANDATE_WORDS = PERSISTED_RULE_MANDATES;
|
|
65
66
|
export const APPROVAL_DENY_SETTLED_BY_WORDS = Object.freeze(['human', 'policy']);
|
|
66
67
|
export function readApprovalDenySettledBy(decision) {
|
|
67
68
|
if (decision === null || typeof decision !== 'object')
|
|
@@ -111,6 +112,9 @@ export function hasApprovalCardPortFor(sessionKey) {
|
|
|
111
112
|
export function approvalCardPortFor(sessionKey) {
|
|
112
113
|
return cardPortByKey.get(sessionKey) ?? null;
|
|
113
114
|
}
|
|
115
|
+
export function __resetSettledApprovalsForTests() {
|
|
116
|
+
clearSettledApprovals();
|
|
117
|
+
}
|
|
114
118
|
export function _resetApprovalCardPortForTest() {
|
|
115
119
|
cardPortByKey.clear();
|
|
116
120
|
cardPortMissesByKey.clear();
|
|
@@ -166,6 +170,14 @@ const ARGS_OMITTED_PATH_RECOVERED_NOTE = 'tool arguments exceeded the wire cap a
|
|
|
166
170
|
const ARGS_OMITTED_NOTHING_RECOVERED_NOTE = 'tool arguments exceeded the wire cap and were omitted, and nothing could be recovered from the approval question — ' +
|
|
167
171
|
'you are deciding without seeing what this call will do; deny it if you are not sure. ' +
|
|
168
172
|
'Edits are not accepted on this card: there is no original input to edit';
|
|
173
|
+
function argsFallbackOf(message, argsOmitted) {
|
|
174
|
+
const p = pathFromGateMessage(typeof message === 'string' ? message : undefined);
|
|
175
|
+
return {
|
|
176
|
+
args: p !== undefined ? { file_path: p } : {},
|
|
177
|
+
pathRecovered: p !== undefined,
|
|
178
|
+
...(argsOmitted === true ? { omittedNote: p !== undefined ? ARGS_OMITTED_PATH_RECOVERED_NOTE : ARGS_OMITTED_NOTHING_RECOVERED_NOTE } : {}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
169
181
|
const PARK_ROW_ARGS_ABSENT_NOTE = "this request's tool arguments are not available on this surface — neither the event stream nor the pending approval record " +
|
|
170
182
|
'carries them, so you are deciding without seeing them; deny it if you are not sure what it will do. ' +
|
|
171
183
|
'Edits are not accepted on this card: there is no original input to edit';
|
|
@@ -273,13 +285,13 @@ async function joinDurableDecision(hold, deps, signal) {
|
|
|
273
285
|
}
|
|
274
286
|
return { ...o, joinedInFlight: true };
|
|
275
287
|
}
|
|
276
|
-
export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signal, parkGatedCallId) {
|
|
288
|
+
export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signal, parkGatedCallId, parkToolName) {
|
|
277
289
|
const decidedByReading = decidedByReadingSnapshotOf(deps);
|
|
278
290
|
const readMark = openDurableRead();
|
|
279
291
|
let found;
|
|
280
292
|
let held;
|
|
281
293
|
try {
|
|
282
|
-
found = await findPendingForTask(deps.client, taskId, (
|
|
294
|
+
found = await findPendingForTask(deps.client, taskId, fallbackRowMatcherFor(parkToolName), signal ? { signal } : undefined, parkGatedCallId, (row) => askParkRowArm(row) === 'tool-gate');
|
|
283
295
|
if (found.ok)
|
|
284
296
|
held = heldDurableDecision(durableHoldKey(found.pending, approvalCallKey(found.gatedCallId, taskId)), readMark);
|
|
285
297
|
}
|
|
@@ -295,7 +307,7 @@ export async function surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signa
|
|
|
295
307
|
const joined = await awaitLiveCardHolder(liveHolder, signal);
|
|
296
308
|
if (joined !== undefined)
|
|
297
309
|
return fsOutcomeOfJoinedLiveCard(joined, found.gatedCallId);
|
|
298
|
-
return surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signal, parkGatedCallId);
|
|
310
|
+
return surfaceFsApprovalAndDecide(deps, taskId, argsByCall, signal, parkGatedCallId, parkToolName);
|
|
299
311
|
}
|
|
300
312
|
const callKey = approvalCallKey(found.gatedCallId, taskId);
|
|
301
313
|
const fetched = found;
|
|
@@ -357,7 +369,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
357
369
|
const durableRuleOffersAbsence = pending.ruleOffersAbsence;
|
|
358
370
|
hold.presented = true;
|
|
359
371
|
deps.onPresented?.();
|
|
360
|
-
const card = await surfaceCallTrackedCard(gatedCallId, undefined, ledgerSlot, {
|
|
372
|
+
const card = await surfaceCallTrackedCard(gatedCallId, undefined, ledgerSlot, withUnreadableEvidence(pending, 'row', {
|
|
361
373
|
toolName,
|
|
362
374
|
args,
|
|
363
375
|
callKey,
|
|
@@ -373,6 +385,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
373
385
|
...(hasOwnStrictTrue(pending, 'mandated') ? { mandated: true } : {}),
|
|
374
386
|
...((w) => (w !== undefined ? { mandate: w } : {}))(readApprovalMandate(pending)),
|
|
375
387
|
...((o) => (o !== undefined ? { origin: o } : {}))(readAskOrigin(pending)),
|
|
388
|
+
...((w) => (w !== undefined ? { approvalCard: w } : {}))(readApprovalCardWord(pending)),
|
|
376
389
|
...(readAskClassPair(pending) ?? {}),
|
|
377
390
|
...(pending.gateKind === 'irreversible_ask' ? { irreversibleParkGate: true } : {}),
|
|
378
391
|
...(pending.hasBidiControls === true ? { hasBidiControls: true } : {}),
|
|
@@ -387,7 +400,9 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
387
400
|
...(typeof pending.toolCallId === 'string' && pending.toolCallId !== ''
|
|
388
401
|
? { toolCallId: pending.toolCallId }
|
|
389
402
|
: {}),
|
|
390
|
-
|
|
403
|
+
allowSessionCarried: true,
|
|
404
|
+
grantBinding: readApprovalGrantBinding(pending),
|
|
405
|
+
}));
|
|
391
406
|
if (rowArgsGap !== undefined && card.kind === 'allow' && card.updatedInput !== undefined) {
|
|
392
407
|
hostLog('error', `liveToolApprovalWire: approval card for ${gatedCallId ?? `task ${taskId}`} returned an edited approval, but the tool input is ${rowArgsGap === 'truncated' ? 'a size marker on the pending row' : 'missing from both the stream and the pending row'} — nothing sent (the park stays pending)`);
|
|
393
408
|
surfaceEditRefusedOnBlindAsk();
|
|
@@ -441,7 +456,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
441
456
|
}
|
|
442
457
|
catch (e) {
|
|
443
458
|
const currentPending = readDecideCurrentPending(e);
|
|
444
|
-
const
|
|
459
|
+
const wireCodes = readWireCodes(e);
|
|
445
460
|
const wireRetriable = typeof e === 'object' && e !== null && refusalSaysStillPending(e);
|
|
446
461
|
const safetyCode = hitlSafetyCodeOf(e);
|
|
447
462
|
const failureTexts = wireFailureTextsOf(e);
|
|
@@ -453,7 +468,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
453
468
|
reason: `decide(approve) failed: ${failureTexts.reason}${decideFailureNote(e, 'approve')}`,
|
|
454
469
|
...(thrownIsInstanceOf(e, DecideTransportRetryExhaustedError) ? { retryExhausted: true } : {}),
|
|
455
470
|
...(currentPending !== undefined ? { currentPending } : {}),
|
|
456
|
-
...
|
|
471
|
+
...wireCodes,
|
|
457
472
|
...(wireRetriable ? { retriable: true } : {}),
|
|
458
473
|
...(safetyCode !== undefined ? { safetyCode } : {}),
|
|
459
474
|
};
|
|
@@ -527,7 +542,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
527
542
|
}
|
|
528
543
|
catch (e) {
|
|
529
544
|
const currentPending = readDecideCurrentPending(e);
|
|
530
|
-
const
|
|
545
|
+
const wireCodes = readWireCodes(e);
|
|
531
546
|
const wireRetriable = typeof e === 'object' && e !== null && refusalSaysStillPending(e);
|
|
532
547
|
const safetyCode = hitlSafetyCodeOf(e);
|
|
533
548
|
const attributionRefusal = denyAttributionRefusalFromError(e, lastSendCarriedAttribution);
|
|
@@ -540,7 +555,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
540
555
|
reason: `decide(deny) failed: ${failureTexts.reason}${decideFailureNote(e, 'deny')}`,
|
|
541
556
|
...(thrownIsInstanceOf(e, DecideTransportRetryExhaustedError) ? { retryExhausted: true } : {}),
|
|
542
557
|
...(currentPending !== undefined ? { currentPending } : {}),
|
|
543
|
-
...
|
|
558
|
+
...wireCodes,
|
|
544
559
|
...(wireRetriable ? { retriable: true } : {}),
|
|
545
560
|
...(safetyCode !== undefined ? { safetyCode } : {}),
|
|
546
561
|
...(attributionRefusal !== null ? { denyAttributionRefusal: attributionRefusal } : {}),
|
|
@@ -584,6 +599,7 @@ export const TOOL_APPROVAL_FRAME_KEYS_MIRROR = [
|
|
|
584
599
|
'mandated',
|
|
585
600
|
'mandate',
|
|
586
601
|
'origin',
|
|
602
|
+
'approvalCard',
|
|
587
603
|
'askClass',
|
|
588
604
|
'classes',
|
|
589
605
|
'inputHasBidi',
|
|
@@ -625,7 +641,21 @@ export function readApprovalMandate(v) {
|
|
|
625
641
|
const raw = v.mandate;
|
|
626
642
|
return isApprovalMandateWord(raw) ? raw : undefined;
|
|
627
643
|
}
|
|
628
|
-
|
|
644
|
+
const APPROVAL_CARD_WORD_SET = new Set(TOOL_APPROVAL_CARD_WORDS);
|
|
645
|
+
export function readApprovalCardWord(carrier) {
|
|
646
|
+
try {
|
|
647
|
+
if (typeof carrier !== 'object' || carrier === null)
|
|
648
|
+
return undefined;
|
|
649
|
+
const d = Object.getOwnPropertyDescriptor(carrier, 'approvalCard');
|
|
650
|
+
if (d === undefined || !('value' in d))
|
|
651
|
+
return undefined;
|
|
652
|
+
return APPROVAL_CARD_WORD_SET.has(d.value) ? d.value : undefined;
|
|
653
|
+
}
|
|
654
|
+
catch {
|
|
655
|
+
return undefined;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
export function toolPermissionRequestAskBits(card, requestId) {
|
|
629
659
|
if (typeof card !== 'object' || card === null)
|
|
630
660
|
return {};
|
|
631
661
|
const mandated = hasOwnStrictTrue(card, 'mandated');
|
|
@@ -639,6 +669,7 @@ export function toolPermissionRequestAskBits(card) {
|
|
|
639
669
|
...(origin !== undefined ? { origin } : {}),
|
|
640
670
|
...(ruleOffersAbsence !== undefined ? { ruleOffersAbsence } : {}),
|
|
641
671
|
...(askClassPair ?? {}),
|
|
672
|
+
...(seatSessionRowOf(card, requestId) ? { sessionRow: true } : {}),
|
|
642
673
|
};
|
|
643
674
|
}
|
|
644
675
|
function hasOwnStrictTrue(v, key) {
|
|
@@ -830,17 +861,28 @@ export function readToolApprovalRespondRefusal(err) {
|
|
|
830
861
|
return undefined;
|
|
831
862
|
}
|
|
832
863
|
};
|
|
833
|
-
const
|
|
834
|
-
const
|
|
864
|
+
const pickMachine = (key) => guardedRead(() => (typeof err === 'object' && err !== null ? readOwnDataValue(err, key) : undefined));
|
|
865
|
+
const rawStatus = pickMachine('status');
|
|
866
|
+
const rawCode = pickMachine('errorCode');
|
|
835
867
|
const status = typeof rawStatus === 'number' && Number.isFinite(rawStatus) ? rawStatus : undefined;
|
|
836
868
|
const errorCode = typeof rawCode === 'string' && rawCode.length > 0 ? rawCode : undefined;
|
|
837
869
|
const message = refusalTextOf(err, pick('message'));
|
|
838
870
|
if (status === undefined && errorCode === undefined && message === undefined)
|
|
839
871
|
return undefined;
|
|
872
|
+
const machine = typeof err === 'object' && err !== null ? err : undefined;
|
|
873
|
+
const retriable = machine !== undefined && refusalSaysStillPending(machine);
|
|
874
|
+
const cause = machine !== undefined ? refusalCauseWordOf(machine) : undefined;
|
|
875
|
+
const field = machine !== undefined ? readRefusalField(machine) : undefined;
|
|
876
|
+
const unreadable = machine !== undefined && readDecisionRefusalAsk(machine).reading === 'unreadable';
|
|
840
877
|
const rest = {
|
|
841
878
|
...(status !== undefined ? { status } : {}),
|
|
842
879
|
...(errorCode !== undefined ? { errorCode } : {}),
|
|
843
880
|
...(message !== undefined ? { message } : {}),
|
|
881
|
+
...(retriable ? { retriable: true } : {}),
|
|
882
|
+
...(cause !== undefined || field !== undefined
|
|
883
|
+
? { extra: { ...(cause !== undefined ? { cause } : {}), ...(field !== undefined ? { field } : {}) } }
|
|
884
|
+
: {}),
|
|
885
|
+
...(unreadable ? { unreadable: true } : {}),
|
|
844
886
|
};
|
|
845
887
|
if (status !== undefined)
|
|
846
888
|
return { ...rest, status };
|
|
@@ -906,15 +948,26 @@ function usableProbeReason(raw) {
|
|
|
906
948
|
}
|
|
907
949
|
const PROBE_CAUSE_CODE_WORD = /^[a-z][a-z0-9_]{0,31}(?:\.[a-z][a-z0-9_]{0,31}){1,3}$/;
|
|
908
950
|
export function askProbeReasonDetail(card) {
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
951
|
+
const prose = usableProbeReason(ownDataValue(card, 'probeReason'));
|
|
952
|
+
const shown = prose === undefined ? '' : displayUntrusted(prose);
|
|
953
|
+
const sentence = probeCauseSentence(ownDataValue(card, 'probeCause'), shown !== '');
|
|
954
|
+
if (sentence === undefined)
|
|
955
|
+
return shown === '' ? undefined : shown;
|
|
956
|
+
return shown === '' ? sentence : `${sentence} ${shown}`;
|
|
957
|
+
}
|
|
958
|
+
function probeCauseSentence(cause, withProse) {
|
|
959
|
+
try {
|
|
960
|
+
if (!isWireRecordCarrier(cause))
|
|
961
|
+
return undefined;
|
|
962
|
+
const code = ownDataValue(cause, 'code');
|
|
963
|
+
const head = withProse
|
|
964
|
+
? 'An automatic check could not clear this call, so it is asking you'
|
|
965
|
+
: 'An automatic check could not clear this call, so it is asking you; the engine did not say the specific reason';
|
|
966
|
+
return typeof code === 'string' && PROBE_CAUSE_CODE_WORD.test(code) ? `${head} (check code: ${code}).` : `${head}.`;
|
|
967
|
+
}
|
|
968
|
+
catch {
|
|
914
969
|
return undefined;
|
|
915
|
-
|
|
916
|
-
const head = 'An automatic check could not clear this call, so it is asking you; the engine did not say the specific reason';
|
|
917
|
-
return typeof code === 'string' && PROBE_CAUSE_CODE_WORD.test(code) ? `${head} (check code: ${code}).` : `${head}.`;
|
|
970
|
+
}
|
|
918
971
|
}
|
|
919
972
|
export function readApprovalRememberRefused(v) {
|
|
920
973
|
try {
|
|
@@ -968,6 +1021,76 @@ export function readApprovalBoundGrants(v) {
|
|
|
968
1021
|
return undefined;
|
|
969
1022
|
return Object.freeze({ skill, allowedTools, disallowedTools });
|
|
970
1023
|
}
|
|
1024
|
+
function readApprovalGrantBinding(carrier) {
|
|
1025
|
+
if (typeof carrier !== 'object' || carrier === null)
|
|
1026
|
+
return 'unreadable';
|
|
1027
|
+
try {
|
|
1028
|
+
if (Object.hasOwn(carrier, 'boundGrantDigest')) {
|
|
1029
|
+
const digest = ownDataValue(carrier, 'boundGrantDigest');
|
|
1030
|
+
return typeof digest === 'string' && digest.length > 0 ? 'bound' : 'unreadable';
|
|
1031
|
+
}
|
|
1032
|
+
const tool = ownDataValue(carrier, 'toolName');
|
|
1033
|
+
if (typeof tool !== 'string' || tool.length === 0)
|
|
1034
|
+
return 'unreadable';
|
|
1035
|
+
return tool === CORE_SKILL_TOOL_NAME ? 'unreadable' : 'none';
|
|
1036
|
+
}
|
|
1037
|
+
catch {
|
|
1038
|
+
return 'unreadable';
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
const UNREADABLE_EVIDENCE_KEYS = Object.freeze({
|
|
1042
|
+
frame: Object.freeze([
|
|
1043
|
+
['rememberRefused', 'rememberRefused'], ['governanceForced', 'governanceForced'], ['requiresRealApproval', 'requiresRealApproval'],
|
|
1044
|
+
['mandated', 'mandated'], ['mandate', 'mandate'], ['origin', 'origin'], ['ruleOffersAbsence', 'ruleOffersAbsence'], ['ruleOffers', 'ruleOffers'],
|
|
1045
|
+
['allowRuleShadowed', 'allowRuleShadow'], ['persistedRuleShadowed', 'allowRuleShadow'], ['askClass', 'askClass'], ['classes', 'classes'],
|
|
1046
|
+
]),
|
|
1047
|
+
row: Object.freeze([
|
|
1048
|
+
['rememberRefused', 'rememberRefused'], ['governanceForced', 'governanceForced'], ['requiresRealApproval', 'requiresRealApproval'],
|
|
1049
|
+
['mandated', 'mandated'], ['mandate', 'mandate'], ['origin', 'origin'], ['ruleOffersAbsence', 'ruleOffersAbsence'], ['ruleOffers', 'ruleOffersReadOnly'],
|
|
1050
|
+
['askClass', 'askClass'], ['classes', 'classes'],
|
|
1051
|
+
]),
|
|
1052
|
+
v1: Object.freeze([
|
|
1053
|
+
['rememberRefused', 'rememberRefused'], ['governanceForced', 'governanceForced'], ['ruleOffersAbsence', 'ruleOffersAbsence'], ['ruleOffers', 'ruleOffersReadOnly'],
|
|
1054
|
+
['allowRuleShadowed', 'allowRuleShadow'], ['persistedRuleShadowed', 'allowRuleShadow'], ['askClass', 'askClass'], ['classes', 'classes'],
|
|
1055
|
+
]),
|
|
1056
|
+
});
|
|
1057
|
+
function carrierHas(carrier, key) {
|
|
1058
|
+
if (typeof carrier !== 'object' || carrier === null)
|
|
1059
|
+
return false;
|
|
1060
|
+
try {
|
|
1061
|
+
return key in carrier;
|
|
1062
|
+
}
|
|
1063
|
+
catch {
|
|
1064
|
+
return true;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function v1RiskUnreadable(card) {
|
|
1068
|
+
if (!carrierHas(card, 'risk'))
|
|
1069
|
+
return false;
|
|
1070
|
+
try {
|
|
1071
|
+
const risk = card.risk;
|
|
1072
|
+
return typeof risk !== 'object' || risk === null || typeof risk.requiresRealApproval !== 'boolean';
|
|
1073
|
+
}
|
|
1074
|
+
catch {
|
|
1075
|
+
return true;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
function withUnreadableEvidence(carrier, leg, req) {
|
|
1079
|
+
const keys = new Set();
|
|
1080
|
+
for (const [from, to] of UNREADABLE_EVIDENCE_KEYS[leg]) {
|
|
1081
|
+
if (carrierHas(carrier, from) && !Object.hasOwn(req, to))
|
|
1082
|
+
keys.add(from);
|
|
1083
|
+
}
|
|
1084
|
+
if (leg === 'row') {
|
|
1085
|
+
const rd = ownDataValue(carrier, 'riskDescriptor');
|
|
1086
|
+
for (const k of ['allowRuleShadowed', 'shadowedRule'])
|
|
1087
|
+
if (carrierHas(rd, k) && !Object.hasOwn(req, 'allowRuleShadow'))
|
|
1088
|
+
keys.add(`riskDescriptor.${k}`);
|
|
1089
|
+
}
|
|
1090
|
+
if (leg === 'v1' && v1RiskUnreadable(carrier))
|
|
1091
|
+
keys.add('risk');
|
|
1092
|
+
return keys.size === 0 ? req : { ...req, unreadableEvidence: Object.freeze([...keys].sort()) };
|
|
1093
|
+
}
|
|
971
1094
|
const CAUSE_WORD = /^[a-z][a-z0-9_]{0,63}$/;
|
|
972
1095
|
export function readApprovalClassifierNoRuling(v) {
|
|
973
1096
|
const w = ownDataValue(v, 'classifierNoRuling');
|
|
@@ -1249,12 +1372,122 @@ function subagentBadgeFor(frame) {
|
|
|
1249
1372
|
name = `${name.slice(0, 31)}…`;
|
|
1250
1373
|
return { name, color: 'cyan' };
|
|
1251
1374
|
}
|
|
1375
|
+
function v1Bit(stamp) {
|
|
1376
|
+
try {
|
|
1377
|
+
stamp();
|
|
1378
|
+
}
|
|
1379
|
+
catch {
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
export function approvalCardFactsOfV1(card) {
|
|
1383
|
+
if (typeof card !== 'object' || card === null)
|
|
1384
|
+
return undefined;
|
|
1385
|
+
const c = card;
|
|
1386
|
+
const asFrame = card;
|
|
1387
|
+
const fromSubagent = (() => {
|
|
1388
|
+
try {
|
|
1389
|
+
return isFromSubagent(asFrame);
|
|
1390
|
+
}
|
|
1391
|
+
catch {
|
|
1392
|
+
return false;
|
|
1393
|
+
}
|
|
1394
|
+
})();
|
|
1395
|
+
const argsPart = (() => {
|
|
1396
|
+
try {
|
|
1397
|
+
const raw = c.args !== undefined && c.args !== null ? c.args : undefined;
|
|
1398
|
+
if (typeof raw === 'object' && raw !== null)
|
|
1399
|
+
return { args: raw };
|
|
1400
|
+
const fallback = argsFallbackOf(c.message, c.argsOmitted);
|
|
1401
|
+
return { args: fallback.args, argsUnavailable: true, ...(fallback.omittedNote !== undefined ? { wireNote: fallback.omittedNote } : {}) };
|
|
1402
|
+
}
|
|
1403
|
+
catch {
|
|
1404
|
+
return { args: {}, argsUnavailable: true };
|
|
1405
|
+
}
|
|
1406
|
+
})();
|
|
1407
|
+
const out = { toolName: '', ...argsPart };
|
|
1408
|
+
v1Bit(() => {
|
|
1409
|
+
if (typeof c.toolName === 'string')
|
|
1410
|
+
out.toolName = c.toolName;
|
|
1411
|
+
});
|
|
1412
|
+
v1Bit(() => {
|
|
1413
|
+
if (typeof c.toolCallId === 'string' && c.toolCallId !== '')
|
|
1414
|
+
out.toolCallId = c.toolCallId;
|
|
1415
|
+
});
|
|
1416
|
+
v1Bit(() => {
|
|
1417
|
+
if (fromSubagent)
|
|
1418
|
+
out.workerBadge = subagentBadgeFor(asFrame);
|
|
1419
|
+
});
|
|
1420
|
+
v1Bit(() => {
|
|
1421
|
+
if (c.governanceForced === true)
|
|
1422
|
+
out.governanceForced = true;
|
|
1423
|
+
});
|
|
1424
|
+
v1Bit(() => {
|
|
1425
|
+
const d = c.delegation;
|
|
1426
|
+
if (fromSubagent && isToolApprovalDelegation(d))
|
|
1427
|
+
out.delegation = d;
|
|
1428
|
+
});
|
|
1429
|
+
v1Bit(() => {
|
|
1430
|
+
const offers = readRuleOffers(c.ruleOffers);
|
|
1431
|
+
if (offers !== undefined)
|
|
1432
|
+
out.ruleOffersReadOnly = offers;
|
|
1433
|
+
});
|
|
1434
|
+
v1Bit(() => {
|
|
1435
|
+
const shadow = readAllowRuleShadowFromWire(card, 'frame');
|
|
1436
|
+
if (shadow !== undefined)
|
|
1437
|
+
out.allowRuleShadow = shadow;
|
|
1438
|
+
});
|
|
1439
|
+
v1Bit(() => {
|
|
1440
|
+
const pc = c.probeCause;
|
|
1441
|
+
if (isWireRecordCarrier(pc))
|
|
1442
|
+
out.probeCause = pc;
|
|
1443
|
+
});
|
|
1444
|
+
v1Bit(() => {
|
|
1445
|
+
if (readApprovalRememberRefused(card))
|
|
1446
|
+
out.rememberRefused = true;
|
|
1447
|
+
});
|
|
1448
|
+
v1Bit(() => {
|
|
1449
|
+
const re = c.ruleEvidence;
|
|
1450
|
+
if (isWireRecordCarrier(re))
|
|
1451
|
+
out.ruleEvidence = re;
|
|
1452
|
+
});
|
|
1453
|
+
v1Bit(() => {
|
|
1454
|
+
const risk = c.risk;
|
|
1455
|
+
if (typeof risk === 'object' && risk !== null && risk.requiresRealApproval === true)
|
|
1456
|
+
out.requiresRealApproval = true;
|
|
1457
|
+
});
|
|
1458
|
+
v1Bit(() => {
|
|
1459
|
+
if (c.inputHasBidi === true)
|
|
1460
|
+
out.inputHasBidi = true;
|
|
1461
|
+
});
|
|
1462
|
+
v1Bit(() => {
|
|
1463
|
+
const w = c.ruleOffersAbsence;
|
|
1464
|
+
if (typeof w === 'string' && w !== '')
|
|
1465
|
+
out.ruleOffersAbsence = w;
|
|
1466
|
+
});
|
|
1467
|
+
v1Bit(() => {
|
|
1468
|
+
const dlf = readDenialLimitFallback(c.denialLimitFallback);
|
|
1469
|
+
if (dlf !== undefined)
|
|
1470
|
+
out.denialLimitFallback = dlf;
|
|
1471
|
+
});
|
|
1472
|
+
v1Bit(() => {
|
|
1473
|
+
const pair = readAskClassPair(card);
|
|
1474
|
+
if (pair !== undefined) {
|
|
1475
|
+
out.askClass = pair.askClass;
|
|
1476
|
+
out.classes = pair.classes;
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
out.grantBinding = readApprovalGrantBinding(card);
|
|
1480
|
+
return Object.freeze(withUnreadableEvidence(card, 'v1', out));
|
|
1481
|
+
}
|
|
1252
1482
|
const MAX_RESPOND_NOTE_CHARS = 2048;
|
|
1253
1483
|
export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamArgs, signal, lane, run) {
|
|
1254
1484
|
const approvalId = frame.approvalId;
|
|
1255
1485
|
const held = liveCardHoldOf(liveFrameCallKey(approvalId));
|
|
1256
1486
|
if (held !== undefined)
|
|
1257
1487
|
return joinLiveCard(held, signal);
|
|
1488
|
+
const settled = settledLiveCardOutcome(approvalId);
|
|
1489
|
+
if (settled !== undefined)
|
|
1490
|
+
return Promise.resolve(settled);
|
|
1258
1491
|
return holdLiveCard(liveCardIdentityOf(approvalId, frame, run), signal, async (hold) => {
|
|
1259
1492
|
const slot = {};
|
|
1260
1493
|
const out = await presentToolApprovalFrameAndRespond(frame, approvalId, respond, streamArgs, signal, lane, hold, slot);
|
|
@@ -1293,9 +1526,12 @@ function readApprovalHolderIdentity(v) {
|
|
|
1293
1526
|
return out;
|
|
1294
1527
|
}
|
|
1295
1528
|
export async function joinApprovalHolder(identity, signal) {
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1298
|
-
|
|
1529
|
+
const who = readApprovalHolderIdentity(identity);
|
|
1530
|
+
const hold = liveCardHoldFor(who);
|
|
1531
|
+
if (hold === undefined) {
|
|
1532
|
+
const entry = settledApprovalOf(who.approvalId);
|
|
1533
|
+
return settledForDurableLane(entry) && entry !== undefined ? { kind: 'joined', outcome: { ...entry.outcome, joinedInFlight: true } } : { kind: 'free' };
|
|
1534
|
+
}
|
|
1299
1535
|
const joined = await awaitLiveCardHolder(hold, signal);
|
|
1300
1536
|
return joined !== undefined ? { kind: 'joined', outcome: joined } : { kind: 'free' };
|
|
1301
1537
|
}
|
|
@@ -1312,11 +1548,11 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1312
1548
|
let argsFallback = false;
|
|
1313
1549
|
if (typeof args !== 'object' || args === null) {
|
|
1314
1550
|
argsFallback = true;
|
|
1315
|
-
const
|
|
1316
|
-
args =
|
|
1317
|
-
if (
|
|
1318
|
-
wireNote =
|
|
1319
|
-
hostLog('debug', `liveToolApprovalWire: frame ${approvalId} args omitted (>16KiB wire cap) — card falls back to ${
|
|
1551
|
+
const fallback = argsFallbackOf(frame.message, frame.argsOmitted);
|
|
1552
|
+
args = fallback.args;
|
|
1553
|
+
if (fallback.omittedNote !== undefined) {
|
|
1554
|
+
wireNote = fallback.omittedNote;
|
|
1555
|
+
hostLog('debug', `liveToolApprovalWire: frame ${approvalId} args omitted (>16KiB wire cap) — card falls back to ${fallback.pathRecovered ? 'the message-derived path' : 'an empty input (no path could be derived from the message)'}`);
|
|
1320
1556
|
}
|
|
1321
1557
|
if (lane?.argsUnavailable === true) {
|
|
1322
1558
|
wireNote =
|
|
@@ -1329,7 +1565,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1329
1565
|
const ruleOffers = readRuleOffers(frame.ruleOffers);
|
|
1330
1566
|
const denialLimitFallback = readDenialLimitFallback(frame.denialLimitFallback);
|
|
1331
1567
|
const frameShadow = readAllowRuleShadowFromWire(frame, 'frame');
|
|
1332
|
-
const card = await surfaceCallTrackedCard(frameToolCallId, approvalId, ledgerSlot, {
|
|
1568
|
+
const card = await surfaceCallTrackedCard(frameToolCallId, approvalId, ledgerSlot, withUnreadableEvidence(frame, 'frame', {
|
|
1333
1569
|
toolName,
|
|
1334
1570
|
args: args,
|
|
1335
1571
|
callKey: liveFrameCallKey(approvalId),
|
|
@@ -1370,10 +1606,13 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1370
1606
|
: {}),
|
|
1371
1607
|
...(denialLimitFallback !== undefined ? { denialLimitFallback } : {}),
|
|
1372
1608
|
...((o) => (o !== undefined ? { origin: o } : {}))(readAskOrigin(frame)),
|
|
1609
|
+
...((w) => (w !== undefined ? { approvalCard: w } : {}))(readApprovalCardWord(frame)),
|
|
1373
1610
|
...(readAskClassPair(frame) ?? {}),
|
|
1374
1611
|
...((g) => (g !== undefined ? { boundGrants: g } : {}))(readApprovalBoundGrants(frame)),
|
|
1375
1612
|
...((w) => (w !== undefined ? { classifierNoRuling: w } : {}))(readApprovalClassifierNoRuling(frame)),
|
|
1376
|
-
|
|
1613
|
+
allowSessionCarried: true,
|
|
1614
|
+
grantBinding: readApprovalGrantBinding(frame),
|
|
1615
|
+
}));
|
|
1377
1616
|
if (hold.superseded !== undefined) {
|
|
1378
1617
|
hostLog('debug', `liveToolApprovalWire: ${approvalId} was settled by the engine while its card was up${hold.superseded.parked ? ' (parked)' : ''} — card withdrawn; ` +
|
|
1379
1618
|
`the card came back ${card.kind}; nothing sent`);
|
|
@@ -1400,7 +1639,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1400
1639
|
catch (e) {
|
|
1401
1640
|
interruptDeny = Promise.reject(e);
|
|
1402
1641
|
}
|
|
1403
|
-
hold.trailing = interruptDeny.then(() => undefined, () =>
|
|
1642
|
+
hold.trailing = interruptDeny.then((body) => readToolApprovalRespondParking(body) === undefined, () => false);
|
|
1404
1643
|
observeCancelByDeny(interruptDeny, approvalId);
|
|
1405
1644
|
hostLog('debug', `liveToolApprovalWire: ${approvalId} card aborted — one tool-level deny issued to settle the pending ask`);
|
|
1406
1645
|
return { decision: 'unresolved', aborted: true };
|
|
@@ -3,15 +3,7 @@ export type HookMatcherVerdict = {
|
|
|
3
3
|
readonly kind: 'matchesAll';
|
|
4
4
|
} | {
|
|
5
5
|
readonly kind: 'accepted';
|
|
6
|
-
readonly reading: 'names';
|
|
7
|
-
readonly names: readonly string[];
|
|
8
|
-
readonly aliases: readonly {
|
|
9
|
-
readonly alias: string;
|
|
10
|
-
readonly canonical: string;
|
|
11
|
-
}[];
|
|
12
|
-
} | {
|
|
13
|
-
readonly kind: 'accepted';
|
|
14
|
-
readonly reading: 'pattern';
|
|
6
|
+
readonly reading: 'names' | 'pattern';
|
|
15
7
|
readonly aliases: readonly {
|
|
16
8
|
readonly alias: string;
|
|
17
9
|
readonly canonical: string;
|