@sema-agent/client-core 0.96.0 → 0.97.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +28 -22
  3. package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
  4. package/dist/adapter/activeRunSelfHeal.js +7 -7
  5. package/dist/adapter/downstream/terminalToSdkResult.js +6 -2
  6. package/dist/agentSession/backgroundView.js +2 -15
  7. package/dist/agentsWireCaps.d.ts +1 -1
  8. package/dist/agentsWireCaps.js +16 -10
  9. package/dist/approvalDecidedByCapability.d.ts +2 -0
  10. package/dist/approvalDecidedByCapability.js +0 -1
  11. package/dist/approvalsStreamLiveCapability.d.ts +2 -0
  12. package/dist/approvalsStreamLiveCapability.js +3 -2
  13. package/dist/attachmentSeatCapability.d.ts +2 -0
  14. package/dist/attachmentSeatCapability.js +0 -1
  15. package/dist/callerCwdCapability.d.ts +2 -0
  16. package/dist/callerCwdCapability.js +0 -1
  17. package/dist/centerWiringCapability.d.ts +2 -0
  18. package/dist/centerWiringCapability.js +4 -3
  19. package/dist/cloudConfigWireCaps.d.ts +2 -2
  20. package/dist/cloudConfigWireCaps.js +192 -56
  21. package/dist/declared/supportFloorDeclared.js +3 -3
  22. package/dist/deviceExecutorManagementCapability.d.ts +2 -0
  23. package/dist/deviceExecutorManagementCapability.js +3 -2
  24. package/dist/displayUntrusted.d.ts +3 -0
  25. package/dist/displayUntrusted.js +15 -0
  26. package/dist/engineCapReader.d.ts +8 -2
  27. package/dist/engineCapReader.js +15 -7
  28. package/dist/engineCapsCache.d.ts +11 -3
  29. package/dist/engineCapsCache.js +54 -23
  30. package/dist/engineErrorCodes.d.ts +3 -0
  31. package/dist/engineErrorCodes.js +9 -1
  32. package/dist/engineNoticeCodes.js +2 -3
  33. package/dist/executionLaneCapability.d.ts +2 -0
  34. package/dist/executionLaneCapability.js +3 -2
  35. package/dist/fileHistoryCaptureCapability.d.ts +2 -0
  36. package/dist/fileHistoryCaptureCapability.js +34 -8
  37. package/dist/fileHistoryLegNotice.js +4 -0
  38. package/dist/fleet/fleetLedger.js +129 -105
  39. package/dist/gateOutcome.js +2 -4
  40. package/dist/gateVocabulary.d.ts +1 -6
  41. package/dist/gateVocabulary.js +2 -5
  42. package/dist/generated/sdkFactTables.d.ts +2 -0
  43. package/dist/generated/sdkFactTables.js +7 -0
  44. package/dist/generated/toolNameTables.d.ts +0 -1
  45. package/dist/generated/toolNameTables.js +0 -42
  46. package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
  47. package/dist/hitl/approvalEndingCause.js +2 -7
  48. package/dist/hitl/approvalHolds.d.ts +16 -1
  49. package/dist/hitl/approvalHolds.js +52 -12
  50. package/dist/hitl/askGateWire.js +1 -0
  51. package/dist/hitl/automaticAnswerVerdict.js +5 -7
  52. package/dist/hitl/decisionConflict.js +4 -3
  53. package/dist/hitl/decisionRefusal.js +19 -12
  54. package/dist/hitl/frameRouter.d.ts +3 -0
  55. package/dist/hitl/frameRouter.js +52 -25
  56. package/dist/hitl/gateLedger.d.ts +0 -5
  57. package/dist/hitl/gateLedger.js +0 -21
  58. package/dist/hitl/hitlBridge.js +18 -4
  59. package/dist/hitl/parkResolver.js +7 -3
  60. package/dist/hitl/replayedApproval.d.ts +2 -3
  61. package/dist/hitl/replayedApproval.js +7 -16
  62. package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
  63. package/dist/hitl/sessionPolicyDeliverable.js +15 -17
  64. package/dist/hitl/sessionPolicyWire.d.ts +2 -0
  65. package/dist/hitl/sessionPolicyWire.js +15 -3
  66. package/dist/hitl/standingRows.d.ts +1 -0
  67. package/dist/hitl/standingRows.js +38 -17
  68. package/dist/hitl/suspendedReopen.js +2 -1
  69. package/dist/hitl/toolApprovalWire.d.ts +8 -8
  70. package/dist/hitl/toolApprovalWire.js +50 -24
  71. package/dist/index.d.ts +6 -4
  72. package/dist/index.js +4 -3
  73. package/dist/liveModelCatalog.d.ts +13 -0
  74. package/dist/liveModelCatalog.js +56 -0
  75. package/dist/mcpProbeCapability.d.ts +2 -0
  76. package/dist/mcpProbeCapability.js +3 -2
  77. package/dist/mcpWireCaps.d.ts +1 -0
  78. package/dist/mcpWireCaps.js +4 -1
  79. package/dist/memoryComplianceCapability.d.ts +2 -0
  80. package/dist/memoryComplianceCapability.js +3 -2
  81. package/dist/memoryOriginCapability.d.ts +2 -0
  82. package/dist/memoryOriginCapability.js +3 -2
  83. package/dist/modelIdentityResolvability.js +2 -2
  84. package/dist/noticePresentation.js +2 -2
  85. package/dist/outputStyleSeatCapability.d.ts +2 -0
  86. package/dist/outputStyleSeatCapability.js +0 -1
  87. package/dist/peerLaneCapability.d.ts +2 -0
  88. package/dist/peerLaneCapability.js +3 -2
  89. package/dist/permissionModesCapability.d.ts +2 -0
  90. package/dist/permissionModesCapability.js +0 -1
  91. package/dist/permissionRulesWriteCapability.d.ts +2 -0
  92. package/dist/permissionRulesWriteCapability.js +3 -2
  93. package/dist/permissionsAllowGrantCapability.d.ts +2 -0
  94. package/dist/permissionsAllowGrantCapability.js +4 -2
  95. package/dist/permissionsDeclaration.js +19 -21
  96. package/dist/request/taskRequest.d.ts +1 -4
  97. package/dist/request/taskRequest.js +74 -19
  98. package/dist/resumeRefusalCopy.js +4 -4
  99. package/dist/rewindArchiveCapability.js +5 -0
  100. package/dist/rewindArchiveReading.d.ts +2 -0
  101. package/dist/rewindArchiveReading.js +0 -1
  102. package/dist/runTerminal.d.ts +33 -4
  103. package/dist/runTerminal.js +170 -15
  104. package/dist/sdkWireTransit.d.ts +2 -1
  105. package/dist/sdkWireTransit.js +1 -0
  106. package/dist/sealedKeyCapability.d.ts +2 -0
  107. package/dist/sealedKeyCapability.js +0 -1
  108. package/dist/seatContract.d.ts +7 -4
  109. package/dist/seatContract.js +34 -20
  110. package/dist/sessionPolicyCapability.d.ts +2 -0
  111. package/dist/sessionPolicyCapability.js +3 -2
  112. package/dist/sessionReadRedactionCapability.d.ts +2 -0
  113. package/dist/sessionReadRedactionCapability.js +0 -1
  114. package/dist/sessionSyncFileHistoryCapability.d.ts +2 -0
  115. package/dist/sessionSyncFileHistoryCapability.js +3 -2
  116. package/dist/skillToolListsCapability.d.ts +2 -0
  117. package/dist/skillToolListsCapability.js +3 -2
  118. package/dist/sqlEngineCapability.d.ts +2 -0
  119. package/dist/sqlEngineCapability.js +4 -3
  120. package/dist/steerPriorityCapability.d.ts +2 -0
  121. package/dist/steerPriorityCapability.js +3 -2
  122. package/dist/storePostureCapability.d.ts +2 -0
  123. package/dist/storePostureCapability.js +4 -3
  124. package/dist/toolHistoryBadTurn.js +3 -2
  125. package/dist/toolResult.d.ts +11 -0
  126. package/dist/toolResult.js +53 -0
  127. package/dist/userInvokedSkillsCapability.d.ts +2 -0
  128. package/dist/userInvokedSkillsCapability.js +3 -2
  129. package/dist/webSearchBackendCapability.d.ts +2 -0
  130. package/dist/webSearchBackendCapability.js +3 -2
  131. package/dist/wireErrorTriage.js +58 -34
  132. package/dist/wireFailureShape.d.ts +1 -1
  133. package/dist/wireFailureShape.js +76 -25
  134. package/dist/workflowsJournalCapability.d.ts +2 -0
  135. package/dist/workflowsJournalCapability.js +3 -2
  136. package/dist/writeProtectionCapability.d.ts +2 -0
  137. package/dist/writeProtectionCapability.js +3 -2
  138. package/docs/INTEGRATION-CLIENTS.md +533 -14
  139. package/package.json +4 -4
  140. package/dist/engineRefusedToolName.d.ts +0 -1
  141. package/dist/engineRefusedToolName.js +0 -8
  142. package/dist/engineWordRenames.d.ts +0 -8
  143. package/dist/engineWordRenames.js +0 -13
@@ -2,8 +2,6 @@ import type { ActiveRunBusySignal } from './runStream.js';
2
2
  import type { PlanReviewReopenTrigger } from '../hitl/planReviewWire.js';
3
3
  import { atMostOnceFailureClass } from '../atMostOnce.js';
4
4
  export declare const PLAN_REVIEW_GATE_KIND = "plan_review";
5
- export declare const PLAN_REVIEW_GATE_KINDS: readonly string[];
6
- export declare const ASK_PARK_GATE_KINDS: readonly string[];
7
5
  export type DurableDecideLeg = 'approval' | 'plan_review' | 'other_gate' | 'unreadable' | 'absent';
8
6
  export declare function durableDecideLegOf(row: {
9
7
  readonly gateKind?: string | null;
@@ -5,14 +5,13 @@ import { atMostOnceFailureClass } from '../atMostOnce.js';
5
5
  import { readSteerReceipt } from '../steerReceipt.js';
6
6
  import { resumeAttachReplayDisclosure, runningAttachOffered } from '../hitl/resumeRunningCard.js';
7
7
  import { isSdkRunTerminal, SDK_PARKED_RUN_STATUSES } from '../terminalStatuses.js';
8
+ import { SDK_APPROVAL_DECIDE_GATE_KINDS, SDK_PLAN_REVIEW_GATE_KINDS } from '../generated/sdkFactTables.js';
8
9
  export const PLAN_REVIEW_GATE_KIND = 'plan_review';
9
- const APPROVAL_LEG_GATE_KINDS = ['human', 'irreversible_ask'];
10
- const PLAN_LEG_GATE_KINDS = ['plan_review'];
10
+ const APPROVAL_LEG_GATE_KINDS = SDK_APPROVAL_DECIDE_GATE_KINDS;
11
+ const PLAN_LEG_GATE_KINDS = SDK_PLAN_REVIEW_GATE_KINDS;
11
12
  const CORE_GATE_KINDS = ['human', 'irreversible_ask', 'resource_limit', 'needs_review', 'plan_review', 'task_done'];
12
- const _durableDecideLegPins = [true, true, true, true, true, true];
13
+ const _durableDecideLegPins = [true, true, true, true, true, true, true, true, true, true];
13
14
  void _durableDecideLegPins;
14
- export const PLAN_REVIEW_GATE_KINDS = Object.freeze([...PLAN_LEG_GATE_KINDS]);
15
- export const ASK_PARK_GATE_KINDS = Object.freeze([...APPROVAL_LEG_GATE_KINDS]);
16
15
  function gateKindReadingOf(row) {
17
16
  let kind;
18
17
  try {
@@ -447,9 +446,10 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
447
446
  };
448
447
  }
449
448
  const gateKind = signal.pendingGate?.kind ?? null;
450
- if (gateKind !== null && PLAN_REVIEW_GATE_KINDS.includes(gateKind))
449
+ const gateLeg = gateKind !== null ? durableDecideLegOf({ gateKind }) : 'absent';
450
+ if (gateLeg === 'plan_review')
451
451
  return planReviewArm(taskId, signal, deps);
452
- if (gateKind !== null && ASK_PARK_GATE_KINDS.includes(gateKind))
452
+ if (gateLeg === 'approval')
453
453
  return askParkArm(taskId, signal, runs, deps);
454
454
  let status = signal.activeTaskStatus;
455
455
  if (status === null) {
@@ -6,12 +6,16 @@ import { readEffectiveReasoning, readEffectiveMemoryScopes } from '../../effecti
6
6
  import { isReviewPark, readRunTerminal, runTerminalCode, runTerminalGateToolName, } from '../../runTerminal.js';
7
7
  import { doneResultView } from '../../replayBody.js';
8
8
  import { toCcModelUsage } from './turnUsageToModelUsage.js';
9
- import { LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, OUTPUT_INVALID, isCorruptSessionCode, isRewindFamilyCode, } from '../../engineErrorCodes.js';
9
+ import { LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, OUTPUT_INVALID, isCorruptSessionCode, idempotencyPayloadMismatchContent, isIdempotencyPayloadMismatchCode, isRewindFamilyCode, } from '../../engineErrorCodes.js';
10
10
  import { corruptSessionContent } from '../../corruptSessionCopy.js';
11
11
  import { runBlockedText } from '../../promptBlockedCopy.js';
12
12
  import { abortCauseNoteOf, readAbortCause } from '../../runCancelContext.js';
13
13
  function withTerminalNote(text, code, frame) {
14
- const withCorrupt = isCorruptSessionCode(code) ? `${text}\n${corruptSessionContent()}` : text;
14
+ const withCorrupt = isCorruptSessionCode(code)
15
+ ? `${text}\n${corruptSessionContent()}`
16
+ : isIdempotencyPayloadMismatchCode(code)
17
+ ? `${text}\n${idempotencyPayloadMismatchContent()}`
18
+ : text;
15
19
  const abortNote = abortCauseNoteOf(frame);
16
20
  return abortNote === undefined ? withCorrupt : `${withCorrupt}\n${abortNote}`;
17
21
  }
@@ -122,7 +122,6 @@ export function createBackgroundView(client, opts) {
122
122
  let disposed = false;
123
123
  let current = null;
124
124
  let lastSerialized = null;
125
- let capsApprovals = null;
126
125
  const listeners = new Set();
127
126
  const abort = new AbortController();
128
127
  function notify() {
@@ -137,27 +136,16 @@ export function createBackgroundView(client, opts) {
137
136
  }
138
137
  }
139
138
  }
140
- async function probeCaps() {
141
- if (capsApprovals !== null)
142
- return;
143
- try {
144
- const caps = await client.capabilities({ signal: abort.signal });
145
- capsApprovals = caps.approvals === true;
146
- }
147
- catch (err) {
148
- debugLog(`caps probe unavailable (approvals 判别缺席,保持 ok 口径): ${String(err)}`);
149
- }
150
- }
151
139
  async function pullAssistant() {
152
140
  try {
153
141
  const { tasks } = await client.assistant.tasks({ signal: abort.signal });
154
142
  if (!Array.isArray(tasks))
155
143
  return { health: 'unavailable', tasks: [] };
156
- return { health: capsApprovals === false ? 'not-configured' : 'ok', tasks };
144
+ return { health: 'ok', tasks };
157
145
  }
158
146
  catch (err) {
159
147
  debugLog(`assistant.tasks degrade: ${String(err)}`);
160
- const health = capsApprovals === false || isNotImplemented(err)
148
+ const health = isNotImplemented(err)
161
149
  ? 'not-configured'
162
150
  : isReadCredentialRefusal(err)
163
151
  ? 'unauthorized'
@@ -183,7 +171,6 @@ export function createBackgroundView(client, opts) {
183
171
  }
184
172
  }
185
173
  async function pollOnce() {
186
- await probeCaps();
187
174
  const [assistant, fleet] = await Promise.all([pullAssistant(), pullFleet()]);
188
175
  if (disposed || abort.signal.aborted)
189
176
  return;
@@ -68,7 +68,7 @@ export type ProjectAgentsResult = {
68
68
  warnings: string[];
69
69
  toolListFlaws?: readonly AgentToolListFlaw[];
70
70
  };
71
- export type AgentToolListFlawKind = 'retired' | 'unprefixed_namespace' | 'case_twin';
71
+ export type AgentToolListFlawKind = 'retired' | 'unprefixed_namespace' | 'unmintable_segment' | 'unjudged' | 'case_twin';
72
72
  export interface AgentToolListFlaw {
73
73
  readonly agent: string;
74
74
  readonly list: 'tools' | 'disallowedTools';
@@ -3,8 +3,8 @@ import { ownDataField } from './ownKey.js';
3
3
  import { makeEngineWireClient } from './engineWireSdk.js';
4
4
  import { frozenSet } from './frozenSet.js';
5
5
  import { settleWithinDeadline } from './abortableSleep.js';
6
- import { isEngineRefusedToolName } from './engineRefusedToolName.js';
7
- import { CORE_PROTOCOL_PREFIXES, CORE_RETIRED_TOOL_CURRENT_NAMES } from './generated/toolNameTables.js';
6
+ import { ruleToolNameVerdictOf } from './protocolSegment.js';
7
+ import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
8
8
  import { rosterMountedNames } from './rosterMountedNames.js';
9
9
  import { capForDisplay } from './fleetTaskDesc.js';
10
10
  export const MAX_TASK_AGENTS = 32;
@@ -43,7 +43,6 @@ const SOURCE_RANK = {
43
43
  function sourceRank(source) {
44
44
  return SOURCE_RANK[source] ?? 5;
45
45
  }
46
- const RETIRED_TABLE_CURRENT_NAMES = frozenSet([...CORE_RETIRED_TOOL_CURRENT_NAMES.values()].filter((v) => typeof v === 'string'));
47
46
  function unescapedIndexOf(s, ch, last) {
48
47
  for (let k = 0; k < s.length; k++) {
49
48
  const i = last ? s.length - 1 - k : k;
@@ -76,12 +75,15 @@ function toolNameFlawOf(entry, names, list) {
76
75
  if (name === undefined || name.length === 0 || name === '*' || names.has(name))
77
76
  return undefined;
78
77
  const named = name !== entry ? { toolName: name } : {};
79
- if (isEngineRefusedToolName(name)) {
80
- const current = CORE_RETIRED_TOOL_CURRENT_NAMES.get(name);
81
- if (current === undefined)
82
- return { kind: 'unprefixed_namespace', ...named };
83
- return typeof current === 'string' ? { kind: 'retired', currentName: current, ...named } : { kind: 'retired', ...named };
84
- }
78
+ const verdict = ruleToolNameVerdictOf(name);
79
+ if (verdict.kind === 'unknown')
80
+ return { kind: 'unjudged', ...named };
81
+ if (verdict.kind === 'unmintable_segment')
82
+ return { kind: 'unmintable_segment', ...named };
83
+ if (verdict.kind === 'unprefixed_namespace')
84
+ return { kind: 'unprefixed_namespace', ...named };
85
+ if (verdict.kind === 'retired')
86
+ return verdict.currentName !== undefined ? { kind: 'retired', currentName: verdict.currentName, ...named } : { kind: 'retired', ...named };
85
87
  if (CORE_PROTOCOL_PREFIXES.some((prefix) => name.startsWith(prefix)))
86
88
  return undefined;
87
89
  const folded = name.toLowerCase();
@@ -94,7 +96,7 @@ export function agentToolListFlaws(agents, roster) {
94
96
  if (!Array.isArray(agents) || agents.length === 0)
95
97
  return [];
96
98
  const mounted = rosterMountedNames(roster);
97
- const names = typeof mounted === 'object' ? mounted : RETIRED_TABLE_CURRENT_NAMES;
99
+ const names = typeof mounted === 'object' ? mounted : new Set();
98
100
  const out = [];
99
101
  for (const a of agents) {
100
102
  if (a === null || typeof a !== 'object' || typeof a.name !== 'string')
@@ -117,6 +119,10 @@ function toolListFlawPhrase(f) {
117
119
  return `${entry} is a retired tool name${f.currentName !== undefined ? ` (now ${JSON.stringify(f.currentName)})` : ' (no longer available under any name)'}`;
118
120
  if (f.kind === 'unprefixed_namespace')
119
121
  return `${entry} contains "__" but does not start with a tool protocol prefix`;
122
+ if (f.kind === 'unmintable_segment')
123
+ return `${entry} spells its server or agent peer part in a way the engine never uses when naming tools, so no tool answers to it`;
124
+ if (f.kind === 'unjudged')
125
+ return `${entry} could not be checked here, because the engine's tool-name check is not available in this client`;
120
126
  return `${entry} differs from the tool ${JSON.stringify(f.currentName ?? '')} only in letter case`;
121
127
  }
122
128
  export function projectAgentsForWire(defs, deps) {
@@ -1,5 +1,7 @@
1
1
  export type ApprovalDecidedByReading = {
2
2
  kind: 'unobserved';
3
+ } | {
4
+ kind: 'unreadable';
3
5
  } | {
4
6
  kind: 'not_reported';
5
7
  } | {
@@ -17,7 +17,6 @@ export function projectApprovalDecidedByCapability(caps) {
17
17
  const reader = createEngineCapReader({
18
18
  name: 'approvalDecidedBy',
19
19
  project: projectApprovalDecidedByCapability,
20
- makeUnobserved: () => ({ kind: 'unobserved' }),
21
20
  });
22
21
  export function noteEngineCapsForApprovalDecidedBy(baseUrl, caps, opts) {
23
22
  reader.note(baseUrl, caps, opts);
@@ -1,5 +1,7 @@
1
1
  export type ApprovalsStreamLiveReading = {
2
2
  kind: 'unobserved';
3
+ } | {
4
+ kind: 'unreadable';
3
5
  } | {
4
6
  kind: 'not_reported';
5
7
  } | {
@@ -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 projectApprovalsStreamLiveCapability(caps) {
5
5
  try {
@@ -21,7 +21,6 @@ export function projectApprovalsStreamLiveCapability(caps) {
21
21
  const reader = createEngineCapReader({
22
22
  name: 'approvalsStreamLive',
23
23
  project: projectApprovalsStreamLiveCapability,
24
- makeUnobserved: () => ({ kind: 'unobserved' }),
25
24
  });
26
25
  export function noteEngineCapsForApprovalsStreamLive(baseUrl, caps, opts) {
27
26
  reader.note(baseUrl, caps, opts);
@@ -34,6 +33,8 @@ export function livePendingNeedsReconcile(reading) {
34
33
  }
35
34
  export function approvalsStreamLiveDoctorDetail(reading) {
36
35
  switch (reading.kind) {
36
+ case 'unreadable':
37
+ return unreadableReadingDetail('live approval push');
37
38
  case 'unobserved':
38
39
  return 'live approval push not observed — the engine reports it on /v1/capabilities; 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), so suspended asks are pulled by the reconcile cadence';
39
40
  case 'not_reported':
@@ -1,5 +1,7 @@
1
1
  export type AttachmentSeatReading = {
2
2
  readonly kind: 'unobserved';
3
+ } | {
4
+ readonly kind: 'unreadable';
3
5
  } | {
4
6
  readonly kind: 'not_reported';
5
7
  };
@@ -11,7 +11,6 @@ function projectAttachmentSeat(caps) {
11
11
  const reader = createEngineCapReader({
12
12
  name: 'attachmentSeat',
13
13
  project: projectAttachmentSeat,
14
- makeUnobserved: () => ({ kind: 'unobserved' }),
15
14
  });
16
15
  export function noteEngineCapsForAttachmentSeat(baseUrl, caps, opts) {
17
16
  reader.note(baseUrl, caps, opts);
@@ -1,5 +1,7 @@
1
1
  export type CallerCwdReading = {
2
2
  kind: 'unobserved';
3
+ } | {
4
+ kind: 'unreadable';
3
5
  } | {
4
6
  kind: 'not_reported';
5
7
  } | {
@@ -17,7 +17,6 @@ export function projectCallerCwdCapability(caps) {
17
17
  const reader = createEngineCapReader({
18
18
  name: 'callerCwd',
19
19
  project: projectCallerCwdCapability,
20
- makeUnobserved: () => ({ kind: 'unobserved' }),
21
20
  });
22
21
  export function observedCallerCwd(baseUrl = engineWireTarget()?.baseUrl) {
23
22
  return reader.observed(baseUrl);
@@ -19,6 +19,8 @@ export interface CenterWiringView {
19
19
  }
20
20
  export type CenterWiringReading = {
21
21
  kind: 'unobserved';
22
+ } | {
23
+ kind: 'unreadable';
22
24
  } | {
23
25
  kind: 'none';
24
26
  } | {
@@ -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
  const nonEmpty = (v) => typeof v === 'string' && v !== '';
6
6
  const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
@@ -86,7 +86,6 @@ function projectCenterWiringOf(caps) {
86
86
  const reader = createEngineCapReader({
87
87
  name: 'centerWiring',
88
88
  project: projectCenterWiringCapability,
89
- makeUnobserved: () => ({ kind: 'unobserved' }),
90
89
  });
91
90
  export function observedCenterWiring(baseUrl = engineWireTarget()?.baseUrl) {
92
91
  return reader.observed(baseUrl);
@@ -96,7 +95,7 @@ function guarded(reading) {
96
95
  return undefined;
97
96
  try {
98
97
  const kind = reading.kind;
99
- if (kind === 'unobserved' || kind === 'none')
98
+ if (kind === 'unobserved' || kind === 'unreadable' || kind === 'none')
100
99
  return { kind };
101
100
  if (kind !== 'present')
102
101
  return undefined;
@@ -158,6 +157,8 @@ function failModeClause(v) {
158
157
  export function centerWiringDoctorDetail(reading) {
159
158
  const unobserved = 'center wiring not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this engine is connected to a configuration center is unknown';
160
159
  const r = guarded(reading);
160
+ if (r?.kind === 'unreadable')
161
+ return unreadableReadingDetail('center wiring');
161
162
  if (r?.kind === 'none') {
162
163
  return 'no configuration center on this deployment — the engine runs on its own local configuration; no quota lease or usage reporting goes through a center';
163
164
  }
@@ -20,7 +20,7 @@ export interface CloudModelRefIssue {
20
20
  readonly key: 'models' | 'roles' | 'atMention' | 'tierGroups' | 'activeTierGroup';
21
21
  readonly at?: string;
22
22
  readonly target?: string;
23
- readonly reason: 'dangling' | 'rejected' | 'unreadable' | 'unsupported' | 'duplicate' | 'shadowed';
23
+ readonly reason: 'dangling' | 'rejected' | 'unreadable' | 'unsupported' | 'duplicate' | 'shadowed' | 'unvouched';
24
24
  readonly outcome: 'dropped' | 'kept';
25
25
  }
26
26
  export interface CloudModelsDocOptions {
@@ -123,4 +123,4 @@ export interface CloudEffectiveNotice {
123
123
  readonly level: 'warn' | 'info';
124
124
  readonly text: string;
125
125
  }
126
- export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues'>): CloudEffectiveNotice[];
126
+ export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues' | 'droppedMcpServers'>): CloudEffectiveNotice[];