@sema-agent/client-core 0.92.0 → 0.93.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 +179 -0
- package/README.md +23 -16
- package/dist/adapt/arms.js +2 -0
- package/dist/adapt/toolCards.js +6 -4
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +1 -1
- package/dist/adapter/runStream.js +3 -1
- package/dist/agentsWireCaps.js +1 -1
- package/dist/approvalDecidedByCapability.d.ts +16 -0
- package/dist/approvalDecidedByCapability.js +47 -0
- package/dist/approvalsStreamLiveCapability.js +3 -3
- package/dist/askSurvivesStandingAnswer.d.ts +1 -1
- package/dist/centerWiringCapability.js +1 -1
- package/dist/cloudConfigWireCaps.js +5 -5
- package/dist/compensations.js +2 -2
- package/dist/decideReceipt.d.ts +2 -0
- package/dist/decideReceipt.js +34 -9
- package/dist/detachWire.d.ts +2 -14
- package/dist/detachWire.js +1 -47
- package/dist/deviceExecutorManagementCapability.d.ts +6 -2
- package/dist/deviceExecutorManagementCapability.js +61 -15
- package/dist/engineConfigDrift.d.ts +20 -0
- package/dist/engineConfigDrift.js +54 -0
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +12 -4
- package/dist/engineInlineTaskStats.d.ts +1 -0
- package/dist/engineNoticeCodes.d.ts +2 -2
- package/dist/engineWireFor.d.ts +22 -0
- package/dist/engineWireFor.js +154 -9
- package/dist/engineWireSdk.d.ts +0 -1
- package/dist/engineWireSdk.js +0 -3
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.d.ts +1 -1
- package/dist/fileHistoryCaptureCapability.js +1 -6
- package/dist/fileHistoryLegNotice.d.ts +1 -1
- package/dist/fileHistoryLegNotice.js +1 -6
- package/dist/gateVocabulary.d.ts +1 -5
- package/dist/gateVocabulary.js +4 -22
- package/dist/generated/engineFactTables.d.ts +4 -3
- package/dist/generated/engineFactTables.js +10 -0
- package/dist/generated/engineNoticeTables.d.ts +1 -1
- package/dist/generated/engineNoticeTables.js +1 -1
- package/dist/goalStopHook.d.ts +1 -8
- package/dist/goalStopHook.js +2 -58
- package/dist/headlessPermissionModeWire.d.ts +3 -2
- package/dist/headlessPermissionModeWire.js +46 -5
- package/dist/hitl/askParkRowRouting.js +2 -2
- package/dist/hitl/frameRouter.js +7 -2
- package/dist/hitl/gateLedger.d.ts +1 -0
- package/dist/hitl/gateLedger.js +3 -0
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +6 -1
- package/dist/hitl/hitlHostSurface.d.ts +3 -2
- package/dist/hitl/hitlHostSurface.js +18 -3
- package/dist/hitl/parkResolver.js +22 -4
- package/dist/hitl/persistedRulesWire.js +29 -17
- package/dist/hitl/planReviewWire.d.ts +0 -2
- package/dist/hitl/planReviewWire.js +1 -18
- package/dist/hitl/sessionPolicyDeliverable.js +3 -3
- package/dist/hitl/sessionPolicyWire.d.ts +2 -0
- package/dist/hitl/sessionPolicyWire.js +7 -4
- package/dist/hitl/toolApprovalWire.d.ts +22 -7
- package/dist/hitl/toolApprovalWire.js +133 -54
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +6 -2
- package/dist/inheritEnvWire.d.ts +1 -4
- package/dist/inheritEnvWire.js +0 -18
- package/dist/limitsWire.d.ts +0 -6
- package/dist/limitsWire.js +0 -38
- package/dist/mcpProbeCapability.js +1 -1
- package/dist/mcpProbeWire.js +10 -12
- package/dist/mcpReconnect.d.ts +5 -0
- package/dist/mcpReconnect.js +28 -0
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/memoryVerbsWire.js +14 -13
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +15 -0
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.d.ts +16 -0
- package/dist/permissionModesCapability.js +71 -0
- package/dist/permissionRuleIssue.js +1 -1
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionWireCaps.d.ts +2 -0
- package/dist/permissionWireCaps.js +8 -1
- package/dist/permissionsAllowGrantCapability.js +7 -2
- package/dist/postureKnob.js +1 -1
- package/dist/protocolSegment.d.ts +2 -0
- package/dist/protocolSegment.js +3 -0
- package/dist/readFacePosture.js +1 -1
- package/dist/resumeRefusalCopy.d.ts +1 -0
- package/dist/resumeRefusalCopy.js +26 -3
- package/dist/retryStatus.js +2 -1
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/runTerminal.d.ts +16 -0
- package/dist/runTerminal.js +32 -3
- package/dist/seam.d.ts +1 -0
- package/dist/sessionPolicyCapability.js +1 -1
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/skillToolListsCapability.js +1 -1
- package/dist/sqlEngineCapability.js +1 -1
- package/dist/steerPriorityCapability.js +1 -1
- package/dist/storePostureCapability.js +2 -2
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +13 -3
- package/dist/taskRequestWords.d.ts +4 -2
- package/dist/taskRequestWords.js +1 -1
- package/dist/toolHistoryBadTurn.js +1 -2
- package/dist/toolResult.d.ts +2 -1
- package/dist/toolResult.js +33 -3
- package/dist/userInvokedSkillsCapability.js +1 -1
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/webSearchWireCaps.d.ts +1 -1
- package/dist/webSearchWireCaps.js +40 -2
- package/dist/wireFailureShape.js +2 -2
- package/dist/wireRefusalCopy.d.ts +9 -3
- package/dist/wireRefusalCopy.js +41 -4
- package/dist/workflowsJournalCapability.js +1 -1
- package/dist/writeProtectionCapability.js +1 -1
- package/docs/INTEGRATION-CLIENTS.md +901 -15
- package/package.json +2 -2
package/dist/retryStatus.js
CHANGED
|
@@ -47,7 +47,7 @@ export function mapBrainStatusToRetry(p, nowMs) {
|
|
|
47
47
|
case 'reconnecting':
|
|
48
48
|
return { kind: 'stalled', deadline, ...extra, ...stalledDetail };
|
|
49
49
|
case 'rate_limited':
|
|
50
|
-
return { kind: 'error', deadline, ...extra, error: { formatted: '', rateLimits:
|
|
50
|
+
return { kind: 'error', deadline, ...extra, error: { formatted: p.detail ?? '', rateLimits: null } };
|
|
51
51
|
case 'circuit_open':
|
|
52
52
|
return {
|
|
53
53
|
kind: 'error',
|
|
@@ -60,6 +60,7 @@ export function mapBrainStatusToRetry(p, nowMs) {
|
|
|
60
60
|
case 'waiting_first_token':
|
|
61
61
|
return { kind: 'waiting', deadline, ...extra, error: { formatted: '' } };
|
|
62
62
|
case 'retrying':
|
|
63
|
+
return { kind: 'error', deadline, ...extra, error: { formatted: p.detail ?? '' } };
|
|
63
64
|
default:
|
|
64
65
|
return { kind: 'error', deadline, ...extra, error: { formatted: '' } };
|
|
65
66
|
}
|
|
@@ -77,7 +77,7 @@ export function rewindArchiveDoctorDetail(reading, mode) {
|
|
|
77
77
|
? `${lane} off on this deployment (no file history store) — the working tree cannot be restored here; whether the conversation alone can be rewound is a separate reading`
|
|
78
78
|
: `${lane} off on this deployment — it needs both a file history store and conversation anchors, and the engine reports at least one missing (it does not say which)`;
|
|
79
79
|
case 'not_reported':
|
|
80
|
-
return `${lane} not reported by this engine
|
|
80
|
+
return `${lane} not reported by this engine, so this does not say whether the code archive can be restored`;
|
|
81
81
|
case 'malformed':
|
|
82
82
|
return `${lane} reported in a shape this reader cannot read — the value is neither true nor false, so the answer is unknown, not "no"`;
|
|
83
83
|
}
|
|
@@ -102,7 +102,7 @@ export function rewindConversationDoctorDetail(reading) {
|
|
|
102
102
|
case 'off':
|
|
103
103
|
return `${lane} off on this deployment (no conversation anchors) — the conversation cannot be moved back to an earlier message here`;
|
|
104
104
|
case 'not_reported':
|
|
105
|
-
return `conversation anchors not reported by this engine
|
|
105
|
+
return `conversation anchors not reported by this engine, so this does not say whether the conversation can be rewound`;
|
|
106
106
|
case 'malformed':
|
|
107
107
|
return `conversation anchors reported in a shape this reader cannot read — the value is neither true nor false, so the answer is unknown, not "no"`;
|
|
108
108
|
}
|
package/dist/runTerminal.d.ts
CHANGED
|
@@ -16,6 +16,21 @@ export interface RunTerminalFailureDetail {
|
|
|
16
16
|
status?: number;
|
|
17
17
|
code?: string;
|
|
18
18
|
}
|
|
19
|
+
export declare const PROMPT_BLOCK_CAUSES: readonly ["block", "crashed", "timeout", "cancelled"];
|
|
20
|
+
export type PromptBlockCause = (typeof PROMPT_BLOCK_CAUSES)[number];
|
|
21
|
+
export type RunTerminalBlockedDetail = {
|
|
22
|
+
kind: 'prompt_blocked_by_hook';
|
|
23
|
+
cause: PromptBlockCause;
|
|
24
|
+
hookReason?: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'prompt_blocked_by_hook';
|
|
27
|
+
cause: 'unrecognized';
|
|
28
|
+
word: string;
|
|
29
|
+
hookReason?: string;
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'unrecognized';
|
|
32
|
+
word: string;
|
|
33
|
+
};
|
|
19
34
|
export type RunTerminalRead = {
|
|
20
35
|
kind: 'completed';
|
|
21
36
|
plane: RunTerminalPlane;
|
|
@@ -31,6 +46,7 @@ export type RunTerminalRead = {
|
|
|
31
46
|
plane: RunTerminalPlane;
|
|
32
47
|
reason?: string;
|
|
33
48
|
code?: string;
|
|
49
|
+
detail?: RunTerminalBlockedDetail;
|
|
34
50
|
} | RunTerminalPausedRead | {
|
|
35
51
|
kind: 'unknown';
|
|
36
52
|
plane: RunTerminalPlane;
|
package/dist/runTerminal.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { CORE_TERMINAL_CAUSE_KINDS } from './generated/engineFactTables.js';
|
|
1
|
+
import { CORE_PROMPT_BLOCK_CAUSES, CORE_TERMINAL_CAUSE_KINDS } from './generated/engineFactTables.js';
|
|
2
|
+
export const PROMPT_BLOCK_CAUSES = CORE_PROMPT_BLOCK_CAUSES;
|
|
3
|
+
const PROMPT_BLOCKED_BY_HOOK_DETAIL_KIND = 'prompt_blocked_by_hook';
|
|
2
4
|
function str(v) {
|
|
3
5
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
4
6
|
}
|
|
@@ -20,10 +22,13 @@ function pauseOf(v) {
|
|
|
20
22
|
...(restoreMode !== undefined ? { restoreMode } : {}),
|
|
21
23
|
};
|
|
22
24
|
}
|
|
25
|
+
function ownValueOf(o, k) {
|
|
26
|
+
return Object.prototype.hasOwnProperty.call(o, k) ? o[k] : undefined;
|
|
27
|
+
}
|
|
23
28
|
const PROVIDER_REJECTED_DETAIL_KIND = 'provider_rejected';
|
|
24
29
|
function failureDetailOf(cause) {
|
|
25
30
|
try {
|
|
26
|
-
const own =
|
|
31
|
+
const own = ownValueOf;
|
|
27
32
|
const v = own(cause, 'detail');
|
|
28
33
|
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
29
34
|
return undefined;
|
|
@@ -41,6 +46,29 @@ function failureDetailOf(cause) {
|
|
|
41
46
|
return undefined;
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
function blockedDetailOf(cause) {
|
|
50
|
+
try {
|
|
51
|
+
const v = ownValueOf(cause, 'detail');
|
|
52
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
53
|
+
return undefined;
|
|
54
|
+
const kind = str(ownValueOf(v, 'kind'));
|
|
55
|
+
if (kind === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
if (kind !== PROMPT_BLOCKED_BY_HOOK_DETAIL_KIND)
|
|
58
|
+
return { kind: 'unrecognized', word: kind };
|
|
59
|
+
const causeWord = str(ownValueOf(v, 'cause'));
|
|
60
|
+
if (causeWord === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
const hookReason = str(ownValueOf(v, 'hookReason'));
|
|
63
|
+
const hook = hookReason !== undefined ? { hookReason } : {};
|
|
64
|
+
return PROMPT_BLOCK_CAUSES.includes(causeWord)
|
|
65
|
+
? { kind: PROMPT_BLOCKED_BY_HOOK_DETAIL_KIND, cause: causeWord, ...hook }
|
|
66
|
+
: { kind: PROMPT_BLOCKED_BY_HOOK_DETAIL_KIND, cause: 'unrecognized', word: causeWord, ...hook };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
44
72
|
const FLAT_PAUSED_STATUSES = ['suspended', 'needs_review'];
|
|
45
73
|
export function readRunTerminal(result) {
|
|
46
74
|
if (typeof result !== 'object' || result === null || Array.isArray(result))
|
|
@@ -77,7 +105,8 @@ export function readRunTerminal(result) {
|
|
|
77
105
|
}
|
|
78
106
|
case 'blocked': {
|
|
79
107
|
const reason = str(c.reason);
|
|
80
|
-
|
|
108
|
+
const detail = blockedDetailOf(c);
|
|
109
|
+
return { kind: 'blocked', plane: 'cause', ...(reason !== undefined ? { reason } : {}), ...(detail !== undefined ? { detail } : {}) };
|
|
81
110
|
}
|
|
82
111
|
case 'paused':
|
|
83
112
|
return { kind: 'paused', plane: 'cause', ...(pauseOf(c) ?? {}) };
|
package/dist/seam.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export function sessionPolicyFaceAvailable(reading) {
|
|
|
34
34
|
export function sessionPolicyDoctorDetail(reading) {
|
|
35
35
|
switch (reading.kind) {
|
|
36
36
|
case 'unobserved':
|
|
37
|
-
return 'per-session rule face not observed — the engine reports it on /v1/capabilities (sessionPolicy); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
37
|
+
return 'per-session rule face not observed — the engine reports it on /v1/capabilities (sessionPolicy); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
38
38
|
case 'not_reported':
|
|
39
39
|
return 'per-session rule face not reported by this engine — this binary predates the position itself; it says nothing about whether the face exists, so read the rules rather than writing them blind';
|
|
40
40
|
case 'absent':
|
|
@@ -33,9 +33,9 @@ export function sessionSyncFileHistoryAvailable(reading) {
|
|
|
33
33
|
export function sessionSyncFileHistoryDoctorDetail(reading) {
|
|
34
34
|
switch (reading.kind) {
|
|
35
35
|
case 'unobserved':
|
|
36
|
-
return 'session-sync file history not observed — the engine reports it on /v1/capabilities (sessionSyncFileHistory); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
36
|
+
return 'session-sync file history not observed — the engine reports it on /v1/capabilities (sessionSyncFileHistory); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
37
37
|
case 'not_reported':
|
|
38
|
-
return 'session-sync file history not reported by this engine
|
|
38
|
+
return 'session-sync file history not reported separately by this engine; this does not say whether file history can be synced';
|
|
39
39
|
case 'absent':
|
|
40
40
|
return 'no session-sync file history on this deployment — syncing a session moves the conversation only; edited-file history stays behind';
|
|
41
41
|
case 'present':
|
|
@@ -33,7 +33,7 @@ export function skillToolListsAvailable(reading) {
|
|
|
33
33
|
export function skillToolListsDoctorDetail(reading) {
|
|
34
34
|
switch (reading.kind) {
|
|
35
35
|
case 'unobserved':
|
|
36
|
-
return 'skill tool lists not observed — the engine reports it on /v1/capabilities (skillToolLists); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
36
|
+
return 'skill tool lists not observed — the engine reports it on /v1/capabilities (skillToolLists); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
37
37
|
case 'not_reported':
|
|
38
38
|
return 'skill tool lists not reported by this engine — the engine predates them: tool lists on request skills are not read, so they do not limit any tool';
|
|
39
39
|
case 'absent':
|
|
@@ -52,7 +52,7 @@ export function sqlEngineDoctorDetail(reading) {
|
|
|
52
52
|
switch (reading.kind) {
|
|
53
53
|
case 'unobserved':
|
|
54
54
|
return ('not observed — the engine reports it on /v1/capabilities; this process has no usable ' +
|
|
55
|
-
'capabilities reading cached for it (none received, or the last one was
|
|
55
|
+
'capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)');
|
|
56
56
|
case 'not_reported':
|
|
57
57
|
return 'not reported by this engine — the capability position needs a newer engine';
|
|
58
58
|
case 'none':
|
|
@@ -61,7 +61,7 @@ export function steerPriorityDoctorDetail(reading) {
|
|
|
61
61
|
return unobserved;
|
|
62
62
|
}
|
|
63
63
|
if (kind === 'not_reported') {
|
|
64
|
-
return 'steer priority not reported by this engine —
|
|
64
|
+
return 'steer priority not reported by this engine — its capabilities reading carries no fleet.steerPriority (the fleet face is not reported, or the face carries no such field; this client cannot tell which), so a "now" or "later" steer is not sent (steers without a priority work as before)';
|
|
65
65
|
}
|
|
66
66
|
if (kind !== 'present' || typeof word !== 'string' || word.length === 0)
|
|
67
67
|
return unobserved;
|
|
@@ -90,7 +90,7 @@ export function storePostureDoctorDetail(reading) {
|
|
|
90
90
|
const unobserved = 'store posture not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this deployment persists its state is unknown';
|
|
91
91
|
const r = presentView(reading);
|
|
92
92
|
if (r?.kind === 'not_reported') {
|
|
93
|
-
return 'store posture not reported by this engine
|
|
93
|
+
return 'store posture not reported by this engine; this does not say whether this deployment persists its state';
|
|
94
94
|
}
|
|
95
95
|
if (r?.kind !== 'present')
|
|
96
96
|
return unobserved;
|
|
@@ -120,7 +120,7 @@ export function storePostureDoctorDetail(reading) {
|
|
|
120
120
|
return `${assembled} — ${lost} (degraded: the declared database could not be opened at start-up, so the engine fell back rather than refusing to start)`;
|
|
121
121
|
}
|
|
122
122
|
if (reason === 'local_unwritable') {
|
|
123
|
-
return `${assembled} — ${lost} (degraded: the default local file store could not be created
|
|
123
|
+
return `${assembled} — ${lost} (degraded: the default local file store could not be created — a read-only or full data directory is one possible cause, and this client cannot tell which applies)`;
|
|
124
124
|
}
|
|
125
125
|
return `${assembled} — ${lost} (degraded for a reason this client does not know yet: "${word(reason)}")`;
|
|
126
126
|
}
|
package/dist/supportFloor.d.ts
CHANGED
|
@@ -8,3 +8,4 @@ export declare const SUPPORT_FLOOR: Readonly<SupportFloor>;
|
|
|
8
8
|
export declare function supportFloorOf(component: unknown): string | undefined;
|
|
9
9
|
export type EngineVersionTier = 'engine' | 'legacy' | 'unknown';
|
|
10
10
|
export declare function engineVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
|
11
|
+
export declare function coreVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
package/dist/supportFloor.js
CHANGED
|
@@ -25,12 +25,16 @@ function compareTriple(a, b) {
|
|
|
25
25
|
}
|
|
26
26
|
return 0;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
function versionTierAgainst(version, base, floor, caller) {
|
|
29
|
+
const baseTriple = releaseTriple(base);
|
|
30
|
+
if (baseTriple === undefined) {
|
|
31
|
+
throw new TypeError(`${caller}: 门槛只接受纯 x.y.z 版本串(整串、无前导零、无前后缀)—— 收到 typeof=${base === null ? 'null' : typeof base}。错误文本只报形状,不回显值。`);
|
|
32
|
+
}
|
|
33
|
+
let need = baseTriple;
|
|
30
34
|
if (floor !== undefined) {
|
|
31
35
|
const own = releaseTriple(floor);
|
|
32
36
|
if (own === undefined) {
|
|
33
|
-
throw new TypeError(
|
|
37
|
+
throw new TypeError(`${caller}: floor 只接受纯 x.y.z 版本串(整串、无前导零、无前后缀)或缺席 —— 收到 typeof=${floor === null ? 'null' : typeof floor}。错误文本只报形状,不回显值。`);
|
|
34
38
|
}
|
|
35
39
|
if (compareTriple(own, need) > 0)
|
|
36
40
|
need = own;
|
|
@@ -40,3 +44,9 @@ export function engineVersionTier(version, floor) {
|
|
|
40
44
|
return 'unknown';
|
|
41
45
|
return compareTriple(got, need) >= 0 ? 'engine' : 'legacy';
|
|
42
46
|
}
|
|
47
|
+
export function engineVersionTier(version, floor) {
|
|
48
|
+
return versionTierAgainst(version, SUPPORT_FLOOR.server, floor, 'engineVersionTier');
|
|
49
|
+
}
|
|
50
|
+
export function coreVersionTier(version, floor) {
|
|
51
|
+
return versionTierAgainst(version, SUPPORT_FLOOR.core, floor, 'coreVersionTier');
|
|
52
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { TaskRequest } from '@sema-agent/sdk';
|
|
2
2
|
export type TaskRequestReasoningEffort = NonNullable<TaskRequest['reasoningEffort']>;
|
|
3
3
|
export declare const REASONING_EFFORT_WORDS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
4
|
-
|
|
5
|
-
export
|
|
4
|
+
type SdkTaskRequestPermissionMode = NonNullable<TaskRequest['permissionMode']>;
|
|
5
|
+
export type TaskRequestPermissionMode = SdkTaskRequestPermissionMode | 'dontAsk';
|
|
6
|
+
export declare const PERMISSION_MODE_WORDS: readonly ["default", "plan", "acceptEdits", "bypassPermissions", "auto", "dontAsk"];
|
|
6
7
|
export interface RetiredAttachmentsKey {
|
|
7
8
|
readonly key: string;
|
|
8
9
|
readonly why: string;
|
|
@@ -10,3 +11,4 @@ export interface RetiredAttachmentsKey {
|
|
|
10
11
|
readonly remedy: string;
|
|
11
12
|
}
|
|
12
13
|
export declare function retiredAttachmentsKeyOf(nameOrToken: string, form?: 'token' | 'key'): RetiredAttachmentsKey | undefined;
|
|
14
|
+
export {};
|
package/dist/taskRequestWords.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const REASONING_EFFORT_WORDS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
|
|
2
|
-
export const PERMISSION_MODE_WORDS = ['default', 'plan', 'acceptEdits', 'bypassPermissions', 'auto'];
|
|
2
|
+
export const PERMISSION_MODE_WORDS = ['default', 'plan', 'acceptEdits', 'bypassPermissions', 'auto', 'dontAsk'];
|
|
3
3
|
const _taskRequestWordPins = [true, true, true, true];
|
|
4
4
|
void _taskRequestWordPins;
|
|
5
5
|
export function retiredAttachmentsKeyOf(nameOrToken, form = 'token') {
|
|
@@ -2,8 +2,7 @@ import { displayUntrusted } from './displayUntrusted.js';
|
|
|
2
2
|
const BAD_TURN_PREVIEW_MAX = 60;
|
|
3
3
|
export function toolHistoryBadTurnSentence(promptText) {
|
|
4
4
|
const text = typeof promptText === 'string' ? promptText : '';
|
|
5
|
-
const
|
|
6
|
-
const washed = displayUntrusted(flat, { foldLines: false, mark: 'dot' });
|
|
5
|
+
const washed = displayUntrusted(stripDisplayTagBlocks(text), { mark: 'dot' }).replace(/\s+/g, ' ').trim();
|
|
7
6
|
const points = Array.from(washed);
|
|
8
7
|
const preview = points.length > BAD_TURN_PREVIEW_MAX ? `${points.slice(0, BAD_TURN_PREVIEW_MAX).join('')}...` : washed;
|
|
9
8
|
return preview.length > 0
|
package/dist/toolResult.d.ts
CHANGED
|
@@ -100,7 +100,8 @@ export interface EngineBgShellRegistration {
|
|
|
100
100
|
receipt: string;
|
|
101
101
|
source: 'bash' | 'monitor';
|
|
102
102
|
}
|
|
103
|
-
export declare function detectEngineBgShellReceipt(toolName: string, rawInput: unknown, outputText: string | undefined): EngineBgShellRegistration | null;
|
|
103
|
+
export declare function detectEngineBgShellReceipt(toolName: string, rawInput: unknown, outputText: string | undefined, structured?: unknown): EngineBgShellRegistration | null;
|
|
104
|
+
export declare function detectEngineBgShellDetach(toolName: string, rawInput: unknown, structured: unknown, outputText: string | undefined): EngineBgShellRegistration | null;
|
|
104
105
|
export declare function todoWriteToolUseResult(rawInput: unknown, oldTodos: unknown[], isError: boolean): {
|
|
105
106
|
toolUseResult: unknown;
|
|
106
107
|
isError: boolean;
|
package/dist/toolResult.js
CHANGED
|
@@ -674,7 +674,7 @@ export function structuredToToolUseResult(structured, modelText, leaderLedger =
|
|
|
674
674
|
return null;
|
|
675
675
|
}
|
|
676
676
|
}
|
|
677
|
-
export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
677
|
+
export function detectEngineBgShellReceipt(toolName, rawInput, outputText, structured) {
|
|
678
678
|
if (typeof outputText !== 'string')
|
|
679
679
|
return null;
|
|
680
680
|
const input = (rawInput ?? {});
|
|
@@ -683,6 +683,8 @@ export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
|
683
683
|
if (toolName === 'Bash') {
|
|
684
684
|
if (input.run_in_background !== true)
|
|
685
685
|
return null;
|
|
686
|
+
if (readBashDetachView(structured)?.registerFailed === true)
|
|
687
|
+
return null;
|
|
686
688
|
m = THREE_GEN_BG_RECEIPT_RE.exec(outputText);
|
|
687
689
|
source = 'bash';
|
|
688
690
|
}
|
|
@@ -695,17 +697,45 @@ export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
|
695
697
|
}
|
|
696
698
|
if (!m?.[1])
|
|
697
699
|
return null;
|
|
700
|
+
return engineBgShellRegistrationBody(m[1], input, outputText, source);
|
|
701
|
+
}
|
|
702
|
+
function engineBgShellRegistrationBody(taskId, rawInput, receipt, source) {
|
|
703
|
+
const input = (rawInput ?? {});
|
|
698
704
|
const command = typeof input.command === 'string' ? input.command : '(engine bash)';
|
|
699
705
|
const description = typeof input.description === 'string' ? input.description : undefined;
|
|
700
706
|
return {
|
|
701
707
|
kind: 'register',
|
|
702
|
-
taskId
|
|
708
|
+
taskId,
|
|
703
709
|
command,
|
|
704
710
|
...(description !== undefined ? { description } : {}),
|
|
705
|
-
receipt
|
|
711
|
+
receipt,
|
|
706
712
|
source,
|
|
707
713
|
};
|
|
708
714
|
}
|
|
715
|
+
export function detectEngineBgShellDetach(toolName, rawInput, structured, outputText) {
|
|
716
|
+
if (toolName !== 'Bash')
|
|
717
|
+
return null;
|
|
718
|
+
const view = readBashDetachView(structured);
|
|
719
|
+
if (view === null || !view.detached || view.registerFailed || view.taskId === undefined)
|
|
720
|
+
return null;
|
|
721
|
+
return engineBgShellRegistrationBody(view.taskId, rawInput, typeof outputText === 'string' ? outputText : '', 'bash');
|
|
722
|
+
}
|
|
723
|
+
function readBashDetachView(structured) {
|
|
724
|
+
if (typeof structured !== 'object' || structured === null)
|
|
725
|
+
return null;
|
|
726
|
+
const s = structured;
|
|
727
|
+
const type = s.type;
|
|
728
|
+
if (type !== 'bash')
|
|
729
|
+
return null;
|
|
730
|
+
const detached = s.detached;
|
|
731
|
+
const registerFailed = s.registerFailed;
|
|
732
|
+
const taskId = s.task_id;
|
|
733
|
+
return {
|
|
734
|
+
detached: detached === true,
|
|
735
|
+
registerFailed: registerFailed === true,
|
|
736
|
+
taskId: typeof taskId === 'string' && taskId.length > 0 ? taskId : undefined,
|
|
737
|
+
};
|
|
738
|
+
}
|
|
709
739
|
export function todoWriteToolUseResult(rawInput, oldTodos, isError) {
|
|
710
740
|
const todos = rawInput?.todos;
|
|
711
741
|
if (!Array.isArray(todos))
|
|
@@ -33,7 +33,7 @@ export function userInvokedSkillsAvailable(reading) {
|
|
|
33
33
|
export function userInvokedSkillsDoctorDetail(reading) {
|
|
34
34
|
switch (reading.kind) {
|
|
35
35
|
case 'unobserved':
|
|
36
|
-
return 'user-invoked skills not observed — the engine reports it on /v1/capabilities (userInvokedSkills); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
36
|
+
return 'user-invoked skills not observed — the engine reports it on /v1/capabilities (userInvokedSkills); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
37
37
|
case 'not_reported':
|
|
38
38
|
return 'user-invoked skills not reported by this engine — the engine predates it, so naming skills on a request is refused (do not send the key)';
|
|
39
39
|
case 'absent':
|
|
@@ -38,9 +38,9 @@ export function webSearchBackendDoctorDetail(reading) {
|
|
|
38
38
|
switch (reading.kind) {
|
|
39
39
|
case 'unobserved':
|
|
40
40
|
return ('deployment default backend not observed — the engine reports it on /v1/capabilities; ' +
|
|
41
|
-
'this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
41
|
+
'this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)');
|
|
42
42
|
case 'not_reported':
|
|
43
|
-
return ('deployment default backend not reported by this engine
|
|
43
|
+
return ('deployment default backend not reported by this engine; ' +
|
|
44
44
|
'this does not say whether the deployment has a search backend');
|
|
45
45
|
case 'none':
|
|
46
46
|
return (`deployment default backend none — ${DEPLOY_ENV} is unset or not a provider word on the engine, ` +
|
|
@@ -32,6 +32,37 @@ function judgeText(raw) {
|
|
|
32
32
|
return { ok: false, issue: 'must be a string' };
|
|
33
33
|
return { ok: true, value: isBlankText(raw) ? undefined : raw };
|
|
34
34
|
}
|
|
35
|
+
const API_KEY_ISSUE = 'must be usable as an HTTP header value (it contains a character an HTTP header cannot carry, such as a line break)';
|
|
36
|
+
const isHttpWhitespaceCode = (c) => c === 0x09 || c === 0x0a || c === 0x0d || c === 0x20;
|
|
37
|
+
function isHttpHeaderValue(value) {
|
|
38
|
+
let start = 0;
|
|
39
|
+
let end = value.length;
|
|
40
|
+
while (start < end && isHttpWhitespaceCode(value.charCodeAt(start)))
|
|
41
|
+
start++;
|
|
42
|
+
while (end > start && isHttpWhitespaceCode(value.charCodeAt(end - 1)))
|
|
43
|
+
end--;
|
|
44
|
+
for (let i = start; i < end; i++) {
|
|
45
|
+
const c = value.charCodeAt(i);
|
|
46
|
+
if (!(c === 0x09 || (c >= 0x20 && c <= 0x7e) || (c >= 0x80 && c <= 0xff)))
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
function apiKeyHeaderValue(provider, key) {
|
|
52
|
+
switch (provider) {
|
|
53
|
+
case 'brave':
|
|
54
|
+
case 'searxng':
|
|
55
|
+
return key;
|
|
56
|
+
case 'tavily':
|
|
57
|
+
return `Bearer ${key}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function judgeApiKey(provider, raw) {
|
|
61
|
+
const text = judgeText(raw);
|
|
62
|
+
if (!text.ok || text.value === undefined)
|
|
63
|
+
return text;
|
|
64
|
+
return isHttpHeaderValue(apiKeyHeaderValue(provider, text.value)) ? text : { ok: false, issue: API_KEY_ISSUE };
|
|
65
|
+
}
|
|
35
66
|
const ENDPOINT_ISSUE = 'must be an absolute URL with a scheme and a host, such as https://search.example.com (a bare host or host:port is not one)';
|
|
36
67
|
function judgeEndpoint(raw) {
|
|
37
68
|
if (raw === undefined || raw === null)
|
|
@@ -114,9 +145,10 @@ function judgeSection(raw, source, apiKeyFor) {
|
|
|
114
145
|
injected = undefined;
|
|
115
146
|
}
|
|
116
147
|
}
|
|
117
|
-
const
|
|
148
|
+
const useInjected = typeof injected === 'string' && !isBlankText(injected);
|
|
149
|
+
const apiKey = judgeApiKey(provider.value, useInjected ? injected : s.apiKey);
|
|
118
150
|
if (!apiKey.ok)
|
|
119
|
-
return { kind: 'malformed', source, field: 'apiKey', issue: apiKey.issue };
|
|
151
|
+
return { kind: 'malformed', source: useInjected ? 'host' : source, field: 'apiKey', issue: apiKey.issue };
|
|
120
152
|
const endpoint = judgeEndpoint(s.endpoint);
|
|
121
153
|
if (!endpoint.ok)
|
|
122
154
|
return { kind: 'malformed', source, field: 'endpoint', issue: endpoint.issue };
|
|
@@ -191,6 +223,12 @@ function envNameOfField(field) {
|
|
|
191
223
|
export function webSearchVerdictMessage(verdict, context = 'submit') {
|
|
192
224
|
if (verdict.kind !== 'malformed')
|
|
193
225
|
return undefined;
|
|
226
|
+
if (verdict.source === 'host') {
|
|
227
|
+
const head = `Web search is misconfigured: the API key your host supplied for webSearch is malformed; it ${verdict.issue}.`;
|
|
228
|
+
return context === 'submit'
|
|
229
|
+
? `${head} The request was not sent — the key needs replacing where your host keeps it.`
|
|
230
|
+
: `${head} Requests will be refused until the key is replaced where your host keeps it.`;
|
|
231
|
+
}
|
|
194
232
|
const where = verdict.source === 'env' ? envNameOfField(verdict.field) : verdict.field === 'section' ? 'the webSearch section in settings' : `webSearch.${verdict.field} in settings`;
|
|
195
233
|
const fix = verdict.source === 'env' ? 'fix it or unset the SEMA_WEBSEARCH_* variables' : 'fix it or remove the webSearch section';
|
|
196
234
|
return context === 'submit'
|
package/dist/wireFailureShape.js
CHANGED
|
@@ -66,9 +66,9 @@ export function readErrorStrictStringList(o, key) {
|
|
|
66
66
|
return true;
|
|
67
67
|
};
|
|
68
68
|
const v = readErrorSlot(o, key, strict);
|
|
69
|
-
if (!Array.isArray(v))
|
|
70
|
-
return undefined;
|
|
71
69
|
try {
|
|
70
|
+
if (!Array.isArray(v))
|
|
71
|
+
return undefined;
|
|
72
72
|
const out = [];
|
|
73
73
|
const len = v.length;
|
|
74
74
|
for (let i = 0; i < len; i++) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FLEET_LEASE_UNAVAILABLE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
1
|
+
import { FLEET_LEASE_UNAVAILABLE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
2
2
|
import type { TaskRequestLike } from './request/taskRequest.js';
|
|
3
3
|
export declare const CONFLICT_APPROVAL_SETTLED = "conflict.approval_settled";
|
|
4
4
|
export declare const CONFLICT_RUN_NOT_RUNNING = "conflict.run_not_running";
|
|
@@ -22,14 +22,20 @@ export interface FleetLeaseUnavailableDetail {
|
|
|
22
22
|
}
|
|
23
23
|
export declare function fleetLeaseUnavailableFromError(err: unknown): FleetLeaseUnavailableDetail | null;
|
|
24
24
|
export declare function fleetLeaseUnavailableContent(detail: FleetLeaseUnavailableDetail): string;
|
|
25
|
-
export
|
|
25
|
+
export interface ScenarioAssignmentUnknownDetail {
|
|
26
|
+
code: typeof SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE;
|
|
27
|
+
scenario?: string;
|
|
28
|
+
source?: 'ruling' | 'deployment';
|
|
29
|
+
}
|
|
30
|
+
export declare function scenarioAssignmentUnknownFromError(err: unknown): ScenarioAssignmentUnknownDetail | null;
|
|
31
|
+
export type DenyAttributionRefusalKind = 'not_in_proof' | 'decision_conflict' | 'attribution_rejected' | 'retired_key';
|
|
26
32
|
export interface DenyAttributionRefusalDetail {
|
|
27
33
|
kind: DenyAttributionRefusalKind;
|
|
28
34
|
code: string;
|
|
29
35
|
status: number;
|
|
30
36
|
field?: string;
|
|
31
37
|
}
|
|
32
|
-
export declare function denyAttributionRefusalFromError(err: unknown,
|
|
38
|
+
export declare function denyAttributionRefusalFromError(err: unknown, sentAttributionKey: boolean): DenyAttributionRefusalDetail | null;
|
|
33
39
|
export declare function denyAttributionRefusalContent(detail: Pick<DenyAttributionRefusalDetail, 'kind' | 'field'>): string;
|
|
34
40
|
export declare const CONFLICT_SESSION_CHILDREN_ALIVE = "conflict.session_children_alive";
|
|
35
41
|
export type SessionDeleteConflictKind = 'children_alive' | 'active_run' | 'unrecognized';
|
package/dist/wireRefusalCopy.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readErrorNumber, readErrorRecord, readErrorStrictStringList, readErrorString, readErrorStringList } from './wireFailureShape.js';
|
|
2
2
|
import { readOwnNonEmptyString } from './ownKey.js';
|
|
3
|
-
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_FIELD_CONFLICT, RESUME_POLICY_FOLD_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
3
|
+
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_FIELD_CONFLICT, RESUME_POLICY_FOLD_CODE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
4
4
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
5
5
|
import { effectiveWireErrorCode } from './wireErrorTriage.js';
|
|
6
6
|
import { CORE_TOOL_DECLARATION_CODES } from './generated/engineFactTables.js';
|
|
@@ -145,7 +145,38 @@ export function fleetLeaseUnavailableContent(detail) {
|
|
|
145
145
|
: ' · The engine did not say how long to wait — send it again a little later';
|
|
146
146
|
return `${head}${cause}${wait}`;
|
|
147
147
|
}
|
|
148
|
+
export function scenarioAssignmentUnknownFromError(err) {
|
|
149
|
+
try {
|
|
150
|
+
if (err === null || typeof err !== 'object')
|
|
151
|
+
return null;
|
|
152
|
+
if (effectiveWireErrorCode(err) !== SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE)
|
|
153
|
+
return null;
|
|
154
|
+
const detail = readErrorRecord(err, 'detail');
|
|
155
|
+
const bit = (key) => {
|
|
156
|
+
if (detail === undefined)
|
|
157
|
+
return undefined;
|
|
158
|
+
try {
|
|
159
|
+
return Object.hasOwn(detail, key) ? detail[key] : undefined;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const scenario = bit('scenario');
|
|
166
|
+
const source = bit('source');
|
|
167
|
+
return {
|
|
168
|
+
code: SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE,
|
|
169
|
+
...(typeof scenario === 'string' && scenario.length > 0 ? { scenario } : {}),
|
|
170
|
+
...(source === 'ruling' || source === 'deployment' ? { source } : {}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
148
177
|
const SETTLED_BY_NOT_IN_PROOF = 'settled_by_not_in_proof';
|
|
178
|
+
const DECIDED_BY_NOT_IN_PROOF = 'decided_by_not_in_proof';
|
|
179
|
+
const RETIRED_DECISION_KEY = 'settledBy';
|
|
149
180
|
const RESUME_OUTCOME_INVALID = 'resume_outcome_invalid';
|
|
150
181
|
const APPROVAL_NON_BINDING_FIELDS = new Set(['hostDecision', 'approver']);
|
|
151
182
|
function readRefusalField(o) {
|
|
@@ -163,7 +194,7 @@ function readRefusalField(o) {
|
|
|
163
194
|
}
|
|
164
195
|
return readStringField(o, 'field');
|
|
165
196
|
}
|
|
166
|
-
export function denyAttributionRefusalFromError(err,
|
|
197
|
+
export function denyAttributionRefusalFromError(err, sentAttributionKey) {
|
|
167
198
|
try {
|
|
168
199
|
if (err === null || typeof err !== 'object')
|
|
169
200
|
return null;
|
|
@@ -175,9 +206,12 @@ export function denyAttributionRefusalFromError(err, sentSettledBy) {
|
|
|
175
206
|
const code = readStringField(o, 'errorCode');
|
|
176
207
|
if (code === undefined)
|
|
177
208
|
return null;
|
|
178
|
-
if (status === 400 && code === SETTLED_BY_NOT_IN_PROOF)
|
|
209
|
+
if (status === 400 && (code === SETTLED_BY_NOT_IN_PROOF || code === DECIDED_BY_NOT_IN_PROOF))
|
|
179
210
|
return { kind: 'not_in_proof', code, status };
|
|
180
|
-
if (status === 400 && code ===
|
|
211
|
+
if (status === 400 && code === BODY_SHAPE && readRefusalField(o) === RETIRED_DECISION_KEY) {
|
|
212
|
+
return { kind: 'retired_key', code, status, field: RETIRED_DECISION_KEY };
|
|
213
|
+
}
|
|
214
|
+
if (status === 400 && code === REQUEST_FIELD_CONFLICT && sentAttributionKey) {
|
|
181
215
|
return { kind: 'decision_conflict', code, status };
|
|
182
216
|
}
|
|
183
217
|
if (status === 409 && code === RESUME_OUTCOME_INVALID) {
|
|
@@ -202,6 +236,9 @@ export function denyAttributionRefusalContent(detail) {
|
|
|
202
236
|
return ('The engine refused this decision before judging it: the body says a policy settled it and also asks to allow the call, ' +
|
|
203
237
|
'and only a person can allow one · Nothing was decided and the approval is still waiting — ' +
|
|
204
238
|
'send it again with the decision and the note in agreement');
|
|
239
|
+
case 'retired_key':
|
|
240
|
+
return ('The engine refused this decision before judging it: the note saying who settled it was sent under a name this engine no longer accepts · ' +
|
|
241
|
+
'Nothing was decided and the approval is still waiting — send the decision again with who made it given under the name the engine now takes in its place');
|
|
205
242
|
case 'attribution_rejected': {
|
|
206
243
|
const named = typeof detail.field === 'string' && APPROVAL_NON_BINDING_FIELDS.has(detail.field)
|
|
207
244
|
? ` It named ${detail.field} as the part it would not take.`
|
|
@@ -33,7 +33,7 @@ export function workflowsJournalAvailable(reading) {
|
|
|
33
33
|
export function workflowsJournalDoctorDetail(reading) {
|
|
34
34
|
switch (reading.kind) {
|
|
35
35
|
case 'unobserved':
|
|
36
|
-
return 'workflow journal not observed — the engine reports it on /v1/capabilities (workflowsJournal); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
36
|
+
return 'workflow journal not observed — the engine reports it on /v1/capabilities (workflowsJournal); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
37
37
|
case 'not_reported':
|
|
38
38
|
return 'workflow journal not reported by this engine — the engine predates the separate flag, so the workflow listing flag still covers the journal';
|
|
39
39
|
case 'absent':
|
|
@@ -75,7 +75,7 @@ export function writeProtectionDoctorDetail(reading) {
|
|
|
75
75
|
switch (reading.kind) {
|
|
76
76
|
case 'unobserved':
|
|
77
77
|
return ('not observed — the engine reports it on /v1/capabilities; this process has no usable ' +
|
|
78
|
-
'capabilities reading cached for it (none received, or the last one was
|
|
78
|
+
'capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)');
|
|
79
79
|
case 'not_reported':
|
|
80
80
|
return ('not reported by this engine — the capability position needs a newer engine; this says ' +
|
|
81
81
|
'nothing about whether a protected-name table is in effect (an absent seat is the engine ' +
|