@sema-agent/client-core 0.96.0 → 0.97.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/README.md +29 -22
- package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
- package/dist/adapter/activeRunSelfHeal.js +7 -7
- package/dist/adapter/downstream/terminalToSdkResult.js +6 -2
- package/dist/agentSession/backgroundView.js +2 -15
- package/dist/agentsWireCaps.d.ts +3 -1
- package/dist/agentsWireCaps.js +67 -39
- package/dist/approvalDecidedByCapability.d.ts +2 -0
- package/dist/approvalDecidedByCapability.js +0 -1
- package/dist/approvalsStreamLiveCapability.d.ts +2 -0
- package/dist/approvalsStreamLiveCapability.js +3 -2
- package/dist/attachmentSeatCapability.d.ts +2 -0
- package/dist/attachmentSeatCapability.js +0 -1
- package/dist/callerCwdCapability.d.ts +2 -0
- package/dist/callerCwdCapability.js +0 -1
- package/dist/centerWiringCapability.d.ts +2 -0
- package/dist/centerWiringCapability.js +4 -3
- package/dist/cloudConfigWireCaps.d.ts +2 -2
- package/dist/cloudConfigWireCaps.js +192 -56
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/deviceExecutorManagementCapability.d.ts +2 -0
- package/dist/deviceExecutorManagementCapability.js +3 -2
- package/dist/displayUntrusted.d.ts +3 -0
- package/dist/displayUntrusted.js +15 -0
- package/dist/engineCapReader.d.ts +8 -2
- package/dist/engineCapReader.js +15 -7
- package/dist/engineCapsCache.d.ts +11 -3
- package/dist/engineCapsCache.js +54 -23
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +9 -1
- package/dist/engineNoticeCodes.js +2 -3
- package/dist/engineToolDirectory.d.ts +27 -0
- package/dist/engineToolDirectory.js +178 -0
- package/dist/executionLaneCapability.d.ts +2 -0
- package/dist/executionLaneCapability.js +3 -2
- package/dist/fileHistoryCaptureCapability.d.ts +2 -0
- package/dist/fileHistoryCaptureCapability.js +34 -8
- package/dist/fileHistoryLegNotice.js +4 -0
- package/dist/fleet/fleetLedger.js +129 -105
- package/dist/gateOutcome.js +2 -4
- package/dist/gateVocabulary.d.ts +1 -6
- package/dist/gateVocabulary.js +2 -5
- package/dist/generated/sdkFactTables.d.ts +2 -0
- package/dist/generated/sdkFactTables.js +7 -0
- package/dist/generated/toolNameTables.d.ts +0 -1
- package/dist/generated/toolNameTables.js +0 -42
- package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
- package/dist/hitl/approvalEndingCause.js +2 -7
- package/dist/hitl/approvalHolds.d.ts +16 -1
- package/dist/hitl/approvalHolds.js +52 -12
- package/dist/hitl/askGateWire.js +1 -0
- package/dist/hitl/automaticAnswerVerdict.js +5 -7
- package/dist/hitl/decisionConflict.js +4 -3
- package/dist/hitl/decisionRefusal.js +19 -12
- package/dist/hitl/frameRouter.d.ts +3 -0
- package/dist/hitl/frameRouter.js +52 -25
- package/dist/hitl/gateLedger.d.ts +0 -5
- package/dist/hitl/gateLedger.js +0 -21
- package/dist/hitl/hitlBridge.js +18 -4
- package/dist/hitl/parkResolver.js +7 -3
- package/dist/hitl/replayedApproval.d.ts +2 -3
- package/dist/hitl/replayedApproval.js +7 -16
- package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
- package/dist/hitl/sessionPolicyDeliverable.js +15 -17
- package/dist/hitl/sessionPolicyWire.d.ts +2 -0
- package/dist/hitl/sessionPolicyWire.js +15 -3
- package/dist/hitl/standingRows.d.ts +1 -0
- package/dist/hitl/standingRows.js +38 -17
- package/dist/hitl/suspendedReopen.js +2 -1
- package/dist/hitl/toolApprovalWire.d.ts +8 -8
- package/dist/hitl/toolApprovalWire.js +50 -24
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -3
- package/dist/liveModelCatalog.d.ts +13 -0
- package/dist/liveModelCatalog.js +56 -0
- package/dist/mcpProbeCapability.d.ts +2 -0
- package/dist/mcpProbeCapability.js +3 -2
- package/dist/mcpWireCaps.d.ts +1 -0
- package/dist/mcpWireCaps.js +4 -1
- package/dist/memoryComplianceCapability.d.ts +2 -0
- package/dist/memoryComplianceCapability.js +3 -2
- package/dist/memoryOriginCapability.d.ts +2 -0
- package/dist/memoryOriginCapability.js +3 -2
- package/dist/modelIdentityResolvability.js +2 -2
- package/dist/noticePresentation.js +2 -2
- package/dist/outputStyleSeatCapability.d.ts +2 -0
- package/dist/outputStyleSeatCapability.js +0 -1
- package/dist/peerLaneCapability.d.ts +2 -0
- package/dist/peerLaneCapability.js +3 -2
- package/dist/permissionModesCapability.d.ts +2 -0
- package/dist/permissionModesCapability.js +0 -1
- package/dist/permissionRulesWriteCapability.d.ts +2 -0
- package/dist/permissionRulesWriteCapability.js +3 -2
- package/dist/permissionsAllowGrantCapability.d.ts +2 -0
- package/dist/permissionsAllowGrantCapability.js +4 -2
- package/dist/permissionsDeclaration.js +19 -21
- package/dist/request/taskRequest.d.ts +1 -4
- package/dist/request/taskRequest.js +74 -19
- package/dist/resumeRefusalCopy.js +4 -4
- package/dist/rewindArchiveCapability.js +5 -0
- package/dist/rewindArchiveReading.d.ts +2 -0
- package/dist/rewindArchiveReading.js +0 -1
- package/dist/runTerminal.d.ts +33 -4
- package/dist/runTerminal.js +170 -15
- package/dist/sdkWireTransit.d.ts +2 -1
- package/dist/sdkWireTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +2 -0
- package/dist/sealedKeyCapability.js +0 -1
- package/dist/seatContract.d.ts +7 -4
- package/dist/seatContract.js +34 -20
- package/dist/sessionPolicyCapability.d.ts +2 -0
- package/dist/sessionPolicyCapability.js +3 -2
- package/dist/sessionReadRedactionCapability.d.ts +2 -0
- package/dist/sessionReadRedactionCapability.js +0 -1
- package/dist/sessionSyncFileHistoryCapability.d.ts +2 -0
- package/dist/sessionSyncFileHistoryCapability.js +3 -2
- package/dist/skillToolListsCapability.d.ts +2 -0
- package/dist/skillToolListsCapability.js +3 -2
- package/dist/sqlEngineCapability.d.ts +2 -0
- package/dist/sqlEngineCapability.js +4 -3
- package/dist/steerPriorityCapability.d.ts +2 -0
- package/dist/steerPriorityCapability.js +3 -2
- package/dist/storePostureCapability.d.ts +2 -0
- package/dist/storePostureCapability.js +4 -3
- package/dist/toolHistoryBadTurn.js +3 -2
- package/dist/toolResult.d.ts +11 -0
- package/dist/toolResult.js +53 -0
- package/dist/userInvokedSkillsCapability.d.ts +2 -0
- package/dist/userInvokedSkillsCapability.js +3 -2
- package/dist/webSearchBackendCapability.d.ts +2 -0
- package/dist/webSearchBackendCapability.js +3 -2
- package/dist/wireErrorTriage.js +58 -34
- package/dist/wireFailureShape.d.ts +1 -1
- package/dist/wireFailureShape.js +76 -25
- package/dist/workflowsJournalCapability.d.ts +2 -0
- package/dist/workflowsJournalCapability.js +3 -2
- package/dist/writeProtectionCapability.d.ts +2 -0
- package/dist/writeProtectionCapability.js +3 -2
- package/docs/INTEGRATION-CLIENTS.md +585 -14
- package/package.json +4 -4
- package/dist/engineRefusedToolName.d.ts +0 -1
- package/dist/engineRefusedToolName.js +0 -8
- package/dist/engineWordRenames.d.ts +0 -8
- package/dist/engineWordRenames.js +0 -13
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
2
2
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
|
-
import { storeSeatOf, createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
import { storeSeatOf, createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
4
4
|
import { projectSqlEngineCapability } from './sqlEngineCapability.js';
|
|
5
5
|
import { ownDataField } from './ownKey.js';
|
|
6
6
|
const nonEmpty = (v) => typeof v === 'string' && v !== '';
|
|
@@ -44,7 +44,6 @@ function projectStorePostureOf(caps) {
|
|
|
44
44
|
const reader = createEngineCapReader({
|
|
45
45
|
name: 'store',
|
|
46
46
|
project: projectStorePostureCapability,
|
|
47
|
-
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
48
47
|
});
|
|
49
48
|
export function observedStorePosture(baseUrl = engineWireTarget()?.baseUrl) {
|
|
50
49
|
return reader.observed(baseUrl);
|
|
@@ -54,7 +53,7 @@ function presentView(reading) {
|
|
|
54
53
|
return undefined;
|
|
55
54
|
try {
|
|
56
55
|
const kind = reading.kind;
|
|
57
|
-
if (kind === 'not_reported' || kind === 'unobserved')
|
|
56
|
+
if (kind === 'not_reported' || kind === 'unobserved' || kind === 'unreadable')
|
|
58
57
|
return { kind };
|
|
59
58
|
if (kind !== 'present')
|
|
60
59
|
return undefined;
|
|
@@ -89,6 +88,8 @@ const word = (v) => capForDisplay(v, WORD_DETAIL_MAX);
|
|
|
89
88
|
export function storePostureDoctorDetail(reading) {
|
|
90
89
|
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
90
|
const r = presentView(reading);
|
|
91
|
+
if (r?.kind === 'unreadable')
|
|
92
|
+
return unreadableReadingDetail('store posture');
|
|
92
93
|
if (r?.kind === 'not_reported') {
|
|
93
94
|
return 'store posture not reported by this engine; this does not say whether this deployment persists its state';
|
|
94
95
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { displayUntrusted } from './displayUntrusted.js';
|
|
1
|
+
import { displayUntrusted, markerSafeCut } 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
5
|
const washed = displayUntrusted(stripDisplayTagBlocks(text), { mark: 'dot' }).replace(/\s+/g, ' ').trim();
|
|
6
6
|
const points = Array.from(washed);
|
|
7
|
-
const
|
|
7
|
+
const head = points.length > BAD_TURN_PREVIEW_MAX ? points.slice(0, BAD_TURN_PREVIEW_MAX).join('') : undefined;
|
|
8
|
+
const preview = head === undefined ? washed : `${washed.slice(0, markerSafeCut(washed, head.length))}...`;
|
|
8
9
|
return preview.length > 0
|
|
9
10
|
? `The broken record is in the turn you started with "${preview}"; /rewind has that prompt preselected, so restore the conversation to before it.`
|
|
10
11
|
: 'The broken record is in the turn /rewind has preselected; restore the conversation to before it.';
|
package/dist/toolResult.d.ts
CHANGED
|
@@ -92,6 +92,17 @@ export interface ToolResultBody {
|
|
|
92
92
|
degraded?: typeof TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT;
|
|
93
93
|
}
|
|
94
94
|
export declare function degradedToolResultBody(isError: boolean): ToolResultBody;
|
|
95
|
+
export type ToolCardDegradedCause = 'not-executed' | 'error-without-detail' | 'no-result' | 'unrecognised';
|
|
96
|
+
export type ToolCardOutcomeReading = {
|
|
97
|
+
readonly kind: 'normal';
|
|
98
|
+
} | {
|
|
99
|
+
readonly kind: 'degraded';
|
|
100
|
+
readonly cause: ToolCardDegradedCause;
|
|
101
|
+
readonly text: string;
|
|
102
|
+
} | {
|
|
103
|
+
readonly kind: 'unreadable';
|
|
104
|
+
};
|
|
105
|
+
export declare function readToolCardOutcome(record: object | null | undefined): ToolCardOutcomeReading;
|
|
95
106
|
export declare function wireOutputToBody(toolName: string, output: unknown, isError: boolean, truncated: boolean, flatten: FlattenWireOutput, structured?: unknown, leaderLedger?: boolean): ToolResultBody;
|
|
96
107
|
export declare function structuredToToolUseResult(structured: unknown, modelText?: string, leaderLedger?: boolean): {
|
|
97
108
|
toolUseResult: unknown;
|
package/dist/toolResult.js
CHANGED
|
@@ -4,6 +4,7 @@ import { parseWorkflowPollEnvelope, projectWorkflowTaskOutput } from './workflow
|
|
|
4
4
|
import { asModelFallbackReason } from './engineErrorCodes.js';
|
|
5
5
|
import { frozenSet } from './frozenSet.js';
|
|
6
6
|
import { bashExitOf, bashExitReadingFailed } from './bashExitReading.js';
|
|
7
|
+
import { readFrameTrueMark } from './ownKey.js';
|
|
7
8
|
import { isCoreSemaTaskTerminal } from './terminalStatuses.js';
|
|
8
9
|
import { CORE_ENGINE_CARD_TYPES } from './generated/engineFactTables.js';
|
|
9
10
|
export const STRUCTURED_DETAIL_TYPES = frozenSet(CORE_ENGINE_CARD_TYPES);
|
|
@@ -276,6 +277,58 @@ export const TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT = 'wire_carried_no_output';
|
|
|
276
277
|
export function degradedToolResultBody(isError) {
|
|
277
278
|
return { content: '', isError, degraded: TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT };
|
|
278
279
|
}
|
|
280
|
+
const TOOL_CARD_DEGRADED_TEXT = {
|
|
281
|
+
'not-executed': 'This tool call did not run: the engine closed it without executing it.',
|
|
282
|
+
'error-without-detail': 'This tool call reported an error but returned no details.',
|
|
283
|
+
'no-result': 'No result was reported for this tool call, so whether it ran and what it did is not shown here — check before running it again.',
|
|
284
|
+
unrecognised: 'This tool call carries a result marker this client does not recognise, so no result is shown for it.',
|
|
285
|
+
};
|
|
286
|
+
const cardDegraded = (cause) => ({ kind: 'degraded', cause, text: TOOL_CARD_DEGRADED_TEXT[cause] });
|
|
287
|
+
function cardOwnData(o, key) {
|
|
288
|
+
const d = Object.getOwnPropertyDescriptor(o, key);
|
|
289
|
+
if (d === undefined)
|
|
290
|
+
return undefined;
|
|
291
|
+
if (!Object.hasOwn(d, 'value'))
|
|
292
|
+
throw new TypeError(`own property "${key}" is an accessor`);
|
|
293
|
+
return d.value;
|
|
294
|
+
}
|
|
295
|
+
const isCardRecordObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
296
|
+
function toolResultBlockOf(record) {
|
|
297
|
+
const message = cardOwnData(record, 'message');
|
|
298
|
+
if (!isCardRecordObject(message))
|
|
299
|
+
return undefined;
|
|
300
|
+
const content = cardOwnData(message, 'content');
|
|
301
|
+
if (!Array.isArray(content))
|
|
302
|
+
return undefined;
|
|
303
|
+
for (let i = 0; i < content.length; i++) {
|
|
304
|
+
const block = cardOwnData(content, String(i));
|
|
305
|
+
if (isCardRecordObject(block) && cardOwnData(block, 'type') === 'tool_result')
|
|
306
|
+
return block;
|
|
307
|
+
}
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
export function readToolCardOutcome(record) {
|
|
311
|
+
try {
|
|
312
|
+
if (!isCardRecordObject(record))
|
|
313
|
+
return { kind: 'unreadable' };
|
|
314
|
+
const block = toolResultBlockOf(record);
|
|
315
|
+
if (block === undefined)
|
|
316
|
+
return { kind: 'unreadable' };
|
|
317
|
+
if (readFrameTrueMark(record, '_sema_not_executed'))
|
|
318
|
+
return cardDegraded('not-executed');
|
|
319
|
+
const markerDesc = Object.getOwnPropertyDescriptor(record, '_sema_degraded');
|
|
320
|
+
if (markerDesc === undefined)
|
|
321
|
+
return { kind: 'normal' };
|
|
322
|
+
if (!Object.hasOwn(markerDesc, 'value'))
|
|
323
|
+
return { kind: 'unreadable' };
|
|
324
|
+
if (markerDesc.value !== TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT)
|
|
325
|
+
return cardDegraded('unrecognised');
|
|
326
|
+
return cardDegraded(cardOwnData(block, 'is_error') === true ? 'error-without-detail' : 'no-result');
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return { kind: 'unreadable' };
|
|
330
|
+
}
|
|
331
|
+
}
|
|
279
332
|
export function wireOutputToBody(toolName, output, isError, truncated, flatten, structured, leaderLedger = true) {
|
|
280
333
|
const text = flatten(output);
|
|
281
334
|
const name = (toolName || '').toLowerCase();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
-
import { createEngineCapReader } from './engineCapReader.js';
|
|
2
|
+
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
3
|
import { ownDataField } from './ownKey.js';
|
|
4
4
|
export function projectUserInvokedSkillsCapability(caps) {
|
|
5
5
|
try {
|
|
@@ -19,7 +19,6 @@ export function projectUserInvokedSkillsCapability(caps) {
|
|
|
19
19
|
const reader = createEngineCapReader({
|
|
20
20
|
name: 'userInvokedSkills',
|
|
21
21
|
project: projectUserInvokedSkillsCapability,
|
|
22
|
-
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
23
22
|
});
|
|
24
23
|
export function noteEngineCapsForUserInvokedSkills(baseUrl, caps, opts) {
|
|
25
24
|
reader.note(baseUrl, caps, opts);
|
|
@@ -36,6 +35,8 @@ export function userInvokedSkillsAvailable(reading) {
|
|
|
36
35
|
}
|
|
37
36
|
export function userInvokedSkillsDoctorDetail(reading) {
|
|
38
37
|
switch (reading.kind) {
|
|
38
|
+
case 'unreadable':
|
|
39
|
+
return unreadableReadingDetail('user-invoked skills');
|
|
39
40
|
case 'unobserved':
|
|
40
41
|
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)';
|
|
41
42
|
case 'not_reported':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
2
2
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
|
-
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
4
4
|
import { ownDataField } from './ownKey.js';
|
|
5
5
|
export const WEB_SEARCH_BACKEND_NONE = 'none';
|
|
6
6
|
export function projectWebSearchBackendCapability(caps) {
|
|
@@ -28,7 +28,6 @@ export function projectWebSearchBackendCapability(caps) {
|
|
|
28
28
|
const reader = createEngineCapReader({
|
|
29
29
|
name: 'webSearch.backend',
|
|
30
30
|
project: projectWebSearchBackendCapability,
|
|
31
|
-
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
32
31
|
});
|
|
33
32
|
export function noteEngineCapsForWebSearchBackend(baseUrl, caps, opts) {
|
|
34
33
|
reader.note(baseUrl, caps, opts);
|
|
@@ -40,6 +39,8 @@ const WS_DETAIL_MAX = 40;
|
|
|
40
39
|
const DEPLOY_ENV = 'WEB_SEARCH_PROVIDER';
|
|
41
40
|
export function webSearchBackendDoctorDetail(reading) {
|
|
42
41
|
switch (reading.kind) {
|
|
42
|
+
case 'unreadable':
|
|
43
|
+
return unreadableReadingDetail('deployment default backend');
|
|
43
44
|
case 'unobserved':
|
|
44
45
|
return ('deployment default backend not observed — the engine reports it on /v1/capabilities; ' +
|
|
45
46
|
'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)');
|
package/dist/wireErrorTriage.js
CHANGED
|
@@ -1,27 +1,51 @@
|
|
|
1
|
-
import { readBlockedBy, readErrorNumber, readErrorString, readErrorStringList } from './wireFailureShape.js';
|
|
1
|
+
import { readBlockedBy, readErrorNumber, readErrorString, readErrorStringList, readThrownSlot, thrownIsInstanceOf, THROWN_SLOT_UNREADABLE, WIRE_FAILURE_UNRENDERABLE_TEXT, } from './wireFailureShape.js';
|
|
2
2
|
import { capForDisplay, escapeDisplayControlChars } from './fleetTaskDesc.js';
|
|
3
3
|
import { readOwnDataValue } from './ownKey.js';
|
|
4
4
|
import { fleetLeaseUnavailableFromError } from './wireRefusalCopy.js';
|
|
5
|
-
import { DRAINING_ERROR_CODE, isCorruptSessionCode, RESUME_AT_ERROR_CODE_PREFIX, RESUME_POLICY_FOLD_CODE, RESUME_RETRY_LATER_CODES, RESUME_USAGE_WINDOW_EXHAUSTED, SCENARIO_NOT_ALLOWED_ERROR_CODE, } from './engineErrorCodes.js';
|
|
5
|
+
import { DRAINING_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, isCorruptSessionCode, RESUME_AT_ERROR_CODE_PREFIX, RESUME_POLICY_FOLD_CODE, RESUME_RETRY_LATER_CODES, RESUME_USAGE_WINDOW_EXHAUSTED, SCENARIO_NOT_ALLOWED_ERROR_CODE, } from './engineErrorCodes.js';
|
|
6
6
|
export const WIRE_NETWORK_ERROR_PATTERN = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|\bterminated\b|\bother side closed\b/i;
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
(
|
|
12
|
-
|
|
7
|
+
function readTurnErrorSlots(err) {
|
|
8
|
+
if (err === null || err === undefined)
|
|
9
|
+
return { status: undefined, errorCode: undefined, message: undefined, cause: undefined, name: undefined };
|
|
10
|
+
return {
|
|
11
|
+
status: readThrownSlot(err, 'status', 'data'),
|
|
12
|
+
errorCode: readThrownSlot(err, 'errorCode', 'data'),
|
|
13
|
+
message: readThrownSlot(err, 'message'),
|
|
14
|
+
cause: readThrownSlot(err, 'cause'),
|
|
15
|
+
name: typeof err === 'object' ? readThrownSlot(err, 'name') : undefined,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function renderedText(err) {
|
|
19
|
+
try {
|
|
20
|
+
return String(err);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return WIRE_FAILURE_UNRENDERABLE_TEXT;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function wireErrorDetailOf(slots, err) {
|
|
27
|
+
const causeMessage = slots.cause === undefined || slots.cause === THROWN_SLOT_UNREADABLE ? undefined : readThrownSlot(slots.cause, 'message');
|
|
28
|
+
return ((typeof causeMessage === 'string' && causeMessage.length > 0 && causeMessage) ||
|
|
29
|
+
(typeof slots.message === 'string' && slots.message.length > 0 && slots.message) ||
|
|
30
|
+
renderedText(err));
|
|
31
|
+
}
|
|
32
|
+
function isTransportShape(slots, detail) {
|
|
33
|
+
if (typeof slots.status === 'number' || slots.status === THROWN_SLOT_UNREADABLE)
|
|
34
|
+
return false;
|
|
35
|
+
return (slots.cause !== undefined && slots.cause !== THROWN_SLOT_UNREADABLE) || WIRE_NETWORK_ERROR_PATTERN.test(detail());
|
|
13
36
|
}
|
|
14
37
|
export function classifyTurnWireError(err) {
|
|
15
|
-
const
|
|
16
|
-
if (typeof
|
|
17
|
-
const errorCode = typeof
|
|
18
|
-
const message = typeof
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
38
|
+
const slots = readTurnErrorSlots(err);
|
|
39
|
+
if (typeof slots.status === 'number') {
|
|
40
|
+
const errorCode = typeof slots.errorCode === 'string' && slots.errorCode.length > 0 ? slots.errorCode : undefined;
|
|
41
|
+
const message = typeof slots.message === 'string' && slots.message.length > 0 ? slots.message : renderedText(err);
|
|
42
|
+
const effectiveCode = typeof err === 'object' && err !== null ? foldedWireErrorCode(err, errorCode) : undefined;
|
|
43
|
+
const storedRowWhere = typeof err === 'object' && err !== null ? storedRowWhereOf(err, effectiveCode) : undefined;
|
|
44
|
+
const sessionUnreadable = isCorruptSessionCode(effectiveCode);
|
|
45
|
+
const leaseUnavailable = slots.errorCode === FLEET_LEASE_UNAVAILABLE && fleetLeaseUnavailableFromError(err) !== null;
|
|
22
46
|
return {
|
|
23
47
|
kind: 'http',
|
|
24
|
-
status:
|
|
48
|
+
status: slots.status,
|
|
25
49
|
...(errorCode !== undefined ? { errorCode } : {}),
|
|
26
50
|
message,
|
|
27
51
|
...(storedRowWhere !== undefined ? { storedRowWhere } : {}),
|
|
@@ -29,27 +53,21 @@ export function classifyTurnWireError(err) {
|
|
|
29
53
|
...(leaseUnavailable ? { leaseUnavailable: true } : {}),
|
|
30
54
|
};
|
|
31
55
|
}
|
|
32
|
-
|
|
33
|
-
? err.name
|
|
34
|
-
: undefined;
|
|
35
|
-
if (errName === 'StreamEndedWithoutTerminalError') {
|
|
56
|
+
if (slots.status !== THROWN_SLOT_UNREADABLE && slots.name === 'StreamEndedWithoutTerminalError') {
|
|
36
57
|
return { kind: 'stream-ended-without-terminal' };
|
|
37
58
|
}
|
|
38
|
-
const detail =
|
|
39
|
-
|
|
40
|
-
if (isNetwork)
|
|
59
|
+
const detail = wireErrorDetailOf(slots, err);
|
|
60
|
+
if (isTransportShape(slots, () => detail))
|
|
41
61
|
return { kind: 'transport', detail };
|
|
42
|
-
|
|
62
|
+
const name = thrownIsInstanceOf(err, Error) && slots.name !== THROWN_SLOT_UNREADABLE ? slots.name : typeof err;
|
|
63
|
+
return { kind: 'internal', name, detail };
|
|
43
64
|
}
|
|
44
65
|
export function isWireTransportError(err) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
return false;
|
|
48
|
-
return e?.cause !== undefined || WIRE_NETWORK_ERROR_PATTERN.test(wireErrorDetail(err));
|
|
66
|
+
const slots = readTurnErrorSlots(err);
|
|
67
|
+
return isTransportShape(slots, () => wireErrorDetailOf(slots, err));
|
|
49
68
|
}
|
|
50
69
|
export function isPreStreamDrainingReject(err) {
|
|
51
|
-
|
|
52
|
-
return typeof e?.status === 'number' && e.status === 503 && e.errorCode === DRAINING_ERROR_CODE;
|
|
70
|
+
return readThrownSlot(err, 'status', 'data') === 503 && readThrownSlot(err, 'errorCode', 'data') === DRAINING_ERROR_CODE;
|
|
53
71
|
}
|
|
54
72
|
export function effectiveWireErrorCode(err) {
|
|
55
73
|
if (typeof err !== 'object' || err === null)
|
|
@@ -62,13 +80,20 @@ export function effectiveWireErrorCode(err) {
|
|
|
62
80
|
outerRaw = undefined;
|
|
63
81
|
}
|
|
64
82
|
const outer = typeof outerRaw === 'string' && outerRaw.length > 0 ? outerRaw : undefined;
|
|
83
|
+
return foldedWireErrorCode(err, outer);
|
|
84
|
+
}
|
|
85
|
+
function foldedWireErrorCode(err, outer) {
|
|
65
86
|
if (outer !== RESUME_POLICY_FOLD_CODE)
|
|
66
87
|
return outer;
|
|
67
88
|
const inner = readBlockedBy(err);
|
|
68
89
|
return inner.kind === 'named' ? inner.code : outer;
|
|
69
90
|
}
|
|
70
91
|
export function corruptStoredRowWhere(err) {
|
|
71
|
-
|
|
92
|
+
const code = effectiveWireErrorCode(err);
|
|
93
|
+
return typeof err === 'object' && err !== null ? storedRowWhereOf(err, code) : undefined;
|
|
94
|
+
}
|
|
95
|
+
function storedRowWhereOf(err, effectiveCode) {
|
|
96
|
+
if (effectiveCode !== 'corrupt')
|
|
72
97
|
return undefined;
|
|
73
98
|
const where = readErrorString(err, 'where');
|
|
74
99
|
return where !== undefined && where.trim().length > 0 ? where : undefined;
|
|
@@ -81,7 +106,7 @@ export function isResumeAtRejection(err) {
|
|
|
81
106
|
return code !== undefined && code.startsWith(RESUME_AT_ERROR_CODE_PREFIX);
|
|
82
107
|
}
|
|
83
108
|
export function drainingRetryDelayMs(err, attempt, opts) {
|
|
84
|
-
const ra = err
|
|
109
|
+
const ra = readThrownSlot(err, 'retryAfterMs', 'data');
|
|
85
110
|
if (typeof ra === 'number' && Number.isFinite(ra) && ra >= 0) {
|
|
86
111
|
return Math.min(ra, opts?.retryAfterCapMs ?? 15_000);
|
|
87
112
|
}
|
|
@@ -183,8 +208,7 @@ export function scenarioNotAllowedContent(detail, requestedScenario, surface) {
|
|
|
183
208
|
export function resumeRetryLaterFromError(err) {
|
|
184
209
|
if (typeof err !== 'object' || err === null)
|
|
185
210
|
return null;
|
|
186
|
-
const
|
|
187
|
-
const code = e.errorCode;
|
|
211
|
+
const code = readThrownSlot(err, 'errorCode', 'data');
|
|
188
212
|
if (typeof code !== 'string' || !RESUME_RETRY_LATER_CODES.includes(code))
|
|
189
213
|
return null;
|
|
190
214
|
const sec = readErrorNumber(err, 'retryAfterSec');
|
|
@@ -10,7 +10,7 @@ interface WireFailureShape {
|
|
|
10
10
|
message: string;
|
|
11
11
|
}
|
|
12
12
|
export declare const THROWN_SLOT_UNREADABLE: unique symbol;
|
|
13
|
-
export declare function readThrownSlot(o: unknown, key: string, own?: boolean): unknown;
|
|
13
|
+
export declare function readThrownSlot(o: unknown, key: string, own?: boolean | 'data'): unknown;
|
|
14
14
|
export declare function thrownIsInstanceOf<C extends abstract new (...args: never[]) => unknown>(e: unknown, cls: C): e is InstanceType<C>;
|
|
15
15
|
export type ThrownExtraReading = {
|
|
16
16
|
readonly state: 'object';
|
package/dist/wireFailureShape.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { guardedRead, ownDataField, readOwnDataValue } from './ownKey.js';
|
|
1
2
|
export const THROWN_SLOT_UNREADABLE = Symbol('thrown-slot-unreadable');
|
|
2
3
|
export function readThrownSlot(o, key, own = false) {
|
|
3
4
|
try {
|
|
5
|
+
if (own === 'data') {
|
|
6
|
+
if (o === null || o === undefined)
|
|
7
|
+
return THROWN_SLOT_UNREADABLE;
|
|
8
|
+
return typeof o === 'object' || typeof o === 'function' ? ownDataField(o, key) : undefined;
|
|
9
|
+
}
|
|
4
10
|
if (own && !Object.hasOwn(o, key))
|
|
5
11
|
return undefined;
|
|
6
12
|
return o[key];
|
|
@@ -21,12 +27,75 @@ export function thrownIsInstanceOf(e, cls) {
|
|
|
21
27
|
return false;
|
|
22
28
|
}
|
|
23
29
|
}
|
|
30
|
+
const EXTRA_KEY = 'extra';
|
|
31
|
+
const EXTRA_CHAIN_DEPTH_MAX = 64;
|
|
32
|
+
function extraSlotOf(o) {
|
|
33
|
+
let node = o;
|
|
34
|
+
for (let depth = 0; node !== null; depth++) {
|
|
35
|
+
if (depth > EXTRA_CHAIN_DEPTH_MAX)
|
|
36
|
+
throw new RangeError('prototype chain too deep to read');
|
|
37
|
+
const d = Object.getOwnPropertyDescriptor(node, EXTRA_KEY);
|
|
38
|
+
if (d !== undefined) {
|
|
39
|
+
const isData = Object.hasOwn(d, 'value');
|
|
40
|
+
if (node === o)
|
|
41
|
+
return isData ? { kind: 'own-data', value: d.value } : { kind: 'own-accessor' };
|
|
42
|
+
return !isData && typeof d.get === 'function' && isSdkErrorClassPrototype(node) ? { kind: 'sdk-class' } : { kind: 'none' };
|
|
43
|
+
}
|
|
44
|
+
node = Object.getPrototypeOf(node);
|
|
45
|
+
}
|
|
46
|
+
return { kind: 'none' };
|
|
47
|
+
}
|
|
48
|
+
function isSdkErrorClassPrototype(holder) {
|
|
49
|
+
if (holder === Object.prototype || !isClassPrototype(holder))
|
|
50
|
+
return false;
|
|
51
|
+
let node = Object.getPrototypeOf(holder);
|
|
52
|
+
for (let depth = 0; node !== null; depth++) {
|
|
53
|
+
if (depth > EXTRA_CHAIN_DEPTH_MAX)
|
|
54
|
+
throw new RangeError('prototype chain too deep to read');
|
|
55
|
+
if (isBuiltinErrorPrototype(node))
|
|
56
|
+
return true;
|
|
57
|
+
node = Object.getPrototypeOf(node);
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function classConstructorOf(node) {
|
|
62
|
+
const ctor = Object.getOwnPropertyDescriptor(node, 'constructor');
|
|
63
|
+
if (ctor === undefined || !Object.hasOwn(ctor, 'value') || typeof ctor.value !== 'function')
|
|
64
|
+
return undefined;
|
|
65
|
+
const fn = ctor.value;
|
|
66
|
+
const p = Object.getOwnPropertyDescriptor(fn, 'prototype');
|
|
67
|
+
return p !== undefined && Object.hasOwn(p, 'value') && p.value === node ? fn : undefined;
|
|
68
|
+
}
|
|
69
|
+
function isClassPrototype(node) {
|
|
70
|
+
return classConstructorOf(node) !== undefined;
|
|
71
|
+
}
|
|
72
|
+
const BUILTIN_ERROR_SOURCE = /^function Error\(\)\s*\{\s*\[native code\]\s*\}$/;
|
|
73
|
+
function isBuiltinErrorPrototype(node) {
|
|
74
|
+
const fn = classConstructorOf(node);
|
|
75
|
+
if (fn === undefined)
|
|
76
|
+
return false;
|
|
77
|
+
const n = Object.getOwnPropertyDescriptor(fn, 'name');
|
|
78
|
+
if (n === undefined || !Object.hasOwn(n, 'value') || n.value !== 'Error')
|
|
79
|
+
return false;
|
|
80
|
+
if (!BUILTIN_ERROR_SOURCE.test(Function.prototype.toString.call(fn)))
|
|
81
|
+
return false;
|
|
82
|
+
return ['message', 'name', 'toString'].every((k) => Object.getOwnPropertyDescriptor(node, k) !== undefined);
|
|
83
|
+
}
|
|
24
84
|
export function readThrownExtra(o) {
|
|
25
|
-
if (o === null || o === undefined)
|
|
85
|
+
if (o === null || o === undefined || (typeof o !== 'object' && typeof o !== 'function'))
|
|
26
86
|
return { state: 'absent' };
|
|
27
|
-
|
|
28
|
-
|
|
87
|
+
let slot;
|
|
88
|
+
try {
|
|
89
|
+
const at = extraSlotOf(o);
|
|
90
|
+
if (at.kind === 'own-accessor')
|
|
91
|
+
return { state: 'unreadable' };
|
|
92
|
+
if (at.kind === 'none')
|
|
93
|
+
return { state: 'absent' };
|
|
94
|
+
slot = at.kind === 'own-data' ? at.value : Reflect.get(o, EXTRA_KEY);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
29
97
|
return { state: 'unreadable' };
|
|
98
|
+
}
|
|
30
99
|
try {
|
|
31
100
|
if (typeof slot !== 'object' || slot === null || Array.isArray(slot))
|
|
32
101
|
return { state: 'absent' };
|
|
@@ -38,27 +107,15 @@ export function readThrownExtra(o) {
|
|
|
38
107
|
}
|
|
39
108
|
function readErrorSlot(obj, key, accept) {
|
|
40
109
|
try {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
top = o[key];
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
top = undefined;
|
|
48
|
-
}
|
|
110
|
+
const topRaw = readThrownSlot(obj, key, 'data');
|
|
111
|
+
const top = topRaw === THROWN_SLOT_UNREADABLE ? undefined : topRaw;
|
|
49
112
|
if (accept(top))
|
|
50
113
|
return top;
|
|
51
114
|
const reading = readThrownExtra(obj);
|
|
52
115
|
if (reading.state !== 'object')
|
|
53
116
|
return undefined;
|
|
54
117
|
const extra = reading.value;
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
fromExtra = Object.hasOwn(extra, key) ? extra[key] : undefined;
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
fromExtra = undefined;
|
|
61
|
-
}
|
|
118
|
+
const fromExtra = guardedRead(() => readOwnDataValue(extra, key));
|
|
62
119
|
return accept(fromExtra) ? fromExtra : undefined;
|
|
63
120
|
}
|
|
64
121
|
catch {
|
|
@@ -217,13 +274,7 @@ export function readBlockedBy(o) {
|
|
|
217
274
|
}
|
|
218
275
|
export function readRefusalField(o) {
|
|
219
276
|
const str = (rec) => {
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
v = rec.field;
|
|
223
|
-
}
|
|
224
|
-
catch {
|
|
225
|
-
return undefined;
|
|
226
|
-
}
|
|
277
|
+
const v = guardedRead(() => readOwnDataValue(rec, 'field'));
|
|
227
278
|
return typeof v === 'string' && v !== '' ? v : undefined;
|
|
228
279
|
};
|
|
229
280
|
const reading = readThrownExtra(o);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
-
import { createEngineCapReader } from './engineCapReader.js';
|
|
2
|
+
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
3
|
import { ownDataField } from './ownKey.js';
|
|
4
4
|
export function projectWorkflowsJournalCapability(caps) {
|
|
5
5
|
try {
|
|
@@ -19,7 +19,6 @@ export function projectWorkflowsJournalCapability(caps) {
|
|
|
19
19
|
const reader = createEngineCapReader({
|
|
20
20
|
name: 'workflowsJournal',
|
|
21
21
|
project: projectWorkflowsJournalCapability,
|
|
22
|
-
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
23
22
|
});
|
|
24
23
|
export function noteEngineCapsForWorkflowsJournal(baseUrl, caps, opts) {
|
|
25
24
|
reader.note(baseUrl, caps, opts);
|
|
@@ -36,6 +35,8 @@ export function workflowsJournalAvailable(reading) {
|
|
|
36
35
|
}
|
|
37
36
|
export function workflowsJournalDoctorDetail(reading) {
|
|
38
37
|
switch (reading.kind) {
|
|
38
|
+
case 'unreadable':
|
|
39
|
+
return unreadableReadingDetail('workflow journal');
|
|
39
40
|
case 'unobserved':
|
|
40
41
|
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)';
|
|
41
42
|
case 'not_reported':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
2
2
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
|
-
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
4
4
|
import { ownDataField } from './ownKey.js';
|
|
5
5
|
export function projectWriteProtectionCapability(caps) {
|
|
6
6
|
try {
|
|
@@ -65,7 +65,6 @@ export function projectWriteProtectionPosture(wiring) {
|
|
|
65
65
|
const reader = createEngineCapReader({
|
|
66
66
|
name: 'writeProtection',
|
|
67
67
|
project: projectWriteProtectionCapability,
|
|
68
|
-
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
69
68
|
});
|
|
70
69
|
export function noteEngineCapsForWriteProtection(baseUrl, caps, opts) {
|
|
71
70
|
reader.note(baseUrl, caps, opts);
|
|
@@ -76,6 +75,8 @@ export function observedWriteProtection(baseUrl = engineWireTarget()?.baseUrl) {
|
|
|
76
75
|
const WP_DETAIL_MAX = 40;
|
|
77
76
|
export function writeProtectionDoctorDetail(reading) {
|
|
78
77
|
switch (reading.kind) {
|
|
78
|
+
case 'unreadable':
|
|
79
|
+
return unreadableReadingDetail();
|
|
79
80
|
case 'unobserved':
|
|
80
81
|
return ('not observed — the engine reports it on /v1/capabilities; this process has no usable ' +
|
|
81
82
|
'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)');
|