@sema-agent/client-core 0.96.0 → 0.97.1
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 +110 -0
- package/README.md +29 -22
- package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
- package/dist/adapter/activeRunSelfHeal.js +7 -7
- package/dist/adapter/downstream/terminalToSdkResult.js +6 -2
- package/dist/agentSession/backgroundView.js +2 -15
- package/dist/agentsWireCaps.d.ts +3 -1
- package/dist/agentsWireCaps.js +67 -39
- 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 -0
- package/dist/callerCwdCapability.js +0 -1
- package/dist/centerWiringCapability.d.ts +2 -0
- package/dist/centerWiringCapability.js +4 -3
- package/dist/cloudConfigWireCaps.d.ts +2 -2
- package/dist/cloudConfigWireCaps.js +192 -56
- 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 +3 -0
- package/dist/displayUntrusted.js +15 -0
- package/dist/engineCapReader.d.ts +8 -2
- package/dist/engineCapReader.js +15 -7
- package/dist/engineCapsCache.d.ts +11 -3
- package/dist/engineCapsCache.js +54 -23
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +9 -1
- package/dist/engineNoticeCodes.js +2 -3
- package/dist/engineToolDirectory.d.ts +27 -0
- package/dist/engineToolDirectory.js +178 -0
- package/dist/executionLaneCapability.d.ts +2 -0
- package/dist/executionLaneCapability.js +3 -2
- package/dist/fileHistoryCaptureCapability.d.ts +2 -0
- package/dist/fileHistoryCaptureCapability.js +34 -8
- package/dist/fileHistoryLegNotice.js +4 -0
- package/dist/fleet/fleetLedger.js +129 -105
- package/dist/gateOutcome.js +2 -4
- package/dist/gateVocabulary.d.ts +1 -6
- package/dist/gateVocabulary.js +2 -5
- package/dist/generated/sdkFactTables.d.ts +2 -0
- package/dist/generated/sdkFactTables.js +7 -0
- package/dist/generated/toolNameTables.d.ts +0 -1
- package/dist/generated/toolNameTables.js +0 -42
- package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
- package/dist/hitl/approvalEndingCause.js +2 -7
- 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/automaticAnswerVerdict.js +5 -7
- package/dist/hitl/decisionConflict.js +4 -3
- package/dist/hitl/decisionRefusal.js +19 -12
- package/dist/hitl/frameRouter.d.ts +3 -0
- package/dist/hitl/frameRouter.js +52 -25
- package/dist/hitl/gateLedger.d.ts +0 -5
- package/dist/hitl/gateLedger.js +0 -21
- package/dist/hitl/hitlBridge.js +18 -4
- package/dist/hitl/parkResolver.js +7 -3
- package/dist/hitl/replayedApproval.d.ts +2 -3
- package/dist/hitl/replayedApproval.js +7 -16
- package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
- package/dist/hitl/sessionPolicyDeliverable.js +15 -17
- package/dist/hitl/sessionPolicyWire.d.ts +2 -0
- package/dist/hitl/sessionPolicyWire.js +15 -3
- package/dist/hitl/standingRows.d.ts +1 -0
- package/dist/hitl/standingRows.js +38 -17
- package/dist/hitl/suspendedReopen.js +2 -1
- package/dist/hitl/toolApprovalWire.d.ts +8 -8
- package/dist/hitl/toolApprovalWire.js +50 -24
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -3
- package/dist/liveModelCatalog.d.ts +13 -0
- package/dist/liveModelCatalog.js +56 -0
- package/dist/mcpProbeCapability.d.ts +2 -0
- package/dist/mcpProbeCapability.js +3 -2
- package/dist/mcpWireCaps.d.ts +1 -0
- package/dist/mcpWireCaps.js +4 -1
- package/dist/memoryComplianceCapability.d.ts +2 -0
- package/dist/memoryComplianceCapability.js +3 -2
- package/dist/memoryOriginCapability.d.ts +2 -0
- package/dist/memoryOriginCapability.js +3 -2
- package/dist/modelIdentityResolvability.js +2 -2
- package/dist/noticePresentation.js +2 -2
- package/dist/outputStyleSeatCapability.d.ts +2 -0
- package/dist/outputStyleSeatCapability.js +0 -1
- package/dist/peerLaneCapability.d.ts +2 -0
- package/dist/peerLaneCapability.js +3 -2
- package/dist/permissionModesCapability.d.ts +2 -0
- package/dist/permissionModesCapability.js +0 -1
- 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.js +19 -21
- package/dist/request/taskRequest.d.ts +1 -4
- package/dist/request/taskRequest.js +74 -19
- package/dist/resumeRefusalCopy.js +4 -4
- package/dist/rewindArchiveCapability.js +5 -0
- package/dist/rewindArchiveReading.d.ts +2 -0
- package/dist/rewindArchiveReading.js +0 -1
- package/dist/runTerminal.d.ts +33 -4
- package/dist/runTerminal.js +170 -15
- package/dist/sdkWireTransit.d.ts +2 -1
- package/dist/sdkWireTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +2 -0
- package/dist/sealedKeyCapability.js +0 -1
- package/dist/seatContract.d.ts +7 -4
- package/dist/seatContract.js +34 -20
- package/dist/sessionPolicyCapability.d.ts +2 -0
- package/dist/sessionPolicyCapability.js +3 -2
- package/dist/sessionReadRedactionCapability.d.ts +2 -0
- package/dist/sessionReadRedactionCapability.js +0 -1
- package/dist/sessionSyncFileHistoryCapability.d.ts +2 -0
- package/dist/sessionSyncFileHistoryCapability.js +3 -2
- package/dist/skillToolListsCapability.d.ts +2 -0
- package/dist/skillToolListsCapability.js +3 -2
- package/dist/sqlEngineCapability.d.ts +2 -0
- package/dist/sqlEngineCapability.js +4 -3
- package/dist/steerPriorityCapability.d.ts +2 -0
- package/dist/steerPriorityCapability.js +3 -2
- package/dist/storePostureCapability.d.ts +2 -0
- package/dist/storePostureCapability.js +4 -3
- package/dist/toolHistoryBadTurn.js +3 -2
- package/dist/toolResult.d.ts +11 -0
- package/dist/toolResult.js +53 -0
- package/dist/userInvokedSkillsCapability.d.ts +2 -0
- package/dist/userInvokedSkillsCapability.js +3 -2
- package/dist/webSearchBackendCapability.d.ts +2 -0
- package/dist/webSearchBackendCapability.js +3 -2
- package/dist/wireErrorTriage.js +58 -34
- package/dist/wireFailureShape.d.ts +1 -1
- package/dist/wireFailureShape.js +76 -25
- 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 +585 -14
- package/package.json +4 -4
- package/dist/engineRefusedToolName.d.ts +0 -1
- package/dist/engineRefusedToolName.js +0 -8
- package/dist/engineWordRenames.d.ts +0 -8
- package/dist/engineWordRenames.js +0 -13
package/dist/hitl/askGateWire.js
CHANGED
|
@@ -60,6 +60,7 @@ export async function* bridgeAskUserQuestionGates(source, deps, opts) {
|
|
|
60
60
|
gate: action.gate,
|
|
61
61
|
...(action.pendingDone !== undefined ? { pendingDone: action.pendingDone } : {}),
|
|
62
62
|
...(action.gatedCallId !== undefined ? { gatedCallId: action.gatedCallId } : {}),
|
|
63
|
+
...(action.toolName !== undefined ? { toolName: action.toolName } : {}),
|
|
63
64
|
};
|
|
64
65
|
break;
|
|
65
66
|
}
|
|
@@ -3,7 +3,6 @@ import { CORE_RELEASABLE_ASK_CLASSES_BY_FACE, CORE_SHELL_FACE_TOOL_NAMES } from
|
|
|
3
3
|
import { mandatedApprovalDetail } from '../gateVocabulary.js';
|
|
4
4
|
import { readAskOrigin, readOwnNonEmptyString } from '../ownKey.js';
|
|
5
5
|
import { readAskClassPairState } from './askClassPair.js';
|
|
6
|
-
import { currentEngineWord } from '../engineWordRenames.js';
|
|
7
6
|
import { approvalAllowRuleShadowed } from './allowRuleShadow.js';
|
|
8
7
|
import { approvalIsMandated, readApprovalMandate } from './toolApprovalWire.js';
|
|
9
8
|
export const MODE_ARBITRATION = CORE_MODE_ARBITRATION;
|
|
@@ -19,8 +18,7 @@ const ORIGIN_IMPLIES_CLASS = Object.freeze({
|
|
|
19
18
|
function mandateWordClass(raw) {
|
|
20
19
|
if (raw === 'operator_always')
|
|
21
20
|
return 'shell_floor';
|
|
22
|
-
|
|
23
|
-
return Object.hasOwn(TABLE, word) ? word : undefined;
|
|
21
|
+
return Object.hasOwn(TABLE, raw) ? raw : undefined;
|
|
24
22
|
}
|
|
25
23
|
const ORDINARY_ROW = CORE_MODE_ARBITRATION.ordinary;
|
|
26
24
|
function bypassImmuneOn(c, face) {
|
|
@@ -44,8 +42,8 @@ export function foldModeArbitrationRow(classes, askFace) {
|
|
|
44
42
|
let ruleMayClear = true;
|
|
45
43
|
let hookAskFloor = false;
|
|
46
44
|
for (const raw of classes) {
|
|
47
|
-
const c =
|
|
48
|
-
if (!Object.hasOwn(TABLE, c))
|
|
45
|
+
const c = raw;
|
|
46
|
+
if (typeof c !== 'string' || !Object.hasOwn(TABLE, c))
|
|
49
47
|
continue;
|
|
50
48
|
const row = TABLE[c];
|
|
51
49
|
any = true;
|
|
@@ -133,7 +131,7 @@ export function automaticAnswerVerdict(card, lane, facts) {
|
|
|
133
131
|
return UNKNOWN.classes_malformed;
|
|
134
132
|
if (pair.state === 'absent')
|
|
135
133
|
return UNKNOWN.classes_absent;
|
|
136
|
-
const classes = pair.classes
|
|
134
|
+
const classes = pair.classes;
|
|
137
135
|
const folded = foldModeArbitrationRow(classes, face);
|
|
138
136
|
let anyKnown = false;
|
|
139
137
|
let firstBlocking;
|
|
@@ -172,7 +170,7 @@ export function mandatedApprovalDetailOf(card) {
|
|
|
172
170
|
const pair = readAskClassPairState(card);
|
|
173
171
|
if (pair.state !== 'pair')
|
|
174
172
|
return mandatedApprovalDetail();
|
|
175
|
-
const classes = pair.classes
|
|
173
|
+
const classes = pair.classes;
|
|
176
174
|
if (classes.some((c) => !Object.hasOwn(TABLE, c)))
|
|
177
175
|
return mandatedApprovalDetail();
|
|
178
176
|
const row = foldModeArbitrationRow(classes);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { APPROVAL_BINDING_MISMATCH, CHECKPOINT_UNSUPPORTED_VERSION, RESUME_OUTCOME_INVALID } from '../engineErrorCodes.js';
|
|
2
|
+
import { ownDataField } from '../ownKey.js';
|
|
2
3
|
import { readRefusalField } from '../wireFailureShape.js';
|
|
3
4
|
const BINDING_SEAT_FIELDS = new Set(['boundCallId', 'boundInputHash']);
|
|
4
5
|
const ANSWER_FIELD = 'answer';
|
|
@@ -9,13 +10,13 @@ export function decisionConflictOf(err) {
|
|
|
9
10
|
let code;
|
|
10
11
|
let name;
|
|
11
12
|
try {
|
|
12
|
-
code = err
|
|
13
|
+
code = ownDataField(err, 'errorCode');
|
|
13
14
|
}
|
|
14
15
|
catch {
|
|
15
|
-
|
|
16
|
+
return undefined;
|
|
16
17
|
}
|
|
17
18
|
try {
|
|
18
|
-
name = err
|
|
19
|
+
name = ownDataField(err, 'name');
|
|
19
20
|
}
|
|
20
21
|
catch {
|
|
21
22
|
name = undefined;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ApprovalStaleError, AskDecidedError, ParkedResumeStartupError } from '@sema-agent/sdk';
|
|
2
1
|
import { ASK_GONE, ASK_GONE_PARKED, isDecideAlreadyResolvedCode, isDecideParkMovedCode, refusalRetriableReading, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
3
2
|
import { notPendingCauseReading } from './approvalEndingCause.js';
|
|
4
3
|
import { GATE_FAILURE_CODES } from './hitlBridge.js';
|
|
5
4
|
import { isAlreadyResolvedGateReason, isCodeClassifiedGateFailure } from './parkResolver.js';
|
|
6
5
|
import { decisionConflictOf } from './decisionConflict.js';
|
|
7
6
|
import { readLivePendingRows } from './livePendingAsk.js';
|
|
7
|
+
import { ownDataField } from '../ownKey.js';
|
|
8
8
|
import { readToolApprovalRespondRefusal } from './toolApprovalWire.js';
|
|
9
9
|
const ASK_DECIDED_CODE = 'conflict.ask_decided';
|
|
10
10
|
const TRANSIENT_STATUSES = new Set([408, 425, 429, 502, 503, 504]);
|
|
@@ -13,22 +13,27 @@ export function decisionRefusalSaysAskGone(err) {
|
|
|
13
13
|
return readDecisionRefusalAsk(err).reading === 'settled';
|
|
14
14
|
}
|
|
15
15
|
const facts = (reading, gateMoved = false, wordingHint = false) => ({ reading, gateMoved, wordingHint });
|
|
16
|
+
const PROTOCOL_ERROR_NAMES = Object.freeze({
|
|
17
|
+
askDecided: 'AskDecidedError',
|
|
18
|
+
approvalStale: 'ApprovalStaleError',
|
|
19
|
+
parkedResumeStartup: 'ParkedResumeStartupError',
|
|
20
|
+
});
|
|
16
21
|
export function readDecisionRefusalAsk(failure) {
|
|
17
22
|
if (typeof failure !== 'object' || failure === null)
|
|
18
23
|
return facts('not_settled');
|
|
19
24
|
let flattened, localCode, name, errorCode, status, retriable, text;
|
|
20
25
|
try {
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
26
|
+
const slot = (key) => ownDataField(failure, key);
|
|
27
|
+
if (slot('unreadable') === true)
|
|
23
28
|
return facts('unreadable');
|
|
24
|
-
flattened =
|
|
29
|
+
flattened = slot('kind') === 'failed';
|
|
25
30
|
const closed = (v) => (typeof v === 'string' && GATE_FAILURE_CODES.includes(v) ? v : undefined);
|
|
26
|
-
localCode = flattened ? (closed(
|
|
27
|
-
name = flattened ? undefined :
|
|
28
|
-
errorCode =
|
|
29
|
-
status =
|
|
31
|
+
localCode = flattened ? (closed(slot('code')) ?? closed(slot('safetyCode'))) : closed(slot('code'));
|
|
32
|
+
name = flattened ? undefined : slot('name');
|
|
33
|
+
errorCode = slot('errorCode');
|
|
34
|
+
status = slot('status');
|
|
30
35
|
retriable = refusalRetriableReading(failure);
|
|
31
|
-
text = flattened ?
|
|
36
|
+
text = flattened ? slot('reason') : String(failure);
|
|
32
37
|
}
|
|
33
38
|
catch {
|
|
34
39
|
return facts('unreadable');
|
|
@@ -40,15 +45,17 @@ export function readDecisionRefusalAsk(failure) {
|
|
|
40
45
|
if (name === 'HitlSafetyError')
|
|
41
46
|
return facts('not_settled');
|
|
42
47
|
const code = typeof errorCode === 'string' && errorCode.length > 0 ? errorCode : undefined;
|
|
48
|
+
if (isCodeClassifiedGateFailure(code, retriable))
|
|
49
|
+
return facts('not_settled');
|
|
43
50
|
const st = typeof status === 'number' && Number.isInteger(status) && status >= 400 && status <= 599 ? status : undefined;
|
|
44
51
|
if (code === ASK_DECIDED_CODE || code === ASK_GONE || (st === 410 && code !== ASK_GONE_PARKED))
|
|
45
52
|
return facts('settled');
|
|
46
53
|
if (st === 404 && notPendingCauseReading(failure) === 'ended')
|
|
47
54
|
return facts('settled');
|
|
48
|
-
if (code === undefined && name ===
|
|
55
|
+
if (code === undefined && name === PROTOCOL_ERROR_NAMES.askDecided)
|
|
49
56
|
return facts('settled');
|
|
50
|
-
const gateMoved = isDecideAlreadyResolvedCode(code) || isDecideParkMovedCode(code) || code === ASK_GONE_PARKED || (code === undefined && name ===
|
|
51
|
-
if (gateMoved || st !== undefined || name ===
|
|
57
|
+
const gateMoved = isDecideAlreadyResolvedCode(code) || isDecideParkMovedCode(code) || code === ASK_GONE_PARKED || (code === undefined && name === PROTOCOL_ERROR_NAMES.approvalStale);
|
|
58
|
+
if (gateMoved || st !== undefined || name === PROTOCOL_ERROR_NAMES.parkedResumeStartup)
|
|
52
59
|
return facts('not_settled', gateMoved);
|
|
53
60
|
return facts('not_settled', false, isAlreadyResolvedGateReason(text));
|
|
54
61
|
}
|
|
@@ -40,6 +40,7 @@ export interface GatePark {
|
|
|
40
40
|
gate: GateKind;
|
|
41
41
|
pendingDone?: AgentEvent | undefined;
|
|
42
42
|
gatedCallId?: string | undefined;
|
|
43
|
+
toolName?: string | undefined;
|
|
43
44
|
}
|
|
44
45
|
export type FrameAction = {
|
|
45
46
|
kind: 'yield';
|
|
@@ -51,6 +52,7 @@ export type FrameAction = {
|
|
|
51
52
|
gate: GateKind;
|
|
52
53
|
pendingDone?: AgentEvent | undefined;
|
|
53
54
|
gatedCallId?: string | undefined;
|
|
55
|
+
toolName?: string | undefined;
|
|
54
56
|
} | {
|
|
55
57
|
kind: 'end';
|
|
56
58
|
events: readonly AgentEvent[];
|
|
@@ -65,6 +67,7 @@ export interface FrameRouterCtx {
|
|
|
65
67
|
signal?: AbortSignal | undefined;
|
|
66
68
|
}
|
|
67
69
|
export declare function isAskTool(toolName: string | undefined): boolean;
|
|
70
|
+
export declare function parkGateArmOf(gate: unknown): GateKind | null;
|
|
68
71
|
export declare function isHostProgressFrame(ev: AgentEvent): boolean;
|
|
69
72
|
interface HeldFlushInterruptEvidence {
|
|
70
73
|
terminal?: AgentEvent | undefined;
|
package/dist/hitl/frameRouter.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { hostLog } from '../host.js';
|
|
2
2
|
import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
|
|
3
|
-
import {
|
|
3
|
+
import { toolNameIsFsWrite, toolNameIsShellExec, isToolApprovalFrame, isFromSubagent, surfaceToolApprovalFrameAndRespond, } from './toolApprovalWire.js';
|
|
4
4
|
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
8
|
import { surfaceForCurrentSession, surfaceReplayedApprovalListUnreadable } from './hitlHostSurface.js';
|
|
9
|
-
import {
|
|
9
|
+
import { liveCardHoldOf, noteEngineClosedApproval, supersedeLiveCard } from './approvalHolds.js';
|
|
10
10
|
import { approvalCompleteParked } from './approvalCompleteParked.js';
|
|
11
11
|
import { liveFrameCallKey } from './gateIdentity.js';
|
|
12
12
|
import { SEMA_DENIAL_KIND_KEY, hasLedgerPositionKey } from './gateLedger.js';
|
|
@@ -15,6 +15,7 @@ import { settleWithinDeadline } from '../abortableSleep.js';
|
|
|
15
15
|
import { ccToolDenialKindForSettledBy } from '../gateVocabulary.js';
|
|
16
16
|
import { REJECT_MESSAGE } from '../adapt/wireShapes.js';
|
|
17
17
|
import { RUN_CANCELLED_CODE } from '../runCancelContext.js';
|
|
18
|
+
import { durableDecideLegOf } from '../adapter/activeRunSelfHeal.js';
|
|
18
19
|
export const HITL_REJECT_MESSAGE = REJECT_MESSAGE;
|
|
19
20
|
export const HITL_POLICY_DENY_MESSAGE = 'Permission for this tool use was denied: it requires interactive approval, and permission prompts are ' +
|
|
20
21
|
'not available in this session. The action was NOT performed. Do not claim it succeeded, and do not retry ' +
|
|
@@ -99,6 +100,27 @@ function parkFamilyEvidence(led, gateToolName, gatedCallId) {
|
|
|
99
100
|
return false;
|
|
100
101
|
return gatedCallId === undefined || led.isFsOrShellGatedCall(gatedCallId);
|
|
101
102
|
}
|
|
103
|
+
export function parkGateArmOf(gate) {
|
|
104
|
+
if (gate === null || typeof gate !== 'object')
|
|
105
|
+
return null;
|
|
106
|
+
let kind;
|
|
107
|
+
let toolName;
|
|
108
|
+
try {
|
|
109
|
+
kind = gate.kind;
|
|
110
|
+
toolName = gate.toolName;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const leg = durableDecideLegOf(typeof kind === 'string' ? { gateKind: kind } : null);
|
|
116
|
+
if (leg !== 'approval' && leg !== 'absent')
|
|
117
|
+
return null;
|
|
118
|
+
if (isAskToolLoose(toolName))
|
|
119
|
+
return 'ask';
|
|
120
|
+
if (leg === 'approval')
|
|
121
|
+
return 'fs';
|
|
122
|
+
return isFsOrShellToolName(toolName) ? 'fs' : null;
|
|
123
|
+
}
|
|
102
124
|
const ENGINE_GATE_PARKED_ERROR_CODE = GATE_PARKED_ERROR_CODE;
|
|
103
125
|
function isEngineAbortToolEnd(ev) {
|
|
104
126
|
if (ev.errorCode === ENGINE_GATE_PARKED_ERROR_CODE)
|
|
@@ -123,11 +145,8 @@ function parkGateOf(result) {
|
|
|
123
145
|
if (typeof taskId !== 'string' || taskId.length === 0)
|
|
124
146
|
return null;
|
|
125
147
|
const toolName = runTerminalGateToolName(read);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (isToolApprovalGate({ kind: runTerminalGateKind(read), toolName }))
|
|
129
|
-
return { taskId, gate: 'fs', toolName };
|
|
130
|
-
return null;
|
|
148
|
+
const arm = parkGateArmOf({ kind: runTerminalGateKind(read), toolName });
|
|
149
|
+
return arm === null ? null : { taskId, gate: arm, toolName };
|
|
131
150
|
}
|
|
132
151
|
function parkGatedCallId(src) {
|
|
133
152
|
const v = src?.toolCallId;
|
|
@@ -264,18 +283,19 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
264
283
|
const { led, deps } = ctx;
|
|
265
284
|
if (ev.type === 'tool_approval_complete') {
|
|
266
285
|
const id = ev.approvalId;
|
|
267
|
-
|
|
286
|
+
const parked = approvalCompleteParked(ev);
|
|
287
|
+
if (typeof id === 'string' && id !== '')
|
|
288
|
+
noteEngineClosedApproval(id, parked);
|
|
289
|
+
if (typeof id === 'string' && id !== '' && supersedeLiveCard(liveFrameCallKey(id), parked)) {
|
|
268
290
|
hostLog('debug', `liveHitlAskWire: tool_approval_complete for ${id} arrived while its card was waiting — card withdrawn (nothing will be sent from it)`);
|
|
269
291
|
}
|
|
270
|
-
if (typeof id === 'string' && id !== '')
|
|
271
|
-
led.noteApprovalSettled(id, 'closed_by_engine');
|
|
272
292
|
return { kind: 'skip' };
|
|
273
293
|
}
|
|
274
294
|
if (!deps.respondToolApproval) {
|
|
275
295
|
hostLog('debug', `liveHitlAskWire: tool_approval frame ${ev.approvalId} but no respond wire — engine self-settles (TTL deny)`);
|
|
276
296
|
return { kind: 'skip' };
|
|
277
297
|
}
|
|
278
|
-
const settledHere = settledApprovalDisposition(ev
|
|
298
|
+
const settledHere = settledApprovalDisposition(ev);
|
|
279
299
|
if (settledHere !== undefined || (hasLedgerPositionKey(ev) && !led.preambleApprovals().has(ev.approvalId))) {
|
|
280
300
|
const disposition = settledHere ?? (await judgeLedgerApprovalFrame(ev, ctx));
|
|
281
301
|
if (disposition.kind !== 'live') {
|
|
@@ -298,21 +318,17 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
298
318
|
const gatedCallId = fromSubagent ? undefined : frameCallId ?? led.lastPendingFsCall();
|
|
299
319
|
const argsCallId = frameCallId === undefined ? gatedCallId : typeof ev.toolName === 'string' && toolNameIsFsWrite(ev.toolName) ? frameCallId : undefined;
|
|
300
320
|
const runTaskId = ctx.taskId.current;
|
|
301
|
-
const approvalIdAtLaunch = ev.approvalId;
|
|
302
321
|
const launched = surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, argsCallId), ctx.signal, deps.approvalLane, typeof runTaskId === 'string' && runTaskId !== '' ? { taskId: runTaskId } : undefined);
|
|
303
322
|
const hold = liveCardHoldOf(liveFrameCallKey(ev.approvalId));
|
|
304
|
-
const handled = launched.then((outcome) => settleLiveCardOutcome(ev,
|
|
323
|
+
const handled = launched.then((outcome) => settleLiveCardOutcome(ev, outcome, ctx, fromSubagent, gatedCallId), (e) => {
|
|
305
324
|
hostLog('debug', `liveHitlAskWire: tool_approval card for ${ev.approvalId} failed: ${String(e).slice(0, 160)}`);
|
|
306
325
|
});
|
|
307
326
|
led.trackLiveCard(() => hold?.phase ?? 'card', handled);
|
|
308
327
|
return { kind: 'skip' };
|
|
309
328
|
}
|
|
310
|
-
function settleLiveCardOutcome(ev,
|
|
329
|
+
function settleLiveCardOutcome(ev, outcome, ctx, fromSubagent, gatedCallId) {
|
|
311
330
|
const { led, deps } = ctx;
|
|
312
331
|
const { decision } = outcome;
|
|
313
|
-
const settledHow = liveCardAnsweredHow(outcome);
|
|
314
|
-
if (settledHow !== undefined)
|
|
315
|
-
led.noteApprovalSettled(approvalId, settledHow);
|
|
316
332
|
if (deps.onToolApprovalOutcome !== undefined) {
|
|
317
333
|
invokeHostCallbackIsolated('liveHitlAskWire: onToolApprovalOutcome', () => deps.onToolApprovalOutcome?.(ev, outcome));
|
|
318
334
|
}
|
|
@@ -349,7 +365,7 @@ async function judgeLedgerApprovalFrame(ev, ctx) {
|
|
|
349
365
|
.finally(release);
|
|
350
366
|
});
|
|
351
367
|
const approvals = got.kind === 'value' ? { read: 'ok', body: got.value } : { read: 'failed' };
|
|
352
|
-
return replayedApprovalDisposition(ev, { preamble: ctx.led.preambleApprovals(), approvals
|
|
368
|
+
return replayedApprovalDisposition(ev, { preamble: ctx.led.preambleApprovals(), approvals });
|
|
353
369
|
}
|
|
354
370
|
function routeToolStart(ev, callId, led) {
|
|
355
371
|
led.noteStart(callId, ev);
|
|
@@ -382,15 +398,20 @@ function routeToolEnd(ev, callId, led) {
|
|
|
382
398
|
}
|
|
383
399
|
function routeSuspended(ev, ctx) {
|
|
384
400
|
const gatedCallId = parkGatedCallId(ev);
|
|
385
|
-
|
|
401
|
+
const arm = parkGateArmOf(ev.gate);
|
|
402
|
+
if (arm === 'ask' && ctx.taskId.current) {
|
|
386
403
|
ctx.led.noteParkGate({ fsOrShellFamily: false });
|
|
387
404
|
return { kind: 'park', gate: 'ask', ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
|
|
388
405
|
}
|
|
389
|
-
if (
|
|
390
|
-
|
|
391
|
-
ctx.
|
|
392
|
-
|
|
393
|
-
|
|
406
|
+
if (arm === 'fs' && ctx.taskId.current) {
|
|
407
|
+
const gateToolName = ev.gate?.toolName;
|
|
408
|
+
ctx.led.noteParkGate({ fsOrShellFamily: parkFamilyEvidence(ctx.led, gateToolName, gatedCallId) });
|
|
409
|
+
return {
|
|
410
|
+
kind: 'park',
|
|
411
|
+
gate: 'fs',
|
|
412
|
+
...(gatedCallId !== undefined ? { gatedCallId } : {}),
|
|
413
|
+
...(typeof gateToolName === 'string' && gateToolName !== '' ? { toolName: gateToolName } : {}),
|
|
414
|
+
};
|
|
394
415
|
}
|
|
395
416
|
return { kind: 'yield', events: [ev] };
|
|
396
417
|
}
|
|
@@ -401,7 +422,13 @@ function routeDone(ev, ctx) {
|
|
|
401
422
|
if (park !== null) {
|
|
402
423
|
ctx.taskId.current = ctx.taskId.current ?? park.taskId;
|
|
403
424
|
led.noteParkGate({ fsOrShellFamily: park.gate === 'fs' && parkFamilyEvidence(led, park.toolName, gatedCallId) });
|
|
404
|
-
return {
|
|
425
|
+
return {
|
|
426
|
+
kind: 'park',
|
|
427
|
+
gate: park.gate,
|
|
428
|
+
pendingDone: ev,
|
|
429
|
+
...(gatedCallId !== undefined ? { gatedCallId } : {}),
|
|
430
|
+
...(park.toolName !== undefined && park.toolName !== '' ? { toolName: park.toolName } : {}),
|
|
431
|
+
};
|
|
405
432
|
}
|
|
406
433
|
const events = [...flushHeldWithInterruptRewrite(led, { terminal: ev, signal: ctx.signal })];
|
|
407
434
|
const r = ev.result;
|
|
@@ -16,9 +16,6 @@ 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;
|
|
22
19
|
export interface GateLedger {
|
|
23
20
|
noteSeq(ev: AgentEvent): void;
|
|
24
21
|
lastSeq(): string | undefined;
|
|
@@ -26,8 +23,6 @@ export interface GateLedger {
|
|
|
26
23
|
notePreambleApproval(approvalId: string): void;
|
|
27
24
|
preambleApprovals(): ReadonlySet<string>;
|
|
28
25
|
beginStreamSegment(): void;
|
|
29
|
-
noteApprovalSettled(approvalId: string, how: ApprovalSettledHow): void;
|
|
30
|
-
settledApprovals(): ReadonlyMap<string, ApprovalSettledHow>;
|
|
31
26
|
trackLiveCard(phaseOf: () => 'card' | 'respond', handled: Promise<void>): void;
|
|
32
27
|
answeringLiveCards(): Promise<void>[];
|
|
33
28
|
liveCardsSettled(): Promise<void>;
|
package/dist/hitl/gateLedger.js
CHANGED
|
@@ -13,8 +13,6 @@ 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;
|
|
18
16
|
export const START_ARGS_MAX_ENTRIES = 256;
|
|
19
17
|
function normalizeDenyAttribution(a) {
|
|
20
18
|
if (a === undefined)
|
|
@@ -90,7 +88,6 @@ export function createGateLedger() {
|
|
|
90
88
|
let denyStampAttribution;
|
|
91
89
|
let seq;
|
|
92
90
|
const preambleApprovalIds = new Set();
|
|
93
|
-
const settledApprovalHows = new Map();
|
|
94
91
|
const liveCards = new Set();
|
|
95
92
|
return {
|
|
96
93
|
noteSeq(ev) {
|
|
@@ -124,24 +121,6 @@ export function createGateLedger() {
|
|
|
124
121
|
beginStreamSegment() {
|
|
125
122
|
preambleApprovalIds.clear();
|
|
126
123
|
},
|
|
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
124
|
trackLiveCard(phaseOf, handled) {
|
|
146
125
|
const entry = { phaseOf, handled };
|
|
147
126
|
liveCards.add(entry);
|
package/dist/hitl/hitlBridge.js
CHANGED
|
@@ -3,7 +3,7 @@ import { eventSeq } from '../adapter/types.js';
|
|
|
3
3
|
import { hostLog } from '../host.js';
|
|
4
4
|
import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
|
|
5
5
|
import { abortableSleep } from '../abortableSleep.js';
|
|
6
|
-
import { readOwnDataValue } from '../ownKey.js';
|
|
6
|
+
import { ownDataField, readOwnDataValue } from '../ownKey.js';
|
|
7
7
|
import { THROWN_SLOT_UNREADABLE, readBlockedBy, readThrownSlot, thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
|
|
8
8
|
import { RESUME_POLICY_FOLD_CODE } from '../engineErrorCodes.js';
|
|
9
9
|
import { suspendedReopenOf } from './suspendedReopen.js';
|
|
@@ -55,7 +55,13 @@ export class HitlSafetyError extends Error {
|
|
|
55
55
|
export function hitlSafetyCodeOf(e) {
|
|
56
56
|
if (!thrownIsInstanceOf(e, HitlSafetyError))
|
|
57
57
|
return undefined;
|
|
58
|
-
|
|
58
|
+
let raw;
|
|
59
|
+
try {
|
|
60
|
+
raw = ownDataField(e, 'code');
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
59
65
|
return typeof raw === 'string' && GATE_FAILURE_CODES.includes(raw) ? raw : undefined;
|
|
60
66
|
}
|
|
61
67
|
const _gateCurrentPendingReadonlyPin = true;
|
|
@@ -88,9 +94,17 @@ export function readWireErrorCode(e) {
|
|
|
88
94
|
export function readWireErrorCodeReading(e) {
|
|
89
95
|
if (e === null || e === undefined)
|
|
90
96
|
return { state: 'absent' };
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
let raw;
|
|
98
|
+
try {
|
|
99
|
+
if (typeof e === 'object' || typeof e === 'function') {
|
|
100
|
+
raw = ownDataField(e, 'errorCode');
|
|
101
|
+
if (raw === undefined && !Object.hasOwn(e, 'errorCode'))
|
|
102
|
+
void e.errorCode;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
93
106
|
return { state: 'unreadable' };
|
|
107
|
+
}
|
|
94
108
|
return typeof raw === 'string' && raw.length > 0 ? { state: 'code', code: raw } : { state: 'absent' };
|
|
95
109
|
}
|
|
96
110
|
export function readWireCodes(e) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { putOwnKey, readOwnDataValue } from '../ownKey.js';
|
|
2
2
|
import { DecideTransportRetryExhaustedError, GATE_FAILURE_CODES, HitlBridge, NO_QUESTION_OVERLAY_REASON, findPendingForTask, hitlSafetyCodeOf, isNoDecisionSurfaceReason, readDecideCurrentPending, readWireCodes, } from './hitlBridge.js';
|
|
3
|
-
import { DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, PARKED_RESUME_STARTUP_FAILED, RESUME_POLICY_FOLD_CODE, isRefusedParkCode, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
3
|
+
import { DECIDE_WORKFLOW_PARK_FORKED, DECIDE_WORKFLOW_PARKS_UNREADABLE, PARKED_RESUME_STARTUP_FAILED, RESUME_POLICY_FOLD_CODE, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, isRefusedParkCode, refusalSaysStillPending } from '../engineErrorCodes.js';
|
|
4
|
+
import { RESUME_REFUSAL_CODES } from '../resumeRefusalCopy.js';
|
|
4
5
|
import { readDecisionRefusalAsk } from './decisionRefusal.js';
|
|
5
6
|
import { publishQuestionFrame, registerLocalQuestionResponder, hasQuestionOverlay, } from '../liveQuestionStore.js';
|
|
6
7
|
import { hostLog } from '../host.js';
|
|
@@ -45,11 +46,14 @@ export function isGateStandingErrorCode(code, retriable) {
|
|
|
45
46
|
return (code === RESUME_POLICY_FOLD_CODE ||
|
|
46
47
|
code === 'corrupt' ||
|
|
47
48
|
(isRefusedParkCode(code) && retriable === true) ||
|
|
49
|
+
(typeof code === 'string' && RESUME_REOPEN_CODES.includes(code) && retriable === true) ||
|
|
48
50
|
code === DECIDE_WORKFLOW_PARKS_UNREADABLE ||
|
|
49
51
|
code === DECIDE_WORKFLOW_PARK_FORKED);
|
|
50
52
|
}
|
|
51
53
|
export function isCodeClassifiedGateFailure(code, retriable) {
|
|
52
|
-
return isGateStandingErrorCode(code, retriable) ||
|
|
54
|
+
return (isGateStandingErrorCode(code, retriable) ||
|
|
55
|
+
code === PARKED_RESUME_STARTUP_FAILED ||
|
|
56
|
+
(typeof code === 'string' && (RESUME_RETRY_LATER_CODES.includes(code) || RESUME_REFUSAL_CODES.includes(code))));
|
|
53
57
|
}
|
|
54
58
|
export function toAnsweredOutput(questions, answer) {
|
|
55
59
|
const answers = {};
|
|
@@ -189,7 +193,7 @@ async function surfaceParkGate(park, ctx, gatedCallId, onPresented) {
|
|
|
189
193
|
...(onPresented ? { onPresented } : {}),
|
|
190
194
|
...(deps.onDecideOperation ? { onDecideOperation: deps.onDecideOperation } : {}),
|
|
191
195
|
...(decidedByReading !== undefined ? { approvalDecidedBy: decidedByReading } : {}),
|
|
192
|
-
}, taskId, argsByCallOf(led), ctx.signal, gatedCallId);
|
|
196
|
+
}, taskId, argsByCallOf(led), ctx.signal, gatedCallId, park.toolName);
|
|
193
197
|
const outcomeDenied = 'denied' in outcome ? outcome.denied : undefined;
|
|
194
198
|
if (outcome.kind === 'decided' && outcomeDenied === true && outcome.gatedCallId) {
|
|
195
199
|
const denySettledBy = 'denySettledBy' in outcome ? outcome.denySettledBy : undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ApprovalSettledHow } from './
|
|
1
|
+
import { type ApprovalSettledHow } from './approvalHolds.js';
|
|
2
2
|
import { type ApprovalsListEnvelope, type CrashConvergedRow } from './crashConverged.js';
|
|
3
3
|
export type ReplayedApprovalDisposition = {
|
|
4
4
|
readonly kind: 'live';
|
|
@@ -20,9 +20,8 @@ export interface ReplayPendingBasis {
|
|
|
20
20
|
} | {
|
|
21
21
|
readonly read: 'failed';
|
|
22
22
|
};
|
|
23
|
-
readonly settled?: ReadonlyMap<string, ApprovalSettledHow>;
|
|
24
23
|
}
|
|
25
|
-
export declare function settledApprovalDisposition(frame: object
|
|
24
|
+
export declare function settledApprovalDisposition(frame: object): ReplayedApprovalDisposition | undefined;
|
|
26
25
|
export declare function replayedApprovalDisposition(frame: object, basis: ReplayPendingBasis): ReplayedApprovalDisposition;
|
|
27
26
|
export declare function replayedApprovalClosesCardFrame(disposition: ReplayedApprovalDisposition | null | undefined): boolean;
|
|
28
27
|
export declare function replayedApprovalSentence(disposition: ReplayedApprovalDisposition | undefined, opts?: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hasLedgerPositionKey } from './gateLedger.js';
|
|
2
|
+
import { anyApprovalSettled, settledApprovalOf } from './approvalHolds.js';
|
|
2
3
|
import { readLivePendingRows } from './livePendingAsk.js';
|
|
3
4
|
import { projectCrashConverged } from './crashConverged.js';
|
|
4
5
|
import { quoteUntrustedForSentence } from '../displayUntrusted.js';
|
|
@@ -23,15 +24,12 @@ function crashConvergedFactsOf(body, approvalId) {
|
|
|
23
24
|
}
|
|
24
25
|
return undefined;
|
|
25
26
|
}
|
|
26
|
-
export function settledApprovalDisposition(frame
|
|
27
|
+
export function settledApprovalDisposition(frame) {
|
|
27
28
|
try {
|
|
28
|
-
if (
|
|
29
|
+
if (!anyApprovalSettled())
|
|
29
30
|
return undefined;
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
return undefined;
|
|
33
|
-
const how = settled.get(id);
|
|
34
|
-
return typeof how === 'string' && APPROVAL_SETTLED_HOWS.includes(how) ? decidedSettled(how) : undefined;
|
|
31
|
+
const entry = settledApprovalOf(approvalIdOf(frame));
|
|
32
|
+
return entry === undefined ? undefined : decidedSettled(entry.how);
|
|
35
33
|
}
|
|
36
34
|
catch {
|
|
37
35
|
return undefined;
|
|
@@ -48,14 +46,7 @@ export function replayedApprovalDisposition(frame, basis) {
|
|
|
48
46
|
catch {
|
|
49
47
|
return unknown('unreadable_frame');
|
|
50
48
|
}
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
settledBasis = typeof basis === 'object' && basis !== null ? basis.settled : undefined;
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
settledBasis = undefined;
|
|
57
|
-
}
|
|
58
|
-
const early = settledApprovalDisposition(frame, settledBasis);
|
|
49
|
+
const early = settledApprovalDisposition(frame);
|
|
59
50
|
if (early !== undefined)
|
|
60
51
|
return early;
|
|
61
52
|
try {
|
|
@@ -15,7 +15,6 @@ export interface SessionPolicyDeliverability {
|
|
|
15
15
|
export interface SessionPolicyDeliverableOptions {
|
|
16
16
|
readonly roster?: ToolRosterView;
|
|
17
17
|
}
|
|
18
|
-
export { isEngineRefusedToolName } from '../engineRefusedToolName.js';
|
|
19
18
|
export declare function sessionPolicyDeliverable(behavior: 'deny' | 'ask', rules: readonly string[], opts?: SessionPolicyDeliverableOptions): SessionPolicyDeliverability;
|
|
20
19
|
export declare function sessionPolicyWithheldNotice(why: SessionPolicyWithheldWhy): string;
|
|
21
20
|
export declare function legacyToolNameFailureNoteOf(code: string | undefined): string | undefined;
|
|
@@ -3,10 +3,8 @@ import { rosterMountedNames } from '../rosterMountedNames.js';
|
|
|
3
3
|
import { ruleCompileVerdict } from '../ruleCompileVerdict.js';
|
|
4
4
|
import { ruleToolNameVerdictOf } from '../protocolSegment.js';
|
|
5
5
|
import { PREFIXES_IN_PROSE, REFUSED_NAME_CLASSES, REFUSED_NAME_FIX, RULES_LEGACY_TOOL_NAME_WRITE_NOTE } from './refusedToolNameProse.js';
|
|
6
|
-
import { CORE_PROTOCOL_PREFIXES
|
|
7
|
-
import { isEngineRefusedToolName } from '../engineRefusedToolName.js';
|
|
6
|
+
import { CORE_PROTOCOL_PREFIXES } from '../generated/toolNameTables.js';
|
|
8
7
|
const COVERING_NAMESPACE_PREFIXES = CORE_PROTOCOL_PREFIXES;
|
|
9
|
-
const ENGINE_RETIRED_TOOL_NAMES = CORE_RETIRED_TOOL_CURRENT_NAMES;
|
|
10
8
|
const WITHHELD_NOTICE = {
|
|
11
9
|
ask_no_bucket: 'Not written to this session’s rule record: that record only holds rules that block outright, and this rule asks before running instead — recording it as a block would change what it means.',
|
|
12
10
|
qualified_deny: 'Not written to this session’s rule record: that record holds whole tool names and command names only, and this rule has a part in parentheses it cannot carry — recording just the name could block more than this rule does.',
|
|
@@ -37,11 +35,8 @@ function withheldWhyOf(rule) {
|
|
|
37
35
|
}
|
|
38
36
|
if (rule.trim() !== rule)
|
|
39
37
|
return 'not_a_tool_name';
|
|
40
|
-
if (isEngineRefusedToolName(rule))
|
|
41
|
-
return 'legacy_tool_name';
|
|
42
38
|
return undefined;
|
|
43
39
|
}
|
|
44
|
-
export { isEngineRefusedToolName } from '../engineRefusedToolName.js';
|
|
45
40
|
function suppliedRosterNames(opts) {
|
|
46
41
|
if (opts === undefined || opts === null)
|
|
47
42
|
return 'absent';
|
|
@@ -95,29 +90,32 @@ export function sessionPolicyDeliverable(behavior, rules, opts) {
|
|
|
95
90
|
continue;
|
|
96
91
|
}
|
|
97
92
|
let why = withheldWhyOf(r);
|
|
93
|
+
let currentName;
|
|
98
94
|
if (why === undefined) {
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
95
|
+
const verdict = ruleToolNameVerdictOf(r);
|
|
96
|
+
if (verdict.kind === 'unknown')
|
|
101
97
|
return unreadable();
|
|
102
|
-
if (
|
|
98
|
+
if (verdict.kind === 'retired' || verdict.kind === 'unprefixed_namespace') {
|
|
99
|
+
why = 'legacy_tool_name';
|
|
100
|
+
if (verdict.kind === 'retired')
|
|
101
|
+
currentName = verdict.currentName;
|
|
102
|
+
}
|
|
103
|
+
else if (verdict.kind === 'unmintable_segment')
|
|
103
104
|
why = 'not_a_tool_name';
|
|
104
105
|
}
|
|
105
|
-
if (why === undefined
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
106
|
+
if (why === undefined) {
|
|
107
|
+
const grammar = ruleCompileVerdict(r, 'deny').kind;
|
|
108
|
+
if (grammar === 'unknown')
|
|
108
109
|
return unreadable();
|
|
109
|
-
if (
|
|
110
|
+
if (grammar === 'refused')
|
|
110
111
|
why = 'not_a_tool_name';
|
|
111
|
-
else if (verdict.kind === 'retired' || verdict.kind === 'unprefixed_namespace')
|
|
112
|
-
why = 'legacy_tool_name';
|
|
113
112
|
}
|
|
114
113
|
if (why === undefined && mounted !== undefined && !mounted.has(r))
|
|
115
114
|
why = 'not_in_roster';
|
|
116
115
|
if (why === undefined)
|
|
117
116
|
exact.push(r);
|
|
118
117
|
else {
|
|
119
|
-
|
|
120
|
-
withheld.push(typeof currentName === 'string' ? { rule: r, why, currentName } : { rule: r, why });
|
|
118
|
+
withheld.push(why === 'legacy_tool_name' && currentName !== undefined ? { rule: r, why, currentName } : { rule: r, why });
|
|
121
119
|
}
|
|
122
120
|
}
|
|
123
121
|
if (withheld.length > 0 || exact.length === 0)
|