@sema-agent/client-core 0.90.0 → 0.91.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 +193 -0
- package/README.md +24 -18
- package/dist/adapt/arms.js +9 -0
- package/dist/adapter/downstream/eventToSdkMessage.js +4 -2
- package/dist/adapter/downstream/wiringManifestView.d.ts +6 -0
- package/dist/adapter/downstream/wiringManifestView.js +16 -0
- package/dist/adapter/runStream.js +37 -20
- package/dist/askSurvivesStandingAnswer.d.ts +10 -0
- package/dist/askSurvivesStandingAnswer.js +40 -0
- package/dist/attachmentSeatCapability.d.ts +11 -0
- package/dist/attachmentSeatCapability.js +27 -0
- package/dist/attachmentsWireCaps.d.ts +9 -0
- package/dist/attachmentsWireCaps.js +74 -21
- package/dist/compensations.js +10 -14
- package/dist/controlRouter.d.ts +9 -2
- package/dist/controlRouter.js +66 -28
- package/dist/decideFailureNote.js +4 -2
- package/dist/disableSkillsWire.d.ts +1 -0
- package/dist/disableSkillsWire.js +8 -1
- package/dist/displayUntrusted.js +153 -4
- package/dist/engineCapsCache.d.ts +3 -1
- package/dist/engineCapsCache.js +56 -6
- package/dist/engineClosedSets.d.ts +2 -0
- package/dist/engineClosedSets.js +3 -0
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +10 -0
- package/dist/generated/engineFactTables.d.ts +12 -0
- package/dist/generated/engineFactTables.js +47 -0
- package/dist/hitl/askGateWire.d.ts +1 -1
- package/dist/hitl/askGateWire.js +1 -1
- package/dist/hitl/crashConverged.d.ts +7 -0
- package/dist/hitl/crashConverged.js +57 -0
- package/dist/hitl/crashConvergedNotice.d.ts +4 -0
- package/dist/hitl/crashConvergedNotice.js +57 -0
- package/dist/hitl/hitlBridge.d.ts +7 -4
- package/dist/hitl/parkResolver.d.ts +7 -2
- package/dist/hitl/parkResolver.js +19 -7
- package/dist/hitl/planReviewWire.d.ts +1 -1
- package/dist/hitl/planReviewWire.js +18 -4
- package/dist/hitl/sessionPolicyWire.d.ts +5 -0
- package/dist/hitl/sessionPolicyWire.js +63 -0
- package/dist/hitl/suspendedReopen.js +2 -2
- package/dist/hitl/toolApprovalWire.d.ts +4 -1
- package/dist/hitl/toolApprovalWire.js +20 -0
- package/dist/hookMatcherVerdict.d.ts +29 -0
- package/dist/hookMatcherVerdict.js +265 -0
- package/dist/humanTurn.d.ts +91 -0
- package/dist/humanTurn.js +253 -0
- package/dist/humanTurnRead.d.ts +105 -0
- package/dist/humanTurnRead.js +331 -0
- package/dist/index.d.ts +25 -8
- package/dist/index.js +16 -6
- package/dist/inheritEnvWire.js +1 -1
- package/dist/liveModelCatalog.d.ts +2 -0
- package/dist/liveModelCatalog.js +51 -3
- package/dist/permissionRuleIssue.d.ts +1 -1
- package/dist/permissionRuleIssue.js +22 -3
- package/dist/permissionsAllowGrantCapability.d.ts +2 -1
- package/dist/permissionsAllowGrantCapability.js +11 -2
- package/dist/permissionsDeclaration.d.ts +23 -0
- package/dist/permissionsDeclaration.js +133 -53
- package/dist/promptDelivery.d.ts +11 -3
- package/dist/promptDelivery.js +164 -29
- package/dist/providerRejection.d.ts +1 -0
- package/dist/providerRejection.js +20 -0
- package/dist/readDenyTiers.d.ts +10 -0
- package/dist/readDenyTiers.js +29 -0
- package/dist/request/taskRequest.js +2 -2
- package/dist/resumeRefusalCopy.d.ts +11 -0
- package/dist/resumeRefusalCopy.js +61 -4
- package/dist/rewindArchiveCapability.js +4 -4
- package/dist/rewindWireCaps.d.ts +2 -1
- package/dist/rewindWireCaps.js +19 -2
- package/dist/seam.d.ts +2 -0
- package/dist/taskRequestWords.d.ts +7 -1
- package/dist/taskRequestWords.js +18 -8
- package/dist/toolHistoryBadTurn.d.ts +1 -0
- package/dist/toolHistoryBadTurn.js +89 -0
- package/dist/toolHistoryMismatch.d.ts +2 -1
- package/dist/toolHistoryMismatch.js +19 -6
- package/dist/userAttachmentEnvelope.d.ts +61 -0
- package/dist/userAttachmentEnvelope.js +204 -0
- package/dist/wireFailureShape.d.ts +1 -0
- package/dist/wireFailureShape.js +4 -0
- package/dist/wireRefusalCopy.d.ts +6 -0
- package/dist/wireRefusalCopy.js +26 -3
- package/docs/INTEGRATION-CLIENTS.md +875 -14
- package/package.json +2 -2
package/dist/adapt/arms.js
CHANGED
|
@@ -11,6 +11,7 @@ import { readAsyncLaunchedAgentReceipt } from '../toolResult.js';
|
|
|
11
11
|
import { isWorkflowAgentTaskId, recordWorkflowAgentTaskId } from '../workflow.js';
|
|
12
12
|
import { isTerminalStatus } from '../runTerminal.js';
|
|
13
13
|
import { readToolHistoryMismatchKey } from '../toolHistoryMismatch.js';
|
|
14
|
+
import { readProviderRejectionResendKey } from '../providerRejection.js';
|
|
14
15
|
import { resolveEnginePanelTaskId } from '../engineAgentPanelStore.js';
|
|
15
16
|
import { fleetRowAgentType } from '../fleet/fleetRowAgentType.js';
|
|
16
17
|
import { chrome, mainLane, transcript, messageIdentityOf } from './ids.js';
|
|
@@ -23,6 +24,13 @@ function toolHistoryKeyCarry(m) {
|
|
|
23
24
|
const key = readToolHistoryMismatchKey(typeof raw === 'object' && raw !== null ? raw : undefined);
|
|
24
25
|
return key === undefined ? {} : { _sema_tool_history_mismatch: key };
|
|
25
26
|
}
|
|
27
|
+
function providerResendKeyCarry(m) {
|
|
28
|
+
if (m._sema_api_error_message !== true)
|
|
29
|
+
return {};
|
|
30
|
+
const raw = m._sema_provider_rejection_resend;
|
|
31
|
+
const key = readProviderRejectionResendKey(typeof raw === 'object' && raw !== null ? raw : undefined);
|
|
32
|
+
return key === undefined ? {} : { _sema_provider_rejection_resend: key };
|
|
33
|
+
}
|
|
26
34
|
const assistantArm = function* (m, { ctx, idOf, text, cards, inst }) {
|
|
27
35
|
const message = m.message;
|
|
28
36
|
const blocks = Array.isArray(message?.content)
|
|
@@ -129,6 +137,7 @@ const assistantArm = function* (m, { ctx, idOf, text, cards, inst }) {
|
|
|
129
137
|
parent_tool_use_id: null,
|
|
130
138
|
...(m._sema_api_error_message === true ? { _sema_api_error_message: true } : {}),
|
|
131
139
|
...toolHistoryKeyCarry(m),
|
|
140
|
+
...providerResendKeyCarry(m),
|
|
132
141
|
}, ctx.now());
|
|
133
142
|
text.markEmittedText(textBlock.text);
|
|
134
143
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readInstructionsSegment, wiringManifestViewOf } from './wiringManifestView.js';
|
|
1
|
+
import { readFleetSegment, readInstructionsSegment, wiringManifestViewOf } from './wiringManifestView.js';
|
|
2
2
|
import { stamp, snapshotSegmentIdentity, } from '../types.js';
|
|
3
3
|
import { turnUsageToModelUsage } from './turnUsageToModelUsage.js';
|
|
4
4
|
import { ccToolDenialKindForToolEnd, gateOutcomeOf } from '../../gateOutcome.js';
|
|
@@ -551,7 +551,8 @@ function wiringManifestSupersetBody(ev) {
|
|
|
551
551
|
const hands = projectHandsSection(ev);
|
|
552
552
|
const fileHistory = projectFileHistorySection(ev);
|
|
553
553
|
const instructions = readInstructionsSegment(ev, 'instructions');
|
|
554
|
-
|
|
554
|
+
const fleet = readFleetSegment(ev, 'fleet');
|
|
555
|
+
if (modelGate === undefined && autoMode === undefined && mcp === undefined && tools === undefined && hooks === undefined && lsp === undefined && writeProtection === undefined && autoConsolidation === undefined && readDeny === undefined && hands === undefined && fileHistory === undefined && instructions === undefined && fleet === undefined)
|
|
555
556
|
return undefined;
|
|
556
557
|
return {
|
|
557
558
|
...(modelGate !== undefined ? { _sema_modelGate: modelGate } : {}),
|
|
@@ -566,6 +567,7 @@ function wiringManifestSupersetBody(ev) {
|
|
|
566
567
|
...(hands !== undefined ? { _sema_hands: hands } : {}),
|
|
567
568
|
...(fileHistory !== undefined ? { _sema_fileHistory: fileHistory } : {}),
|
|
568
569
|
...(instructions !== undefined ? { _sema_instructions: instructions } : {}),
|
|
570
|
+
...(fleet !== undefined ? { _sema_fleet: fleet } : {}),
|
|
569
571
|
};
|
|
570
572
|
}
|
|
571
573
|
function projectFileHistorySection(holder) {
|
|
@@ -15,8 +15,12 @@ export type WiringManifestSections = {
|
|
|
15
15
|
_sema_instructions?: {
|
|
16
16
|
readonly selected: readonly string[];
|
|
17
17
|
};
|
|
18
|
+
_sema_fleet?: WiringManifestFleetView;
|
|
18
19
|
eventId?: string;
|
|
19
20
|
};
|
|
21
|
+
export interface WiringManifestFleetView {
|
|
22
|
+
readonly subagentTranscripts: string;
|
|
23
|
+
}
|
|
20
24
|
export interface WiringManifestView {
|
|
21
25
|
modelGate?: WiringManifestModelGate;
|
|
22
26
|
autoMode?: WiringManifestAutoMode;
|
|
@@ -32,9 +36,11 @@ export interface WiringManifestView {
|
|
|
32
36
|
instructions?: {
|
|
33
37
|
readonly selected: readonly string[];
|
|
34
38
|
};
|
|
39
|
+
fleet?: WiringManifestFleetView;
|
|
35
40
|
eventId?: string;
|
|
36
41
|
}
|
|
37
42
|
export declare function readInstructionsSegment(holder: object, key: 'instructions' | '_sema_instructions'): {
|
|
38
43
|
readonly selected: readonly string[];
|
|
39
44
|
} | undefined;
|
|
45
|
+
export declare function readFleetSegment(holder: object, key: 'fleet' | '_sema_fleet'): WiringManifestFleetView | undefined;
|
|
40
46
|
export declare function wiringManifestViewOf(s: WiringManifestSections): WiringManifestView | undefined;
|
|
@@ -27,9 +27,24 @@ export function readInstructionsSegment(holder, key) {
|
|
|
27
27
|
return undefined;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
export function readFleetSegment(holder, key) {
|
|
31
|
+
try {
|
|
32
|
+
if (!Object.hasOwn(holder, key))
|
|
33
|
+
return undefined;
|
|
34
|
+
const raw = holder[key];
|
|
35
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw) || !Object.hasOwn(raw, 'subagentTranscripts'))
|
|
36
|
+
return undefined;
|
|
37
|
+
const tier = raw.subagentTranscripts;
|
|
38
|
+
return typeof tier === 'string' && tier.length > 0 ? Object.freeze({ subagentTranscripts: tier }) : undefined;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
30
44
|
const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
31
45
|
export function wiringManifestViewOf(s) {
|
|
32
46
|
const instructions = readInstructionsSegment(s, '_sema_instructions');
|
|
47
|
+
const fleet = readFleetSegment(s, '_sema_fleet');
|
|
33
48
|
const view = {
|
|
34
49
|
...(isObj(s._sema_modelGate) ? { modelGate: s._sema_modelGate } : {}),
|
|
35
50
|
...(isObj(s._sema_autoMode) ? { autoMode: s._sema_autoMode } : {}),
|
|
@@ -43,6 +58,7 @@ export function wiringManifestViewOf(s) {
|
|
|
43
58
|
...(isObj(s._sema_hands) && typeof s._sema_hands.mounted === 'boolean' ? { hands: s._sema_hands } : {}),
|
|
44
59
|
...(typeof s._sema_fileHistory === 'string' && s._sema_fileHistory.length > 0 ? { fileHistory: s._sema_fileHistory } : {}),
|
|
45
60
|
...(instructions !== undefined ? { instructions } : {}),
|
|
61
|
+
...(fleet !== undefined ? { fleet } : {}),
|
|
46
62
|
};
|
|
47
63
|
if (Object.keys(view).length === 0)
|
|
48
64
|
return undefined;
|
|
@@ -7,6 +7,7 @@ import { ACTIVE_RUN_BUSY_ERROR_CODE, OUTPUT_INVALID, isCorruptSessionCode, isLim
|
|
|
7
7
|
import { corruptSessionContent } from '../corruptSessionCopy.js';
|
|
8
8
|
import { classifyToolHistoryMismatch, noteToolHistoryTerminal, openToolHistoryGeneration, TOOL_HISTORY_REWIND_SENTENCE, toolHistoryMismatchRowKey, toolHistoryRepeatSentence, toolHistoryRewindOffered, } from '../toolHistoryMismatch.js';
|
|
9
9
|
import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
|
|
10
|
+
import { providerRejectionResend } from '../providerRejection.js';
|
|
10
11
|
import { washCredentials } from '../displayUntrusted.js';
|
|
11
12
|
import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
|
|
12
13
|
import { resumeReopenContent, resumeReopenFromError, suspendedReopenOf } from '../hitl/suspendedReopen.js';
|
|
@@ -121,7 +122,7 @@ export function isModelOutputErrorRowText(text) {
|
|
|
121
122
|
return text.trimStart().startsWith(`${MODEL_OUTPUT_ERROR_PREFIX}:`);
|
|
122
123
|
}
|
|
123
124
|
export const OUTCOME_UNKNOWN_ROW_PREFIX = 'Outcome unknown';
|
|
124
|
-
function syntheticTerminalRow(ctx, text, historyKey) {
|
|
125
|
+
function syntheticTerminalRow(ctx, text, historyKey, resend) {
|
|
125
126
|
return stamp(ctx, {
|
|
126
127
|
uuid: undefined,
|
|
127
128
|
session_id: undefined,
|
|
@@ -130,6 +131,7 @@ function syntheticTerminalRow(ctx, text, historyKey) {
|
|
|
130
131
|
parent_tool_use_id: null,
|
|
131
132
|
_sema_api_error_message: true,
|
|
132
133
|
...(historyKey !== undefined ? { _sema_tool_history_mismatch: historyKey } : {}),
|
|
134
|
+
...(resend !== undefined ? { _sema_provider_rejection_resend: { resend: resend.resend, text: resend.text } } : {}),
|
|
133
135
|
});
|
|
134
136
|
}
|
|
135
137
|
function engineRunIdOf(result) {
|
|
@@ -264,41 +266,52 @@ export function toolHistoryErrorCarrierOf(terminalOrResult) {
|
|
|
264
266
|
return empty();
|
|
265
267
|
}
|
|
266
268
|
}
|
|
269
|
+
function terminalRowArmOf(facts) {
|
|
270
|
+
if (facts.errText === null)
|
|
271
|
+
return null;
|
|
272
|
+
return facts.busy.busy ? 'busy' : facts.governance ? 'governance' : isModelOutputErrorText(facts.errText) ? 'modelOutput' : 'apiError';
|
|
273
|
+
}
|
|
267
274
|
function toolHistoryCarrierFromFacts(x, facts) {
|
|
268
|
-
|
|
275
|
+
return apiErrorTerminalFromFacts(x, facts).carrier;
|
|
276
|
+
}
|
|
277
|
+
function apiErrorTerminalFromFacts(x, facts) {
|
|
278
|
+
const none = () => ({ carrier: mintToolHistoryCarrier(undefined, undefined, undefined), detail: undefined });
|
|
269
279
|
try {
|
|
270
280
|
const type = ownDataBit(x, 'type');
|
|
271
|
-
if (facts
|
|
272
|
-
return
|
|
281
|
+
if (terminalRowArmOf(facts) !== 'apiError')
|
|
282
|
+
return none();
|
|
273
283
|
if (type === 'failed')
|
|
274
|
-
return mintToolHistoryCarrier(nonEmptyStr(ownDataBit(x, 'errorCode')), undefined, nonEmptyStr(ownDataBit(x, 'errorMessage')));
|
|
284
|
+
return { carrier: mintToolHistoryCarrier(nonEmptyStr(ownDataBit(x, 'errorCode')), undefined, nonEmptyStr(ownDataBit(x, 'errorMessage'))), detail: undefined };
|
|
275
285
|
const result = type === 'done' ? plainObjectOf(ownDataBit(x, 'result')) : x;
|
|
276
286
|
if (result === undefined)
|
|
277
|
-
return
|
|
287
|
+
return none();
|
|
278
288
|
const snap = ownTerminalSnapshot(result);
|
|
279
289
|
if (snap === undefined)
|
|
280
|
-
return
|
|
290
|
+
return none();
|
|
281
291
|
const read = readRunTerminal(snap);
|
|
282
292
|
if (read === null || read.kind !== 'failed')
|
|
283
|
-
return
|
|
293
|
+
return none();
|
|
284
294
|
const detail = plainObjectOf(ownDataBit(read, 'detail'));
|
|
285
295
|
const detailStatus = detail !== undefined && ownDataBit(detail, 'kind') === PROVIDER_REJECTED_DETAIL ? ownDataBit(detail, 'status') : undefined;
|
|
286
296
|
const apiFailure = plainObjectOf(ownDataBit(result, 'apiFailure'));
|
|
287
297
|
const apiStatus = apiFailure === undefined ? undefined : ownDataBit(apiFailure, 'status');
|
|
288
298
|
const status = typeof apiStatus === 'number' && Number.isFinite(apiStatus) ? apiStatus : typeof detailStatus === 'number' ? detailStatus : undefined;
|
|
289
|
-
return
|
|
299
|
+
return {
|
|
300
|
+
carrier: mintToolHistoryCarrier(nonEmptyStr(ownDataBit(read, 'code')), status, nonEmptyStr(ownDataBit(read, 'message'))),
|
|
301
|
+
detail: detail,
|
|
302
|
+
};
|
|
290
303
|
}
|
|
291
304
|
catch {
|
|
292
|
-
return
|
|
305
|
+
return none();
|
|
293
306
|
}
|
|
294
307
|
}
|
|
295
|
-
function
|
|
308
|
+
function apiErrorTerminalOfRowFrame(ev, facts) {
|
|
296
309
|
try {
|
|
297
310
|
const x = plainObjectOf(ev);
|
|
298
|
-
return x === undefined ? mintToolHistoryCarrier(undefined, undefined, undefined) :
|
|
311
|
+
return x === undefined ? { carrier: mintToolHistoryCarrier(undefined, undefined, undefined), detail: undefined } : apiErrorTerminalFromFacts(x, facts);
|
|
299
312
|
}
|
|
300
313
|
catch {
|
|
301
|
-
return mintToolHistoryCarrier(undefined, undefined, undefined);
|
|
314
|
+
return { carrier: mintToolHistoryCarrier(undefined, undefined, undefined), detail: undefined };
|
|
302
315
|
}
|
|
303
316
|
}
|
|
304
317
|
const reportedDroppedTypes = new Set();
|
|
@@ -631,23 +644,24 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
631
644
|
const maxTokHint = /max_tokens/i.test(errText)
|
|
632
645
|
? '\nyour provider caps max_tokens lower — lower it in /model (press m, or M to type a value)'
|
|
633
646
|
: '';
|
|
634
|
-
const governance = rowFacts.governance;
|
|
635
647
|
const busyHandle = busy.handle;
|
|
636
|
-
const
|
|
648
|
+
const arm = terminalRowArmOf(rowFacts);
|
|
649
|
+
const rowText = arm === 'busy'
|
|
637
650
|
? `This session is locked by an earlier run${busyHandle ? ` (run ${busyHandle})` : ''} that ` +
|
|
638
651
|
`has not been released, so this message was NOT sent. Nothing releases it on its own — ` +
|
|
639
652
|
`cancel that run (POST /v1/runs/${busyHandle ?? '<id>'}/cancel), or start a new session.`
|
|
640
|
-
: governance
|
|
653
|
+
: arm === 'governance'
|
|
641
654
|
?
|
|
642
655
|
`${isGovernanceStopRowText(errText) ? errText : `${RUN_STOPPED_MESSAGE_PREFIX}: ${errText}`}${maxTokHint}`
|
|
643
|
-
:
|
|
656
|
+
: arm === 'modelOutput'
|
|
644
657
|
?
|
|
645
658
|
`${MODEL_OUTPUT_ERROR_PREFIX}: ${errText}${maxTokHint}`
|
|
646
659
|
: `API Error: ${errText}${maxTokHint}`;
|
|
647
660
|
const sessionUnreadable = ev.type === 'failed'
|
|
648
661
|
? isCorruptSessionCode(ev.errorCode)
|
|
649
662
|
: doneTerminal?.kind === 'failed' && isCorruptSessionCode(doneTerminal.code);
|
|
650
|
-
const
|
|
663
|
+
const historyTerminal = apiErrorTerminalOfRowFrame(ev, rowFacts);
|
|
664
|
+
const historyMismatch = classifyToolHistoryMismatch(historyTerminal.carrier);
|
|
651
665
|
const historyEchoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
|
|
652
666
|
const historyRepeat = noteToolHistoryTerminal({
|
|
653
667
|
sessionId: historyEchoedSid ?? ctx.sessionId,
|
|
@@ -657,10 +671,13 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
657
671
|
replay: ev.type === 'done' && ev.replay === true,
|
|
658
672
|
mismatch: historyMismatch,
|
|
659
673
|
});
|
|
660
|
-
const
|
|
674
|
+
const rewindOffered = historyMismatch !== null && ctx.lane !== 'print' && ctx.lane !== 'utility' && toolHistoryRewindOffered(ctx.offersRewind);
|
|
675
|
+
const rewindLine = rewindOffered
|
|
661
676
|
? `\n${TOOL_HISTORY_REWIND_SENTENCE}${historyRepeat !== undefined && historyRepeat >= 2 ? ` ${toolHistoryRepeatSentence(historyRepeat)}` : ''}`
|
|
662
677
|
: '';
|
|
663
|
-
|
|
678
|
+
const resend = historyTerminal.detail !== undefined ? providerRejectionResend(historyTerminal.detail, historyTerminal.carrier) : undefined;
|
|
679
|
+
const resendLine = resend !== undefined ? `\n${resend.text}` : '';
|
|
680
|
+
yield syntheticTerminalRow(ctx, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
|
|
664
681
|
}
|
|
665
682
|
else {
|
|
666
683
|
const echoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const MODE_ARBITRATION: Readonly<Record<"hook" | "write_protection" | "mode" | "rule_unreadable" | "content_question" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "ask_rule" | "denial_limit_fallback" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", import("./generated/engineFactTables.js").CoreModeArbitrationRow>>;
|
|
2
|
+
export type StandingAnswerVerdict = {
|
|
3
|
+
readonly kind: 'must_ask';
|
|
4
|
+
readonly by: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'may_answer';
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'unknown';
|
|
9
|
+
};
|
|
10
|
+
export declare function askSurvivesStandingAnswer(card: object | null | undefined): StandingAnswerVerdict;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CORE_MODE_ARBITRATION } from './generated/engineFactTables.js';
|
|
2
|
+
export const MODE_ARBITRATION = CORE_MODE_ARBITRATION;
|
|
3
|
+
const MUST_ASK_MANDATED = Object.freeze({ kind: 'must_ask', by: 'mandated' });
|
|
4
|
+
const MAY_ANSWER = Object.freeze({ kind: 'may_answer' });
|
|
5
|
+
const UNKNOWN = Object.freeze({ kind: 'unknown' });
|
|
6
|
+
export function askSurvivesStandingAnswer(card) {
|
|
7
|
+
try {
|
|
8
|
+
if (card === null || card === undefined || typeof card !== 'object')
|
|
9
|
+
return UNKNOWN;
|
|
10
|
+
if (Object.hasOwn(card, 'mandated') && card.mandated === true)
|
|
11
|
+
return MUST_ASK_MANDATED;
|
|
12
|
+
const classes = Object.hasOwn(card, 'classes') ? card.classes : undefined;
|
|
13
|
+
if (!Array.isArray(classes))
|
|
14
|
+
return UNKNOWN;
|
|
15
|
+
const length = classes.length;
|
|
16
|
+
if (typeof length !== 'number' || !Number.isSafeInteger(length) || length <= 0)
|
|
17
|
+
return UNKNOWN;
|
|
18
|
+
const names = [];
|
|
19
|
+
for (let i = 0; i < length; i += 1) {
|
|
20
|
+
if (!Object.hasOwn(classes, i))
|
|
21
|
+
return UNKNOWN;
|
|
22
|
+
const c = classes[i];
|
|
23
|
+
if (typeof c !== 'string')
|
|
24
|
+
return UNKNOWN;
|
|
25
|
+
names.push(c);
|
|
26
|
+
}
|
|
27
|
+
if (classes.length !== length)
|
|
28
|
+
return UNKNOWN;
|
|
29
|
+
for (const name of names) {
|
|
30
|
+
if (!Object.hasOwn(MODE_ARBITRATION, name))
|
|
31
|
+
return UNKNOWN;
|
|
32
|
+
if (MODE_ARBITRATION[name]?.ruleMayClear !== true)
|
|
33
|
+
return Object.freeze({ kind: 'must_ask', by: name });
|
|
34
|
+
}
|
|
35
|
+
return MAY_ANSWER;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return UNKNOWN;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type AttachmentSeatReading = {
|
|
2
|
+
readonly kind: 'unobserved';
|
|
3
|
+
} | {
|
|
4
|
+
readonly kind: 'not_reported';
|
|
5
|
+
};
|
|
6
|
+
export declare function noteEngineCapsForAttachmentSeat(baseUrl: string, caps: unknown, opts?: {
|
|
7
|
+
generation?: number;
|
|
8
|
+
}): void;
|
|
9
|
+
export declare function observedAttachmentSeat(baseUrl?: string | undefined): AttachmentSeatReading;
|
|
10
|
+
export declare function forgetAttachmentSeatReading(baseUrl: string | undefined): void;
|
|
11
|
+
export declare function __resetAttachmentSeatReadingsForTests(): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
function projectAttachmentSeat(caps) {
|
|
4
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
5
|
+
return undefined;
|
|
6
|
+
const p = Object.getPrototypeOf(caps);
|
|
7
|
+
if (p !== Object.prototype && p !== null)
|
|
8
|
+
return undefined;
|
|
9
|
+
return { kind: 'not_reported' };
|
|
10
|
+
}
|
|
11
|
+
const reader = createEngineCapReader({
|
|
12
|
+
name: 'attachmentSeat',
|
|
13
|
+
project: projectAttachmentSeat,
|
|
14
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
15
|
+
});
|
|
16
|
+
export function noteEngineCapsForAttachmentSeat(baseUrl, caps, opts) {
|
|
17
|
+
reader.note(baseUrl, caps, opts);
|
|
18
|
+
}
|
|
19
|
+
export function observedAttachmentSeat(baseUrl = engineWireTarget()?.baseUrl) {
|
|
20
|
+
return reader.observed(baseUrl);
|
|
21
|
+
}
|
|
22
|
+
export function forgetAttachmentSeatReading(baseUrl) {
|
|
23
|
+
reader.forget(baseUrl);
|
|
24
|
+
}
|
|
25
|
+
export function __resetAttachmentSeatReadingsForTests() {
|
|
26
|
+
reader.__resetForTests();
|
|
27
|
+
}
|
|
@@ -28,3 +28,12 @@ export declare class AttachmentsSpecRefused extends TypeError {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
export declare function attachmentsForRequest(env?: EnvLike): AttachmentsSpec | undefined;
|
|
31
|
+
export type AttachmentsSubmitVerdict = {
|
|
32
|
+
readonly ok: true;
|
|
33
|
+
readonly attachments: AttachmentsSpec;
|
|
34
|
+
} | {
|
|
35
|
+
readonly ok: false;
|
|
36
|
+
readonly sentence: string;
|
|
37
|
+
readonly refusedKey: string | undefined;
|
|
38
|
+
};
|
|
39
|
+
export declare function attachmentsSubmitVerdict(env?: EnvLike): AttachmentsSubmitVerdict;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
2
|
import { envFlagOff } from './envFlag.js';
|
|
3
|
-
import {
|
|
3
|
+
import { retiredAttachmentsKeyOf } from './taskRequestWords.js';
|
|
4
4
|
export const ATTACHMENTS_ENV = 'SEMA_ATTACHMENTS';
|
|
5
5
|
export const ATTACHMENTS_SPEC_KEYS = Object.freeze([
|
|
6
6
|
'todoReminder',
|
|
@@ -48,25 +48,27 @@ function refuse(token, why) {
|
|
|
48
48
|
const allowed = legalAttachmentsTokens();
|
|
49
49
|
throw new AttachmentsSpecRefused(`${ATTACHMENTS_ENV}: refusing token "${token}" — ${why}. Legal tokens: ${allowed.join(' | ')}`, { token, why, allowed });
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
function deny(kind, token, why, index, key) {
|
|
52
|
+
return { ok: false, refusal: { kind, token, why, entry: index + 1, key } };
|
|
53
|
+
}
|
|
54
|
+
function judgeAttachmentsEnv(raw) {
|
|
53
55
|
if (envFlagOff(raw))
|
|
54
|
-
return allDefaultOnOff();
|
|
56
|
+
return { ok: true, spec: allDefaultOnOff() };
|
|
55
57
|
const tokens = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
|
|
56
|
-
for (const token of tokens) {
|
|
57
|
-
const named =
|
|
58
|
+
for (const [i, token] of tokens.entries()) {
|
|
59
|
+
const named = retiredAttachmentsKeyOf(token);
|
|
58
60
|
if (named !== undefined)
|
|
59
|
-
|
|
61
|
+
return { ok: false, refusal: { kind: 'retired_key', token, why: named.why, entry: i + 1, key: named.key, retired: named } };
|
|
60
62
|
}
|
|
61
63
|
if (tokens.length === 0)
|
|
62
|
-
return { backgroundTasks: true, toolsDelta: true };
|
|
64
|
+
return { ok: true, spec: { backgroundTasks: true, toolsDelta: true } };
|
|
63
65
|
if (tokens.length === 1 && (tokens[0] === 'full' || tokens[0] === 'all'))
|
|
64
|
-
return allLiteralTrue();
|
|
66
|
+
return { ok: true, spec: allLiteralTrue() };
|
|
65
67
|
if (tokens.length === 1 && !isKnownToken(tokens[0])) {
|
|
66
|
-
return { backgroundTasks: true, toolsDelta: true };
|
|
68
|
+
return { ok: true, spec: { backgroundTasks: true, toolsDelta: true } };
|
|
67
69
|
}
|
|
68
70
|
const spec = {};
|
|
69
|
-
for (const token of tokens) {
|
|
71
|
+
for (const [i, token] of tokens.entries()) {
|
|
70
72
|
if (token === 'full' || token === 'all') {
|
|
71
73
|
Object.assign(spec, allLiteralTrue());
|
|
72
74
|
continue;
|
|
@@ -79,11 +81,11 @@ export function attachmentsForRequest(env = hostEnv()) {
|
|
|
79
81
|
if (token.startsWith('-')) {
|
|
80
82
|
const key = canonicalKey(token.slice(1));
|
|
81
83
|
if (key === undefined)
|
|
82
|
-
|
|
84
|
+
return deny('unknown_key', token, 'unknown attachments key', i, undefined);
|
|
83
85
|
if (!isDefaultOnKey(key)) {
|
|
84
|
-
|
|
86
|
+
return deny('minus_on_literal_true_key', token, `"${key}" belongs to the literal-true family whose OFF is "delete the key", not "send false" ` +
|
|
85
87
|
'(core wire contract, board [479] ask-2) — simply do not turn it on. ' +
|
|
86
|
-
`Only the core DEFAULT-ON keys (${ATTACHMENTS_DEFAULT_ON_KEYS.join(' / ')}) accept an explicit false
|
|
88
|
+
`Only the core DEFAULT-ON keys (${ATTACHMENTS_DEFAULT_ON_KEYS.join(' / ')}) accept an explicit false`, i, key);
|
|
87
89
|
}
|
|
88
90
|
spec[key] = false;
|
|
89
91
|
continue;
|
|
@@ -91,25 +93,76 @@ export function attachmentsForRequest(env = hostEnv()) {
|
|
|
91
93
|
const [lhs, rhs] = splitAssign(token);
|
|
92
94
|
if (rhs !== undefined) {
|
|
93
95
|
if (canonicalKey(lhs) !== 'todoReminderMode')
|
|
94
|
-
|
|
96
|
+
return deny('value_form_on_other_key', token, 'only `todoReminderMode` takes a `key=value` form', i, canonicalKey(lhs));
|
|
95
97
|
const mode = TODO_REMINDER_MODES.find(v => v === rhs);
|
|
96
98
|
if (mode === undefined)
|
|
97
|
-
|
|
99
|
+
return deny('todo_mode_bad_value', token, `todoReminderMode must be one of ${TODO_REMINDER_MODES.join('|')}`, i, 'todoReminderMode');
|
|
98
100
|
spec.todoReminderMode = mode;
|
|
99
101
|
continue;
|
|
100
102
|
}
|
|
101
103
|
const key = canonicalKey(lhs.startsWith('+') ? lhs.slice(1) : lhs);
|
|
102
104
|
if (key === undefined)
|
|
103
|
-
|
|
105
|
+
return deny('unknown_key', token, 'unknown attachments key', i, undefined);
|
|
104
106
|
if (isDefaultOnOnlyKey(key)) {
|
|
105
|
-
|
|
106
|
-
`use "-${key}" to turn it OFF`);
|
|
107
|
+
return deny('plus_on_default_on_key', token, `"${key}" is core DEFAULT-ON — turning it "on" is a no-op that would send a redundant true; ` + `use "-${key}" to turn it OFF`, i, key);
|
|
107
108
|
}
|
|
108
109
|
if (key === 'todoReminderMode')
|
|
109
|
-
|
|
110
|
+
return deny('todo_mode_needs_value', token, 'todoReminderMode needs a value: `todoReminderMode=baseline|off`', i, key);
|
|
110
111
|
spec[key] = true;
|
|
111
112
|
}
|
|
112
|
-
return spec;
|
|
113
|
+
return { ok: true, spec };
|
|
114
|
+
}
|
|
115
|
+
function envRawOf(env) {
|
|
116
|
+
return (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
|
|
117
|
+
}
|
|
118
|
+
export function attachmentsForRequest(env = hostEnv()) {
|
|
119
|
+
const judged = judgeAttachmentsEnv(envRawOf(env));
|
|
120
|
+
if (!judged.ok)
|
|
121
|
+
return refuse(judged.refusal.token, judged.refusal.why);
|
|
122
|
+
return judged.spec;
|
|
123
|
+
}
|
|
124
|
+
function attachmentsWayOut() {
|
|
125
|
+
const on = OPT_IN_KEYS.join(', ');
|
|
126
|
+
const off = ATTACHMENTS_DEFAULT_ON_KEYS.join(', ');
|
|
127
|
+
return (`Accepted writing is either the single word off on its own (every attachment off; it cannot be combined with other entries), or a comma-separated list of: ` +
|
|
128
|
+
`full or all (every opt-in attachment on), default, the name of an attachment to turn on (${on}), a leading minus to turn off one of ${off}, and todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}. ` +
|
|
129
|
+
`To drop the setting altogether, unset ${ATTACHMENTS_ENV}; the defaults then apply.`);
|
|
130
|
+
}
|
|
131
|
+
function attachmentsRefusalSentence(r) {
|
|
132
|
+
const head = `The attachments setting (${ATTACHMENTS_ENV}) cannot be used as it is set: entry ${r.entry} of the list`;
|
|
133
|
+
const key = r.key ?? '';
|
|
134
|
+
switch (r.kind) {
|
|
135
|
+
case 'retired_key':
|
|
136
|
+
return `${head} names "${key}", a key that no longer exists — ${r.retired?.because ?? 'it was retired'}, and a request carrying that key is refused by the server. Remove that entry${r.retired === undefined ? '' : `; ${r.retired.remedy}`}. ${attachmentsWayOut()}`;
|
|
137
|
+
case 'unknown_key':
|
|
138
|
+
return `${head} is not an attachment this version knows. ${attachmentsWayOut()}`;
|
|
139
|
+
case 'minus_on_literal_true_key':
|
|
140
|
+
return key === 'todoReminderMode'
|
|
141
|
+
? `${head} puts a minus on todoReminderMode, which is a setting with a value rather than something to turn off — write todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}, or leave it out of the list. A minus only works on ${ATTACHMENTS_DEFAULT_ON_KEYS.join(', ')}, which are on by default. ${attachmentsWayOut()}`
|
|
142
|
+
: `${head} puts a minus on ${key}, and a minus cannot switch that attachment off — it is on only when it is named, or when full, all or default switches it on. A minus only works on ${ATTACHMENTS_DEFAULT_ON_KEYS.join(', ')}, which are on by default. To leave ${key} out, do not name it, and if full, all or default is what switches it on, list the attachments you want one by one instead. ${attachmentsWayOut()}`;
|
|
143
|
+
case 'plus_on_default_on_key':
|
|
144
|
+
return `${head} turns on ${key}, which is already on by default. To turn it off write -${key}; otherwise leave it out of the list. ${attachmentsWayOut()}`;
|
|
145
|
+
case 'value_form_on_other_key':
|
|
146
|
+
return `${head} uses a name=value form, and only todoReminderMode takes one. ${attachmentsWayOut()}`;
|
|
147
|
+
case 'todo_mode_bad_value':
|
|
148
|
+
return `${head} gives todoReminderMode a value it does not accept; the values are ${TODO_REMINDER_MODES.join(' and ')}. ${attachmentsWayOut()}`;
|
|
149
|
+
case 'todo_mode_needs_value':
|
|
150
|
+
return `${head} names todoReminderMode without a value; write todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}. ${attachmentsWayOut()}`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function attachmentsUnreadableSentence() {
|
|
154
|
+
return `The attachments setting (${ATTACHMENTS_ENV}) could not be read as text, so it cannot be used as it is set. Set it to a plain comma-separated list, or unset it. ${attachmentsWayOut()}`;
|
|
155
|
+
}
|
|
156
|
+
export function attachmentsSubmitVerdict(env = hostEnv()) {
|
|
157
|
+
try {
|
|
158
|
+
const judged = judgeAttachmentsEnv(envRawOf(env));
|
|
159
|
+
if (judged.ok)
|
|
160
|
+
return { ok: true, attachments: judged.spec };
|
|
161
|
+
return { ok: false, sentence: attachmentsRefusalSentence(judged.refusal), refusedKey: judged.refusal.key };
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { ok: false, sentence: attachmentsUnreadableSentence(), refusedKey: undefined };
|
|
165
|
+
}
|
|
113
166
|
}
|
|
114
167
|
function allDefaultOnOff() {
|
|
115
168
|
const out = {};
|
package/dist/compensations.js
CHANGED
|
@@ -7,8 +7,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
7
7
|
libraryHalf: 'adapt.ts bindTaskCard()',
|
|
8
8
|
chromeArm: null,
|
|
9
9
|
hostHalf: null,
|
|
10
|
-
retireOn: '
|
|
11
|
-
'FIFO 回落臂可删 —— 但只在**确认不再支持老引擎**时删,见 bindTaskCard 的 old-engine fallback 注释',
|
|
10
|
+
retireOn: 'RL-31',
|
|
12
11
|
},
|
|
13
12
|
{
|
|
14
13
|
id: 'T34',
|
|
@@ -26,7 +25,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
26
25
|
libraryHalf: 'adapt.ts fireSubagentStart()(类型恒记 + 一生一次去重 + if-started 门)',
|
|
27
26
|
chromeArm: 'subagent_lifecycle',
|
|
28
27
|
hostHalf: '真执行用户 hook 进程(浏览器宿主根本不能执行 ⇒ 这一半必须留端)',
|
|
29
|
-
retireOn: '
|
|
28
|
+
retireOn: 'RL-32',
|
|
30
29
|
},
|
|
31
30
|
{
|
|
32
31
|
id: 'T36',
|
|
@@ -35,7 +34,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
35
34
|
libraryHalf: 'adapt.ts settlePanelTasks 的四个调用点(tool_end 关卡 / result / turn 末 / abort)',
|
|
36
35
|
chromeArm: 'inline_task_stats',
|
|
37
36
|
hostHalf: null,
|
|
38
|
-
retireOn: '
|
|
37
|
+
retireOn: 'RL-33',
|
|
39
38
|
},
|
|
40
39
|
{
|
|
41
40
|
id: 'T44',
|
|
@@ -53,7 +52,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
53
52
|
libraryHalf: 'adapt.ts task_progress 臂的 workflowRunId / wa-id / workflow-card-parent 三级门',
|
|
54
53
|
chromeArm: null,
|
|
55
54
|
hostHalf: null,
|
|
56
|
-
retireOn: '
|
|
55
|
+
retireOn: 'RL-34',
|
|
57
56
|
},
|
|
58
57
|
{
|
|
59
58
|
id: 'T48',
|
|
@@ -63,7 +62,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
63
62
|
chromeArm: null,
|
|
64
63
|
hostHalf: 'footer 行过滤 isFooterTaskRow/filterFooterTaskRows —— 含「丢弃所有无 parentId 顶层行」' +
|
|
65
64
|
'这条**端专属决策**(主 run 头部行由端自己合成渲染),留 TUI',
|
|
66
|
-
retireOn: '
|
|
65
|
+
retireOn: 'RL-35',
|
|
67
66
|
},
|
|
68
67
|
{
|
|
69
68
|
id: 'T1',
|
|
@@ -83,8 +82,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
83
82
|
libraryHalf: 'notifications.ts taskNotificationDedupKey + taskNotificationDedupKeyFromWire(裸 wire 入口)',
|
|
84
83
|
chromeArm: null,
|
|
85
84
|
hostHalf: null,
|
|
86
|
-
retireOn: '
|
|
87
|
-
'删之前要先有一批「同一完成在两条通道上 completionId 相同」的实测(否则换成了一把更差的键)',
|
|
85
|
+
retireOn: 'RL-36',
|
|
88
86
|
},
|
|
89
87
|
{
|
|
90
88
|
id: 'T3',
|
|
@@ -95,8 +93,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
95
93
|
'adapt.ts importLedgerFromTranscript(消费口)',
|
|
96
94
|
chromeArm: null,
|
|
97
95
|
hostHalf: null,
|
|
98
|
-
retireOn: '
|
|
99
|
-
'completionId。所以退的是「XML 反解」这一段,不是整条回植',
|
|
96
|
+
retireOn: 'RL-37',
|
|
100
97
|
},
|
|
101
98
|
{
|
|
102
99
|
id: 'T25',
|
|
@@ -106,7 +103,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
106
103
|
libraryHalf: 'toolResult.ts 终态轮询卡臂的预 seed + notifications.markEngineWorkflowNotified',
|
|
107
104
|
chromeArm: null,
|
|
108
105
|
hostHalf: null,
|
|
109
|
-
retireOn: '
|
|
106
|
+
retireOn: 'RL-38',
|
|
110
107
|
},
|
|
111
108
|
{
|
|
112
109
|
id: 'T53',
|
|
@@ -115,8 +112,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
115
112
|
libraryHalf: 'adapt.ts task_notification / workflow_complete 两臂的四道门(逐道说明见本行上方注释)',
|
|
116
113
|
chromeArm: null,
|
|
117
114
|
hostHalf: null,
|
|
118
|
-
retireOn: '
|
|
119
|
-
'🔴 判据不是「四变一」而是逐道过一遍上面那四行 —— 把 ④ 当成去重删掉会让队列里的旧条目重新上屏',
|
|
115
|
+
retireOn: 'RL-39',
|
|
120
116
|
},
|
|
121
117
|
{
|
|
122
118
|
id: 'T49',
|
|
@@ -125,7 +121,7 @@ export const MIGRATED_COMPENSATIONS = [
|
|
|
125
121
|
libraryHalf: 'adapt.ts task_progress 臂 registerSubagentAlias(explicitParent, taskId)',
|
|
126
122
|
chromeArm: null,
|
|
127
123
|
hostHalf: null,
|
|
128
|
-
retireOn: '
|
|
124
|
+
retireOn: 'RL-40',
|
|
129
125
|
},
|
|
130
126
|
];
|
|
131
127
|
export function compensationSplitViolations() {
|
package/dist/controlRouter.d.ts
CHANGED
|
@@ -21,7 +21,12 @@ export type ControlSafetyCode = 'not_running' | 'invalid_content' | 'queue_full'
|
|
|
21
21
|
export declare class ControlSafetyError extends Error {
|
|
22
22
|
readonly code: ControlSafetyCode;
|
|
23
23
|
readonly cause?: unknown | undefined;
|
|
24
|
-
|
|
24
|
+
readonly advice?: string;
|
|
25
|
+
readonly status?: number;
|
|
26
|
+
constructor(message: string, code: ControlSafetyCode, cause?: unknown | undefined, detail?: {
|
|
27
|
+
readonly advice?: string;
|
|
28
|
+
readonly status?: number;
|
|
29
|
+
});
|
|
25
30
|
}
|
|
26
31
|
export type QueuePriority = 'now' | 'next' | 'later';
|
|
27
32
|
export interface QueuedCommand {
|
|
@@ -72,8 +77,10 @@ export interface ErrCodes {
|
|
|
72
77
|
}
|
|
73
78
|
export declare function errCodes(e: unknown): ErrCodes;
|
|
74
79
|
export declare function steeringStatusIs4xx(e: object): boolean;
|
|
75
|
-
export interface
|
|
80
|
+
export interface SteerRefusalAdvice {
|
|
76
81
|
safety: ControlSafetyCode;
|
|
77
82
|
advice: string;
|
|
78
83
|
}
|
|
84
|
+
export type SteeringRefusedBeforeEngine = SteerRefusalAdvice;
|
|
79
85
|
export declare function steeringRefusedBeforeEngine(e: object): SteeringRefusedBeforeEngine | undefined;
|
|
86
|
+
export declare function steerRefusalAdviceOf(e: object): SteerRefusalAdvice | undefined;
|