@sema-agent/client-core 0.95.0 → 0.96.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 +180 -0
- package/README.md +49 -25
- 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 -0
- package/dist/adapter/activeRunSelfHeal.js +30 -4
- package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
- package/dist/adapter/downstream/terminalToSdkResult.js +8 -9
- package/dist/adapter/runStream.js +30 -47
- package/dist/agentSession/engineAgentRegistryRead.js +5 -4
- package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
- package/dist/agentsWireCaps.js +13 -2
- package/dist/callerCwdCapability.d.ts +0 -4
- package/dist/callerCwdCapability.js +0 -6
- package/dist/centerWiringCapability.d.ts +0 -4
- package/dist/centerWiringCapability.js +0 -6
- package/dist/classifierVerdictWire.js +4 -16
- package/dist/clientSlice.js +1 -1
- package/dist/cloudConfigWireCaps.d.ts +3 -3
- package/dist/cloudConfigWireCaps.js +65 -45
- 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/displayUntrusted.d.ts +7 -3
- package/dist/displayUntrusted.js +356 -60
- package/dist/engineCapsCache.d.ts +6 -0
- package/dist/engineCapsCache.js +226 -32
- package/dist/engineDirectory.d.ts +79 -0
- package/dist/engineDirectory.js +186 -0
- package/dist/engineErrorCodes.d.ts +14 -1
- package/dist/engineErrorCodes.js +37 -15
- package/dist/engineNoticeCodes.d.ts +17 -0
- package/dist/engineNoticeCodes.js +57 -3
- package/dist/engineWordRenames.d.ts +8 -0
- package/dist/engineWordRenames.js +13 -0
- package/dist/fileHistoryCaptureCapability.d.ts +14 -0
- package/dist/fileHistoryCaptureCapability.js +70 -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 +103 -89
- 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 +58 -1
- package/dist/gateVocabulary.d.ts +7 -2
- package/dist/gateVocabulary.js +5 -1
- 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/settingsSchemaFns.d.ts +3 -0
- package/dist/generated/settingsSchemaFns.js +53 -0
- package/dist/generated/toolNameTables.d.ts +1 -0
- package/dist/generated/toolNameTables.js +1 -0
- package/dist/hitl/approvalEndingCause.d.ts +2 -0
- package/dist/hitl/approvalEndingCause.js +31 -21
- package/dist/hitl/askParkRowRouting.js +1 -1
- package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
- package/dist/hitl/automaticAnswerVerdict.js +13 -8
- package/dist/hitl/decisionConflict.js +0 -2
- package/dist/hitl/decisionRefusal.d.ts +8 -0
- package/dist/hitl/decisionRefusal.js +48 -14
- package/dist/hitl/frameRouter.d.ts +0 -1
- package/dist/hitl/frameRouter.js +6 -14
- package/dist/hitl/hitlBridge.d.ts +6 -2
- package/dist/hitl/hitlBridge.js +28 -7
- 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 +8 -54
- 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 +1 -0
- package/dist/hitl/replayedApproval.js +14 -0
- package/dist/hitl/sessionPolicyDeliverable.js +8 -6
- package/dist/hitl/standingRows.d.ts +18 -0
- package/dist/hitl/standingRows.js +127 -0
- package/dist/hitl/toolApprovalWire.d.ts +15 -3
- package/dist/hitl/toolApprovalWire.js +238 -25
- 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 +21 -9
- package/dist/index.js +17 -8
- package/dist/mcpProbeCapability.d.ts +0 -4
- package/dist/mcpProbeCapability.js +0 -6
- package/dist/memoryComplianceCapability.d.ts +0 -4
- package/dist/memoryComplianceCapability.js +0 -6
- package/dist/memoryOriginCapability.d.ts +0 -4
- package/dist/memoryOriginCapability.js +0 -6
- package/dist/memorySpecWire.js +2 -2
- package/dist/modelIdentityResolvability.d.ts +2 -2
- package/dist/modelIdentityResolvability.js +12 -3
- package/dist/noticePresentation.d.ts +68 -0
- package/dist/noticePresentation.js +247 -0
- package/dist/outputStyleSeatCapability.d.ts +0 -1
- package/dist/outputStyleSeatCapability.js +0 -3
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +18 -0
- package/dist/peerFrames.js +13 -9
- package/dist/permissionModesCapability.d.ts +0 -4
- package/dist/permissionModesCapability.js +0 -6
- package/dist/permissionRuleIssue.js +0 -3
- package/dist/permissionsDeclaration.d.ts +2 -0
- package/dist/permissionsDeclaration.js +56 -41
- 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/resumeRefusalCopy.js +5 -21
- package/dist/retryStatus.d.ts +9 -1
- package/dist/retryStatus.js +9 -2
- package/dist/rewindArchiveCapability.d.ts +3 -13
- package/dist/rewindArchiveCapability.js +7 -58
- package/dist/rewindArchiveReading.d.ts +15 -0
- package/dist/rewindArchiveReading.js +56 -0
- package/dist/ruleCompileVerdict.d.ts +9 -1
- package/dist/ruleCompileVerdict.js +29 -4
- package/dist/runTerminal.d.ts +15 -1
- package/dist/runTerminal.js +56 -8
- package/dist/sandboxWire.js +13 -0
- package/dist/sealedKeyCapability.d.ts +0 -4
- package/dist/sealedKeyCapability.js +0 -6
- package/dist/seam.js +4 -2
- package/dist/seatContract.d.ts +73 -11
- package/dist/seatContract.js +195 -14
- package/dist/sessionReadRedactionCapability.d.ts +0 -4
- package/dist/sessionReadRedactionCapability.js +0 -6
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +66 -0
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
- package/dist/sessionSyncFileHistoryCapability.js +0 -3
- package/dist/skillToolListsCapability.d.ts +0 -1
- package/dist/skillToolListsCapability.js +0 -3
- package/dist/steerPriorityCapability.d.ts +0 -1
- package/dist/steerPriorityCapability.js +0 -3
- package/dist/storePostureCapability.d.ts +0 -4
- package/dist/storePostureCapability.js +0 -6
- 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/toolHistoryMismatch.d.ts +0 -3
- package/dist/toolHistoryMismatch.js +3 -7
- package/dist/toolResult.d.ts +1 -1
- package/dist/toolResult.js +2 -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 +0 -1
- package/dist/userInvokedSkillsCapability.js +0 -3
- package/dist/wireErrorTriage.d.ts +2 -0
- package/dist/wireErrorTriage.js +34 -5
- package/dist/wireFailureShape.d.ts +19 -2
- package/dist/wireFailureShape.js +55 -50
- package/docs/INTEGRATION-CLIENTS.md +1262 -17
- package/package.json +5 -5
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export type NoAllowCause = 'no_allow_rule' | 'ask_rule' | 'budget' | 'other';
|
|
1
|
+
export type NoAllowCause = 'no_allow_rule' | 'ask_rule' | 'engine_ask_rule' | 'budget' | 'other';
|
|
2
2
|
export interface RuleLadderNoAllowFacts {
|
|
3
3
|
readonly allowed?: boolean;
|
|
4
4
|
readonly denied?: boolean;
|
|
5
5
|
readonly askRuleMatched?: boolean;
|
|
6
6
|
readonly budgetExhausted?: boolean;
|
|
7
7
|
readonly noRuleMatched?: boolean;
|
|
8
|
+
readonly noAskRuleMatched?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare function noAllowCauseOf(card: object | null | undefined, ladder: RuleLadderNoAllowFacts | null | undefined): NoAllowCause | undefined;
|
|
@@ -18,8 +18,9 @@ export function noAllowCauseOf(card, ladder) {
|
|
|
18
18
|
if (ladderSays(ladder, 'budgetExhausted'))
|
|
19
19
|
return 'budget';
|
|
20
20
|
const standing = automaticAnswerVerdict(card, 'standing_rule');
|
|
21
|
-
if (standing.kind === 'must_ask' && (standing.askClass === 'ask_rule' || standing.origin === 'ask_rule'))
|
|
22
|
-
return 'ask_rule';
|
|
21
|
+
if (standing.kind === 'must_ask' && (standing.askClass === 'ask_rule' || standing.origin === 'ask_rule')) {
|
|
22
|
+
return ladderSays(ladder, 'noAskRuleMatched') || ladderSays(ladder, 'noRuleMatched') ? 'engine_ask_rule' : 'ask_rule';
|
|
23
|
+
}
|
|
23
24
|
if (ladderSays(ladder, 'noRuleMatched') && standing.kind === 'may_answer')
|
|
24
25
|
return 'no_allow_rule';
|
|
25
26
|
return 'other';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { putOwnKey, readOwnDataValue } from '../ownKey.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { isHitlSafetyErrorLike } from './parkOwnership.js';
|
|
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';
|
|
4
|
+
import { readDecisionRefusalAsk } from './decisionRefusal.js';
|
|
6
5
|
import { publishQuestionFrame, registerLocalQuestionResponder, hasQuestionOverlay, } from '../liveQuestionStore.js';
|
|
7
6
|
import { hostLog } from '../host.js';
|
|
8
7
|
import { surfaceFsApprovalAndDecide } from './toolApprovalWire.js';
|
|
@@ -35,62 +34,17 @@ function alreadyResolvedReasonToken(reason) {
|
|
|
35
34
|
}
|
|
36
35
|
export function isAlreadyResolvedFailure(failure) {
|
|
37
36
|
try {
|
|
38
|
-
|
|
37
|
+
const r = readDecisionRefusalAsk(failure);
|
|
38
|
+
return r.reading === 'settled' || (r.reading === 'not_settled' && (r.gateMoved || r.wordingHint));
|
|
39
39
|
}
|
|
40
40
|
catch {
|
|
41
41
|
return false;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
const ALREADY_RESOLVED_TYPED_ERROR_NAMES = Object.freeze([ApprovalStaleError.name, NotFoundError.name]);
|
|
45
|
-
const PARKED_RESUME_STARTUP_TYPED_ERROR_NAME = ParkedResumeStartupError.name;
|
|
46
|
-
function decideFailureFactsOf(failure) {
|
|
47
|
-
if (typeof failure !== 'object' || failure === null)
|
|
48
|
-
return undefined;
|
|
49
|
-
const o = failure;
|
|
50
|
-
const ec = o.errorCode;
|
|
51
|
-
const errorCode = typeof ec === 'string' && ec.length > 0 ? ec : undefined;
|
|
52
|
-
const retriable = refusalSaysStillPending(failure);
|
|
53
|
-
if (Object.hasOwn(failure, 'kind') && o.kind === 'failed') {
|
|
54
|
-
const safety = isGateFailureCode(o.safetyCode) ? o.safetyCode : undefined;
|
|
55
|
-
const code = isGateFailureCode(o.code) ? o.code : safety;
|
|
56
|
-
return { code, safetySignal: safety !== undefined, errorCode, retriable, typedErrorName: undefined, reason: o.reason };
|
|
57
|
-
}
|
|
58
|
-
const name = o.name;
|
|
59
|
-
return {
|
|
60
|
-
code: isGateFailureCode(o.code) ? o.code : undefined,
|
|
61
|
-
safetySignal: isHitlSafetyErrorLike(failure),
|
|
62
|
-
errorCode,
|
|
63
|
-
retriable,
|
|
64
|
-
typedErrorName: typeof name === 'string' ? name : undefined,
|
|
65
|
-
reason: String(failure),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function alreadyResolvedFailureVerdict(failure) {
|
|
69
|
-
const f = decideFailureFactsOf(failure);
|
|
70
|
-
if (f === undefined)
|
|
71
|
-
return false;
|
|
72
|
-
if (f.code !== undefined)
|
|
73
|
-
return f.code === 'no_pending';
|
|
74
|
-
if (f.safetySignal)
|
|
75
|
-
return false;
|
|
76
|
-
if (isDecideAlreadyResolvedCode(f.errorCode))
|
|
77
|
-
return true;
|
|
78
|
-
if (f.typedErrorName !== undefined && ALREADY_RESOLVED_TYPED_ERROR_NAMES.includes(f.typedErrorName))
|
|
79
|
-
return true;
|
|
80
|
-
if (f.typedErrorName === PARKED_RESUME_STARTUP_TYPED_ERROR_NAME && !isDecideParkMovedCode(f.errorCode))
|
|
81
|
-
return false;
|
|
82
|
-
if (isCodeClassifiedGateFailure(f.errorCode, f.retriable))
|
|
83
|
-
return false;
|
|
84
|
-
if (isDecideParkMovedCode(f.errorCode))
|
|
85
|
-
return true;
|
|
86
|
-
if (f.errorCode === ASK_GONE)
|
|
87
|
-
return true;
|
|
88
|
-
return isAlreadyResolvedGateReason(f.reason);
|
|
89
|
-
}
|
|
90
44
|
export function isGateStandingErrorCode(code, retriable) {
|
|
91
45
|
return (code === RESUME_POLICY_FOLD_CODE ||
|
|
92
46
|
code === 'corrupt' ||
|
|
93
|
-
(code
|
|
47
|
+
(isRefusedParkCode(code) && retriable === true) ||
|
|
94
48
|
code === DECIDE_WORKFLOW_PARKS_UNREADABLE ||
|
|
95
49
|
code === DECIDE_WORKFLOW_PARK_FORKED);
|
|
96
50
|
}
|
|
@@ -193,7 +147,7 @@ async function surfaceGateAndDecide(deps, taskId, askArgsByCall, signal, parkGat
|
|
|
193
147
|
catch (e) {
|
|
194
148
|
const code = hitlSafetyCodeOf(e);
|
|
195
149
|
const currentPending = readDecideCurrentPending(e);
|
|
196
|
-
const
|
|
150
|
+
const wireCodes = readWireCodes(e);
|
|
197
151
|
const wireRetriable = typeof e === 'object' && e !== null && refusalSaysStillPending(e);
|
|
198
152
|
const failureTexts = wireFailureTextsOf(e);
|
|
199
153
|
hostLog('debug', `liveHitlAskWire: decide failed: ${failureTexts.log}`);
|
|
@@ -205,7 +159,7 @@ async function surfaceGateAndDecide(deps, taskId, askArgsByCall, signal, parkGat
|
|
|
205
159
|
...(code !== undefined ? { code } : {}),
|
|
206
160
|
...(thrownIsInstanceOf(e, DecideTransportRetryExhaustedError) ? { retryExhausted: true } : {}),
|
|
207
161
|
...(currentPending !== undefined ? { currentPending } : {}),
|
|
208
|
-
...
|
|
162
|
+
...wireCodes,
|
|
209
163
|
...(wireRetriable ? { retriable: true } : {}),
|
|
210
164
|
};
|
|
211
165
|
}
|
|
@@ -35,5 +35,6 @@ export interface ParkRowBirthWaitDeps<Row> {
|
|
|
35
35
|
now?: () => number;
|
|
36
36
|
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
37
37
|
signal?: AbortSignal;
|
|
38
|
+
onFailure?: (log: string) => void;
|
|
38
39
|
}
|
|
39
40
|
export declare function waitForParkRowBirth<Row>(deps: ParkRowBirthWaitDeps<Row>): Promise<ParkRowWaitVerdict<Row>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { abortableSleep } from '../abortableSleep.js';
|
|
2
|
-
import {
|
|
2
|
+
import { reasonOfThrownWithSink } from '../hostCallbackGuard.js';
|
|
3
3
|
function parkRowPollDelay(ms, signal) {
|
|
4
4
|
return abortableSleep(ms, signal ?? new AbortController().signal);
|
|
5
5
|
}
|
|
@@ -17,7 +17,7 @@ export async function waitForParkRowBirth(deps) {
|
|
|
17
17
|
return await deps.probe(attempt, signal);
|
|
18
18
|
}
|
|
19
19
|
catch (e) {
|
|
20
|
-
return { kind: 'unborn', reason: `probe threw: ${
|
|
20
|
+
return { kind: 'unborn', reason: `probe threw: ${reasonOfThrownWithSink(e, (log) => deps.onFailure?.(log))}` };
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
const probeWithinRemaining = async (attempt, remainingMs) => {
|
|
@@ -13,7 +13,7 @@ import { denyReasonForWire, isPlanReviewModeAfter } from './hitlBridge.js';
|
|
|
13
13
|
import { planReviewQuestionId, REOPEN_ID_TAIL, taskIdFromPlanReviewQuestionId } from './gateIdentity.js';
|
|
14
14
|
import { notePlanReviewAnswered, notePlanReviewAnsweredFor, planReviewArmedKeyFor, registerArmedGateFor, waitForGateArmedFor, wasGateArmedFor, } from './armedGateRegistry.js';
|
|
15
15
|
import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
16
|
-
import { PLAN_REVIEW_GATE_KIND } from '../adapter/activeRunSelfHeal.js';
|
|
16
|
+
import { PLAN_REVIEW_GATE_KIND, durableDecideLegOf } from '../adapter/activeRunSelfHeal.js';
|
|
17
17
|
import { readRunTerminal, runTerminalGateKind } from '../runTerminal.js';
|
|
18
18
|
const PLAN_REVIEW_RESUME_TIMEOUT_MS = 6 * 60 * 60_000;
|
|
19
19
|
export const PLAN_REVIEW_APPROVE_LABEL = 'Yes, approve and run the plan';
|
|
@@ -130,6 +130,18 @@ function pausedCheckpointIdOf(carrier) {
|
|
|
130
130
|
return undefined;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
+
function pausedGateKindOf(carrier) {
|
|
134
|
+
try {
|
|
135
|
+
const read = readRunTerminal(carrier);
|
|
136
|
+
if (read === null || read.kind !== 'paused')
|
|
137
|
+
return undefined;
|
|
138
|
+
const kind = runTerminalGateKind(read);
|
|
139
|
+
return typeof kind === 'string' && kind.length > 0 ? kind : undefined;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
133
145
|
const armedPlanReviewTaskIds = new Set();
|
|
134
146
|
const offerModeAfterByTask = new Map();
|
|
135
147
|
export function _resetArmedPlanReviewsForTest() {
|
|
@@ -470,7 +482,53 @@ export function __resetPlanReviewDecisionLatchForTests() {
|
|
|
470
482
|
planReviewDecisionOps.length = 0;
|
|
471
483
|
}
|
|
472
484
|
export async function decidePlanReview(taskId, decision, permissionModeAfter, opts) {
|
|
473
|
-
return decidePlanReviewFor(taskId, decision, permissionModeAfter, opts,
|
|
485
|
+
return decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, parkedGateIdentityOf(opts));
|
|
486
|
+
}
|
|
487
|
+
function parkedGateIdentityOf(opts) {
|
|
488
|
+
try {
|
|
489
|
+
return opts !== null && typeof opts === 'object' ? pausedCheckpointIdOf(opts.parkedResult) : undefined;
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
return undefined;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function planReviewSettledVerdict(r) {
|
|
496
|
+
const status = r.postStatus ?? r.bodyStatus;
|
|
497
|
+
const gateMoved = r.gateBefore !== undefined && r.gateAfter !== undefined && r.gateAfter !== r.gateBefore;
|
|
498
|
+
if (r.reparked)
|
|
499
|
+
return status !== 'completed' && !gateMoved ? { effect: 'still_parked', proven: true } : { effect: 'unconfirmed', proven: false };
|
|
500
|
+
if (status === 'completed')
|
|
501
|
+
return { effect: 'took_effect', proven: false };
|
|
502
|
+
const newGateHasCard = () => {
|
|
503
|
+
const leg = durableDecideLegOf({ gateKind: r.gateKindAfter ?? null });
|
|
504
|
+
return leg === 'approval' || leg === 'plan_review';
|
|
505
|
+
};
|
|
506
|
+
if (status === 'suspended' && r.postStatus === 'suspended' && newGateHasCard())
|
|
507
|
+
return { effect: 'advanced', proven: false };
|
|
508
|
+
if (status === 'needs_review' && r.postStatus === 'needs_review' && r.gateBefore !== undefined && r.gateAfter !== undefined) {
|
|
509
|
+
if (r.gateAfter === r.gateBefore)
|
|
510
|
+
return { effect: 'still_parked', proven: true };
|
|
511
|
+
if (newGateHasCard())
|
|
512
|
+
return { effect: 'advanced', proven: false };
|
|
513
|
+
}
|
|
514
|
+
return { effect: 'unconfirmed', proven: false };
|
|
515
|
+
}
|
|
516
|
+
function bodyWordOf(body, key) {
|
|
517
|
+
try {
|
|
518
|
+
const v = body !== null && typeof body === 'object' ? body[key] : undefined;
|
|
519
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
return undefined;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
function bodySaysReparked(body) {
|
|
526
|
+
try {
|
|
527
|
+
return body !== null && typeof body === 'object' && body.retriable === true;
|
|
528
|
+
}
|
|
529
|
+
catch {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
474
532
|
}
|
|
475
533
|
async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, gateBefore) {
|
|
476
534
|
if (typeof taskId === 'string' && planReviewDecisionOps.some((op) => op.taskId === taskId && op.phase === 'posting')) {
|
|
@@ -586,6 +644,7 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
586
644
|
hostLog('debug', `planReviewWire: ${decision} → ok (dispatch #${dispatchNo}) ${JSON.stringify(body).slice(0, 200)}`);
|
|
587
645
|
let postStatus;
|
|
588
646
|
let gateAfter;
|
|
647
|
+
let gateKindAfter;
|
|
589
648
|
try {
|
|
590
649
|
const probe = clients.repull();
|
|
591
650
|
if (probe) {
|
|
@@ -601,35 +660,54 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
601
660
|
else {
|
|
602
661
|
post = (await probe.runs.get(taskId));
|
|
603
662
|
}
|
|
604
|
-
postStatus =
|
|
663
|
+
postStatus = bodyWordOf(post, 'status');
|
|
605
664
|
gateAfter = pausedCheckpointIdOf(post?.result);
|
|
665
|
+
gateKindAfter = pausedGateKindOf(post?.result);
|
|
606
666
|
}
|
|
607
667
|
}
|
|
608
668
|
catch (e) {
|
|
609
669
|
hostLog('debug', `planReviewWire: post-decide status re-pull failed (fail-soft): ${String(e)}`);
|
|
610
670
|
}
|
|
611
|
-
const
|
|
671
|
+
const bodyStatus = bodyWordOf(body, 'status');
|
|
672
|
+
const effective = postStatus ?? bodyStatus;
|
|
612
673
|
statusSeen = effective;
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
else if (effective === 'needs_review') {
|
|
619
|
-
effect = 'still_parked';
|
|
620
|
-
stillParkedProven = postStatus === 'needs_review' && gateBefore !== undefined && gateAfter !== undefined && gateAfter === gateBefore;
|
|
674
|
+
const verdict = planReviewSettledVerdict({ postStatus, bodyStatus, reparked: bodySaysReparked(body), gateBefore, gateAfter, gateKindAfter });
|
|
675
|
+
effect = verdict.effect;
|
|
676
|
+
stillParkedProven = verdict.proven;
|
|
677
|
+
const code = bodyWordOf(body, 'errorCode');
|
|
678
|
+
if (effect === 'still_parked' && postStatus === 'needs_review' && !bodySaysReparked(body)) {
|
|
621
679
|
outcome =
|
|
622
680
|
`The plan_review ${decision} returned HTTP 200 but the session is STILL locked on the same review gate ` +
|
|
623
681
|
`(post-decide status: needs_review). The decision did NOT take effect (known engine issue, RB-471 family). ` +
|
|
624
682
|
`Tell the user plainly that the ${decision} did not go through; the reliable exits today are approving the plan or cancelling the task.`;
|
|
625
683
|
}
|
|
626
|
-
else if (
|
|
627
|
-
|
|
628
|
-
|
|
684
|
+
else if (effect === 'still_parked') {
|
|
685
|
+
outcome =
|
|
686
|
+
`The plan_review ${decision} was NOT applied: the engine could not continue the task and put the plan back to wait for a decision` +
|
|
687
|
+
`${code !== undefined ? ` (engine code: ${code})` : ''}. Tell the user plainly that the ${decision} did not go through.`;
|
|
688
|
+
}
|
|
689
|
+
else if (effect === 'advanced') {
|
|
690
|
+
outcome = planReviewAdvancedOutcome(decision, effective === 'needs_review' ? 'needs_review' : 'suspended');
|
|
691
|
+
}
|
|
692
|
+
else if (effect === 'took_effect') {
|
|
693
|
+
outcome =
|
|
694
|
+
`The plan was ${decision === 'approve' ? 'approved and the parked task resumed to completion' : 'rejected (plan discarded)'} — final status: ${effective} ` +
|
|
695
|
+
`(${postStatus !== undefined ? 'post-decide re-checked: task left the review gate' : "from the decision's own reply; the post-decide re-check was unavailable"}).`;
|
|
696
|
+
}
|
|
697
|
+
else if (effective === 'needs_review' && (gateBefore === undefined || gateAfter === undefined || postStatus !== 'needs_review')) {
|
|
698
|
+
outcome =
|
|
699
|
+
`The plan_review ${decision} returned HTTP 200 and the task is waiting at a plan review gate again (post-decide status: needs_review), ` +
|
|
700
|
+
`but it could not be told whether this is the same review (the ${decision} did not take effect) or a new plan written after it (it did).`;
|
|
701
|
+
}
|
|
702
|
+
else if (effective === 'suspended' || effective === 'needs_review') {
|
|
703
|
+
outcome =
|
|
704
|
+
`The plan_review ${decision} was accepted by the engine (HTTP 200) and the task is paused again (post-decide status: ${effective}), ` +
|
|
705
|
+
`${gateKindAfter !== undefined ? `at a '${gateKindAfter}' pause that is not an approval card` : 'but the pause it stopped at was not reported'} — what the ${decision} led to could not be confirmed.`;
|
|
629
706
|
}
|
|
630
707
|
else if (effective !== undefined) {
|
|
631
|
-
|
|
632
|
-
|
|
708
|
+
outcome =
|
|
709
|
+
`The plan_review ${decision} was accepted by the engine (HTTP 200), but the task then reported status ${effective}` +
|
|
710
|
+
`${code !== undefined ? ` (engine code: ${code})` : ''} — not a completion; what the ${decision} led to could not be confirmed.`;
|
|
633
711
|
}
|
|
634
712
|
else {
|
|
635
713
|
outcome = `The plan_review ${decision} was accepted by the engine (HTTP 200) but its effect is unconfirmed — final status: unknown (post-decide verification unavailable). Do not treat this as ${decision === 'approve' ? 'an approval that resumed the task' : 'a discarded plan'}.`;
|
|
@@ -678,10 +756,10 @@ async function decidePlanReviewInner(taskId, decision, permissionModeAfter, disp
|
|
|
678
756
|
outcome = `This ${decision} was not applied. ${corruptStoredRowContent(where)}`;
|
|
679
757
|
}
|
|
680
758
|
else if (typeof status === 'number') {
|
|
681
|
-
const
|
|
682
|
-
hostLog('debug', `planReviewWire: ${decision} → ${status} ${
|
|
759
|
+
const failureTexts = wireFailureTextsOf(e);
|
|
760
|
+
hostLog('debug', `planReviewWire: ${decision} → ${status} ${failureTexts.log.slice(0, 200)}`);
|
|
683
761
|
effect = (status >= 400 && status < 500) || (typeof refusedCode === 'string' && isUnavailableFaceCode(refusedCode)) ? 'not_applied' : 'unconfirmed';
|
|
684
|
-
outcome = `${`The plan_review decision failed: HTTP ${status} ${
|
|
762
|
+
outcome = `${`The plan_review decision failed: HTTP ${status} ${failureTexts.reason}`.trim()}${decideFailureNote(e)}`;
|
|
685
763
|
}
|
|
686
764
|
else if (noAnswer === 'time-limit' || noAnswer === 'deadline') {
|
|
687
765
|
hostLog('debug', `planReviewWire: ${decision} sent but no answer within the request time limit (task ${taskId})`);
|
|
@@ -24,6 +24,7 @@ export interface ReplayPendingBasis {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function settledApprovalDisposition(frame: object, settled: ReplayPendingBasis['settled']): ReplayedApprovalDisposition | undefined;
|
|
26
26
|
export declare function replayedApprovalDisposition(frame: object, basis: ReplayPendingBasis): ReplayedApprovalDisposition;
|
|
27
|
+
export declare function replayedApprovalClosesCardFrame(disposition: ReplayedApprovalDisposition | null | undefined): boolean;
|
|
27
28
|
export declare function replayedApprovalSentence(disposition: ReplayedApprovalDisposition | undefined, opts?: {
|
|
28
29
|
readonly toolName?: string;
|
|
29
30
|
}): string | undefined;
|
|
@@ -2,6 +2,7 @@ import { APPROVAL_SETTLED_HOWS, hasLedgerPositionKey } from './gateLedger.js';
|
|
|
2
2
|
import { readLivePendingRows } from './livePendingAsk.js';
|
|
3
3
|
import { projectCrashConverged } from './crashConverged.js';
|
|
4
4
|
import { quoteUntrustedForSentence } from '../displayUntrusted.js';
|
|
5
|
+
import { readOwnDataValue } from '../ownKey.js';
|
|
5
6
|
const live = (basis) => Object.freeze({ kind: 'live', basis });
|
|
6
7
|
const unknown = (why) => Object.freeze({ kind: 'unknown', why });
|
|
7
8
|
const decided = (row) => Object.freeze(row === undefined
|
|
@@ -162,6 +163,19 @@ const SETTLED_PHRASE = Object.freeze({
|
|
|
162
163
|
});
|
|
163
164
|
const settledRepeat = (what, how) => `${sentenceInitial(what)} was ${SETTLED_PHRASE[how]} earlier, so this repeated copy of it was not raised as a new question and no decision was sent for it.`;
|
|
164
165
|
const decidedPlain = (what) => `${sentenceInitial(what)} is no longer listed by the engine as waiting for a decision, so no decision was sent for it.`;
|
|
166
|
+
export function replayedApprovalClosesCardFrame(disposition) {
|
|
167
|
+
try {
|
|
168
|
+
if (typeof disposition !== 'object' || disposition === null)
|
|
169
|
+
return false;
|
|
170
|
+
if (readOwnDataValue(disposition, 'kind') !== 'decided')
|
|
171
|
+
return false;
|
|
172
|
+
const cause = readOwnDataValue(disposition, 'cause');
|
|
173
|
+
return typeof cause === 'string' && Object.hasOwn(STOPPED_BY_CAUSE, cause);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
165
179
|
const unconfirmed = (what) => `Whether ${what} is still waiting for a decision could not be confirmed, so no decision was sent for it.`;
|
|
166
180
|
function guardedGet(o, key) {
|
|
167
181
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CONFIG_LEGACY_TOOL_NAME, RULES_LEGACY_TOOL_NAME } from '../engineErrorCodes.js';
|
|
2
2
|
import { rosterMountedNames } from '../rosterMountedNames.js';
|
|
3
3
|
import { ruleCompileVerdict } from '../ruleCompileVerdict.js';
|
|
4
|
-
import {
|
|
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
6
|
import { CORE_PROTOCOL_PREFIXES, CORE_RETIRED_TOOL_CURRENT_NAMES } from '../generated/toolNameTables.js';
|
|
7
7
|
import { isEngineRefusedToolName } from '../engineRefusedToolName.js';
|
|
@@ -96,18 +96,20 @@ export function sessionPolicyDeliverable(behavior, rules, opts) {
|
|
|
96
96
|
}
|
|
97
97
|
let why = withheldWhyOf(r);
|
|
98
98
|
if (why === undefined) {
|
|
99
|
-
const grammar = ruleCompileVerdict(r, 'deny');
|
|
99
|
+
const grammar = ruleCompileVerdict(r, 'deny').kind;
|
|
100
100
|
if (grammar === 'unknown')
|
|
101
101
|
return unreadable();
|
|
102
102
|
if (grammar === 'refused')
|
|
103
103
|
why = 'not_a_tool_name';
|
|
104
104
|
}
|
|
105
105
|
if (why === undefined && COVERING_NAMESPACE_PREFIXES.some((p) => r.startsWith(p))) {
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
why = 'not_a_tool_name';
|
|
109
|
-
else if (segment.kind === 'unknown')
|
|
106
|
+
const verdict = ruleToolNameVerdictOf(r);
|
|
107
|
+
if (verdict.kind === 'unknown')
|
|
110
108
|
return unreadable();
|
|
109
|
+
if (verdict.kind === 'unmintable_segment')
|
|
110
|
+
why = 'not_a_tool_name';
|
|
111
|
+
else if (verdict.kind === 'retired' || verdict.kind === 'unprefixed_namespace')
|
|
112
|
+
why = 'legacy_tool_name';
|
|
111
113
|
}
|
|
112
114
|
if (why === undefined && mounted !== undefined && !mounted.has(r))
|
|
113
115
|
why = 'not_in_roster';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type StandingRowWhy = 'given' | 'card_unreadable' | 'remember_refused' | 'remember_unreadable' | 'route_cannot_carry' | 'classes_unreadable' | 'not_deployment_list_question' | 'evidence_unreadable' | 'offers_unreadable' | 'engine_lane_closed' | 'args_unavailable' | 'grant_binding' | 'tool_name_unreadable' | 'rule_cannot_clear' | 'host_fact_missing' | 'face_not_generic' | 'rule_not_sent';
|
|
2
|
+
export type StandingPersistentRow = 'engine_offer' | 'local_whole_tool' | 'none';
|
|
3
|
+
export interface StandingRowsWhy {
|
|
4
|
+
readonly session: StandingRowWhy;
|
|
5
|
+
readonly persistent: StandingRowWhy;
|
|
6
|
+
readonly deploymentList: StandingRowWhy;
|
|
7
|
+
}
|
|
8
|
+
export interface StandingRows {
|
|
9
|
+
readonly sessionRow: boolean;
|
|
10
|
+
readonly persistentRow: StandingPersistentRow;
|
|
11
|
+
readonly deploymentListSessionRow: boolean;
|
|
12
|
+
readonly why: StandingRowsWhy;
|
|
13
|
+
}
|
|
14
|
+
export interface StandingRowsHostFacts {
|
|
15
|
+
readonly cardFace?: string;
|
|
16
|
+
readonly wholeToolRuleSent?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function standingRowsOf(card: object | null | undefined, host?: StandingRowsHostFacts | null): StandingRows;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { readAskClassPairState } from './askClassPair.js';
|
|
2
|
+
import { automaticAnswerVerdict } from './automaticAnswerVerdict.js';
|
|
3
|
+
import { readRuleOffers } from './toolApprovalWire.js';
|
|
4
|
+
const DEPLOYMENT_LIST_ASK_CLASSES = Object.freeze(['ask_rule']);
|
|
5
|
+
const UNREADABLE = Symbol('unreadable');
|
|
6
|
+
function ownData(v, key) {
|
|
7
|
+
try {
|
|
8
|
+
const d = Object.getOwnPropertyDescriptor(v, key);
|
|
9
|
+
return d !== undefined && 'value' in d ? d.value : undefined;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function hasKey(v, key) {
|
|
16
|
+
try {
|
|
17
|
+
return { inCard: key in v };
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return UNREADABLE;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function present(v, key) {
|
|
24
|
+
try {
|
|
25
|
+
const inCard = key in v;
|
|
26
|
+
return { inCard, value: inCard ? v[key] : undefined };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return UNREADABLE;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function freezeRows(sessionRow, persistentRow, deploymentListSessionRow, why) {
|
|
33
|
+
return Object.freeze({ sessionRow, persistentRow, deploymentListSessionRow, why: Object.freeze({ ...why }) });
|
|
34
|
+
}
|
|
35
|
+
function allClosed(why) {
|
|
36
|
+
return freezeRows(false, 'none', false, { session: why, persistent: why, deploymentList: why });
|
|
37
|
+
}
|
|
38
|
+
function persistentRowOf(card, host, evidenceUnreadable) {
|
|
39
|
+
if (evidenceUnreadable)
|
|
40
|
+
return { row: 'none', why: 'evidence_unreadable' };
|
|
41
|
+
for (const key of ['ruleOffers', 'ruleOffersReadOnly']) {
|
|
42
|
+
const p = hasKey(card, key);
|
|
43
|
+
if (p === UNREADABLE)
|
|
44
|
+
return UNREADABLE;
|
|
45
|
+
if (!p.inCard)
|
|
46
|
+
continue;
|
|
47
|
+
const offers = readRuleOffers(ownData(card, key));
|
|
48
|
+
if (offers === undefined || offers.length === 0)
|
|
49
|
+
return { row: 'none', why: 'offers_unreadable' };
|
|
50
|
+
return { row: 'engine_offer', why: 'given' };
|
|
51
|
+
}
|
|
52
|
+
const absence = present(card, 'ruleOffersAbsence');
|
|
53
|
+
if (absence === UNREADABLE)
|
|
54
|
+
return UNREADABLE;
|
|
55
|
+
if (absence.inCard)
|
|
56
|
+
return { row: 'none', why: 'engine_lane_closed' };
|
|
57
|
+
const blind = present(card, 'argsUnavailable');
|
|
58
|
+
if (blind === UNREADABLE)
|
|
59
|
+
return UNREADABLE;
|
|
60
|
+
if (blind.inCard)
|
|
61
|
+
return { row: 'none', why: 'args_unavailable' };
|
|
62
|
+
if (ownData(card, 'grantBinding') !== 'none')
|
|
63
|
+
return { row: 'none', why: 'grant_binding' };
|
|
64
|
+
const tool = ownData(card, 'toolName');
|
|
65
|
+
if (typeof tool !== 'string' || tool.length === 0)
|
|
66
|
+
return { row: 'none', why: 'tool_name_unreadable' };
|
|
67
|
+
if (automaticAnswerVerdict(card, 'standing_rule').kind !== 'may_answer')
|
|
68
|
+
return { row: 'none', why: 'rule_cannot_clear' };
|
|
69
|
+
if (typeof host !== 'object' || host === null)
|
|
70
|
+
return { row: 'none', why: 'host_fact_missing' };
|
|
71
|
+
const face = ownData(host, 'cardFace');
|
|
72
|
+
if (typeof face !== 'string')
|
|
73
|
+
return { row: 'none', why: 'host_fact_missing' };
|
|
74
|
+
if (face !== 'generic')
|
|
75
|
+
return { row: 'none', why: 'face_not_generic' };
|
|
76
|
+
const sent = ownData(host, 'wholeToolRuleSent');
|
|
77
|
+
if (typeof sent !== 'boolean')
|
|
78
|
+
return { row: 'none', why: 'host_fact_missing' };
|
|
79
|
+
if (!sent)
|
|
80
|
+
return { row: 'none', why: 'rule_not_sent' };
|
|
81
|
+
return { row: 'local_whole_tool', why: 'given' };
|
|
82
|
+
}
|
|
83
|
+
export function standingRowsOf(card, host) {
|
|
84
|
+
if (typeof card !== 'object' || card === null)
|
|
85
|
+
return allClosed('card_unreadable');
|
|
86
|
+
try {
|
|
87
|
+
const refused = present(card, 'rememberRefused');
|
|
88
|
+
if (refused === UNREADABLE)
|
|
89
|
+
return allClosed('card_unreadable');
|
|
90
|
+
if (refused.inCard)
|
|
91
|
+
return allClosed(refused.value === true ? 'remember_refused' : 'remember_unreadable');
|
|
92
|
+
const evidence = present(card, 'unreadableEvidence');
|
|
93
|
+
if (evidence === UNREADABLE)
|
|
94
|
+
return allClosed('card_unreadable');
|
|
95
|
+
let evidenceUnreadable = false;
|
|
96
|
+
if (evidence.inCard) {
|
|
97
|
+
const list = ownData(card, 'unreadableEvidence');
|
|
98
|
+
if (!Array.isArray(list) || !list.every((k) => typeof k === 'string'))
|
|
99
|
+
return allClosed('card_unreadable');
|
|
100
|
+
if (list.includes('rememberRefused'))
|
|
101
|
+
return allClosed('remember_unreadable');
|
|
102
|
+
evidenceUnreadable = list.length > 0;
|
|
103
|
+
}
|
|
104
|
+
const sessionRow = ownData(card, 'allowSessionCarried') === true;
|
|
105
|
+
const sessionWhy = sessionRow ? 'given' : 'route_cannot_carry';
|
|
106
|
+
let deploymentList;
|
|
107
|
+
if (!sessionRow) {
|
|
108
|
+
deploymentList = 'route_cannot_carry';
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const pair = readAskClassPairState(card);
|
|
112
|
+
deploymentList =
|
|
113
|
+
pair.state !== 'pair'
|
|
114
|
+
? 'classes_unreadable'
|
|
115
|
+
: pair.classes.every((c) => DEPLOYMENT_LIST_ASK_CLASSES.includes(c))
|
|
116
|
+
? 'given'
|
|
117
|
+
: 'not_deployment_list_question';
|
|
118
|
+
}
|
|
119
|
+
const persistent = persistentRowOf(card, host, evidenceUnreadable);
|
|
120
|
+
if (persistent === UNREADABLE)
|
|
121
|
+
return allClosed('card_unreadable');
|
|
122
|
+
return freezeRows(sessionRow, persistent.row, deploymentList === 'given', { session: sessionWhy, persistent: persistent.why, deploymentList });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return allClosed('card_unreadable');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -40,8 +40,9 @@ export type FsApprovalOutcome = {
|
|
|
40
40
|
stage: HitlFailureStage;
|
|
41
41
|
gatedCallId?: string | undefined;
|
|
42
42
|
reason: string;
|
|
43
|
-
code?: 'no_pending' | undefined;
|
|
43
|
+
code?: 'no_pending' | 'wrong_gate' | undefined;
|
|
44
44
|
errorCode?: string | undefined;
|
|
45
|
+
blockedBy?: string | undefined;
|
|
45
46
|
retriable?: true;
|
|
46
47
|
safetyCode?: HitlSafetyCode | undefined;
|
|
47
48
|
retryExhausted?: true;
|
|
@@ -68,7 +69,6 @@ export type DenialLimitKind = SdkDenialLimitKind;
|
|
|
68
69
|
export type DenialLimitFallback = SdkDenialLimitFallback;
|
|
69
70
|
export { RULE_OFFERS_ABSENCE_REASONS };
|
|
70
71
|
export declare const ASK_ORIGIN_WORDS: readonly string[];
|
|
71
|
-
export declare const APPROVAL_MANDATE_WORDS: readonly ["operator_always", "tool_marks", "probe_mandate", "probe_unanswered", "write_protection", "write_protection_unresolved"];
|
|
72
72
|
export type WireRuleOffer = {
|
|
73
73
|
kind: 'single';
|
|
74
74
|
rule: string;
|
|
@@ -141,6 +141,7 @@ export interface ApprovalCardRequest {
|
|
|
141
141
|
probeCause?: unknown;
|
|
142
142
|
probeReason?: string;
|
|
143
143
|
rememberRefused?: true;
|
|
144
|
+
allowSessionCarried?: true;
|
|
144
145
|
ruleEvidence?: unknown;
|
|
145
146
|
requiresRealApproval?: true;
|
|
146
147
|
irreversibleParkGate?: true;
|
|
@@ -157,6 +158,8 @@ export interface ApprovalCardRequest {
|
|
|
157
158
|
askClass?: string;
|
|
158
159
|
classes?: readonly string[];
|
|
159
160
|
boundGrants?: BoundSkillGrantsWire;
|
|
161
|
+
grantBinding?: ApprovalGrantBinding;
|
|
162
|
+
unreadableEvidence?: readonly string[];
|
|
160
163
|
classifierNoRuling?: string;
|
|
161
164
|
priorCardsForCall?: readonly ApprovalPriorCard[];
|
|
162
165
|
}
|
|
@@ -245,7 +248,7 @@ export declare function approvalIsMandated(v: ApprovalMandatedFacts | undefined
|
|
|
245
248
|
export declare function readApprovalMandate(v: {
|
|
246
249
|
readonly mandate?: string;
|
|
247
250
|
} | undefined | null): ApprovalMandateWord | undefined;
|
|
248
|
-
export declare function toolPermissionRequestAskBits(card: object | null | undefined): Pick<ToolPermissionRequest, 'mandated' | 'mandate' | 'origin' | 'ruleOffersAbsence' | 'askClass' | 'classes'>;
|
|
251
|
+
export declare function toolPermissionRequestAskBits(card: object | null | undefined): Pick<ToolPermissionRequest, 'mandated' | 'mandate' | 'origin' | 'ruleOffersAbsence' | 'askClass' | 'classes' | 'rememberRefused'>;
|
|
249
252
|
export declare function isFromSubagent(frame: ToolApprovalFrame): boolean;
|
|
250
253
|
export type ToolApprovalRespondDecision = 'allow' | 'allow_session' | 'deny';
|
|
251
254
|
export interface RespondToolApprovalOpts {
|
|
@@ -299,6 +302,12 @@ interface ToolApprovalRespondRefusalFields {
|
|
|
299
302
|
status?: number;
|
|
300
303
|
errorCode?: string;
|
|
301
304
|
message?: string;
|
|
305
|
+
retriable?: true;
|
|
306
|
+
extra?: {
|
|
307
|
+
readonly cause?: string;
|
|
308
|
+
readonly field?: string;
|
|
309
|
+
};
|
|
310
|
+
unreadable?: true;
|
|
302
311
|
}
|
|
303
312
|
export type ToolApprovalRespondRefusal = (ToolApprovalRespondRefusalFields & {
|
|
304
313
|
status: number;
|
|
@@ -312,6 +321,7 @@ export declare function isToolApprovalFrame(ev: unknown): ev is ToolApprovalFram
|
|
|
312
321
|
export declare function askProbeReasonDetail(card: Pick<ApprovalCardRequest, 'probeReason' | 'probeCause'> | null | undefined): string | undefined;
|
|
313
322
|
export declare function readApprovalRememberRefused(v: unknown): boolean;
|
|
314
323
|
export declare function readApprovalBoundGrants(v: unknown): BoundSkillGrantsWire | undefined;
|
|
324
|
+
export type ApprovalGrantBinding = 'bound' | 'none' | 'unreadable';
|
|
315
325
|
export declare function readApprovalClassifierNoRuling(v: unknown): string | undefined;
|
|
316
326
|
export declare function classifierNoRulingDetail(word: string | undefined): string;
|
|
317
327
|
export declare function approvalBoundGrantsDetail(grants: BoundSkillGrantsWire | null | undefined): string | undefined;
|
|
@@ -319,6 +329,8 @@ export declare function approvalPriorCardsDetail(card: Pick<ApprovalCardRequest,
|
|
|
319
329
|
export declare function readDenialLimitFallback(v: unknown): DenialLimitFallback | undefined;
|
|
320
330
|
export declare function readRuleOffers(v: unknown): RuleOffer[] | undefined;
|
|
321
331
|
export declare function readRuleOfferSupply(offers: unknown): RuleOffer[] | undefined;
|
|
332
|
+
export type ApprovalCardV1Facts = Pick<ApprovalCardRequest, 'toolName' | 'args'> & Pick<ApprovalCardRequest, 'toolCallId' | 'workerBadge' | 'wireNote' | 'argsUnavailable' | 'governanceForced' | 'delegation' | 'ruleOffersReadOnly' | 'inputHasBidi' | 'allowRuleShadow' | 'probeCause' | 'rememberRefused' | 'ruleEvidence' | 'requiresRealApproval' | 'ruleOffersAbsence' | 'denialLimitFallback' | 'askClass' | 'classes' | 'grantBinding' | 'unreadableEvidence'>;
|
|
333
|
+
export declare function approvalCardFactsOfV1(card: object | null | undefined): Readonly<ApprovalCardV1Facts> | undefined;
|
|
322
334
|
export interface ToolApprovalFrameLaneOpts {
|
|
323
335
|
approvalDecisionNoteCapable?: boolean;
|
|
324
336
|
respondFreeFormRulesCapable?: boolean;
|