@sema-agent/client-core 0.98.0 → 0.100.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 (236) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +61 -35
  3. package/dist/adapt/arms.js +120 -55
  4. package/dist/adapt/panelTasks.d.ts +3 -2
  5. package/dist/adapt/panelTasks.js +34 -11
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
  9. package/dist/adapter/activeRunSelfHeal.js +210 -294
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +82 -40
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/adapter/types.js +2 -1
  18. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  19. package/dist/agentsWireCaps.d.ts +7 -3
  20. package/dist/agentsWireCaps.js +133 -39
  21. package/dist/cloudConfigWireCaps.d.ts +10 -1
  22. package/dist/cloudConfigWireCaps.js +181 -65
  23. package/dist/compactionStatus.d.ts +34 -0
  24. package/dist/compactionStatus.js +196 -0
  25. package/dist/controlRouter.d.ts +4 -2
  26. package/dist/controlRouter.js +39 -51
  27. package/dist/coreValuePorts.d.ts +26 -1
  28. package/dist/coreValuePorts.js +10 -0
  29. package/dist/corruptSessionCopy.d.ts +2 -1
  30. package/dist/corruptSessionCopy.js +3 -3
  31. package/dist/decideFailureNote.js +3 -3
  32. package/dist/declared/supportFloorDeclared.js +1 -1
  33. package/dist/detachWire.js +3 -2
  34. package/dist/devicesFace.d.ts +34 -0
  35. package/dist/devicesFace.js +90 -0
  36. package/dist/displayUntrusted.d.ts +1 -0
  37. package/dist/displayUntrusted.js +153 -5
  38. package/dist/engineAgentPanelStore.d.ts +14 -4
  39. package/dist/engineAgentPanelStore.js +14 -0
  40. package/dist/engineCapReader.d.ts +2 -1
  41. package/dist/engineCapReader.js +7 -5
  42. package/dist/engineCapsCache.d.ts +8 -0
  43. package/dist/engineCapsCache.js +59 -6
  44. package/dist/engineCapsChange.d.ts +2 -0
  45. package/dist/engineCapsChange.js +9 -0
  46. package/dist/engineErrorCodes.d.ts +11 -2
  47. package/dist/engineErrorCodes.js +11 -12
  48. package/dist/engineRowRef.js +4 -0
  49. package/dist/engineSessionMessages.d.ts +1 -0
  50. package/dist/engineSessionMessages.js +7 -1
  51. package/dist/engineTargetSeat.d.ts +27 -0
  52. package/dist/engineTargetSeat.js +199 -0
  53. package/dist/engineToolDirectory.d.ts +3 -0
  54. package/dist/engineToolDirectory.js +4 -2
  55. package/dist/engineWireFor.js +3 -8
  56. package/dist/env/uiLanguage.d.ts +2 -1
  57. package/dist/env/uiLanguage.js +3 -2
  58. package/dist/eventLeg.d.ts +7 -5
  59. package/dist/eventLeg.js +68 -49
  60. package/dist/fileHistoryCaptureCapability.d.ts +2 -4
  61. package/dist/fileHistoryCaptureCapability.js +12 -22
  62. package/dist/fileHistoryLegNotice.d.ts +2 -1
  63. package/dist/fileHistoryLegNotice.js +3 -3
  64. package/dist/frameBinding.d.ts +3 -0
  65. package/dist/frameBinding.js +12 -0
  66. package/dist/gateOutcome.js +16 -2
  67. package/dist/gateVocabulary.d.ts +8 -7
  68. package/dist/gateVocabulary.js +71 -73
  69. package/dist/generated/engineFactTables.d.ts +18 -1
  70. package/dist/generated/engineFactTables.js +56 -0
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/settingsSchemaFns.d.ts +18 -0
  73. package/dist/generated/settingsSchemaFns.js +70 -0
  74. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  75. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  76. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  77. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  78. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  79. package/dist/generated/settingsSchemaTables.js +9 -0
  80. package/dist/generated/settingsSchemaTypes.d.ts +133 -0
  81. package/dist/generated/settingsSchemaTypes.js +1 -0
  82. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  83. package/dist/hitl/allowRuleShadow.js +18 -15
  84. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  85. package/dist/hitl/approvalCardReasons.js +29 -30
  86. package/dist/hitl/approvalHolds.d.ts +17 -0
  87. package/dist/hitl/approvalHolds.js +114 -29
  88. package/dist/hitl/askClassPair.d.ts +2 -2
  89. package/dist/hitl/askClassPair.js +16 -0
  90. package/dist/hitl/askGateWire.js +2 -1
  91. package/dist/hitl/askSettlementLine.d.ts +14 -4
  92. package/dist/hitl/askSettlementLine.js +67 -47
  93. package/dist/hitl/attributionLadder.d.ts +23 -0
  94. package/dist/hitl/attributionLadder.js +67 -0
  95. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  96. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  97. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  98. package/dist/hitl/crashConvergedNotice.js +28 -41
  99. package/dist/hitl/decisionLedger.d.ts +55 -0
  100. package/dist/hitl/decisionLedger.js +156 -0
  101. package/dist/hitl/decisionRefusal.d.ts +1 -0
  102. package/dist/hitl/decisionRefusal.js +1 -1
  103. package/dist/hitl/decisionSend.d.ts +113 -0
  104. package/dist/hitl/decisionSend.js +579 -0
  105. package/dist/hitl/frameRouter.js +7 -8
  106. package/dist/hitl/hitlBridge.d.ts +1 -0
  107. package/dist/hitl/hitlBridge.js +21 -9
  108. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  109. package/dist/hitl/persistedRulesWire.js +55 -73
  110. package/dist/hitl/planReviewWire.d.ts +5 -0
  111. package/dist/hitl/planReviewWire.js +53 -76
  112. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  113. package/dist/hitl/sessionPolicyDeliverable.js +49 -9
  114. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  115. package/dist/hitl/sessionPolicyWire.js +23 -24
  116. package/dist/hitl/suspendedReopen.d.ts +2 -1
  117. package/dist/hitl/suspendedReopen.js +7 -10
  118. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  119. package/dist/hitl/toolApprovalWire.js +120 -147
  120. package/dist/hooksWireCaps.js +145 -56
  121. package/dist/host.d.ts +21 -0
  122. package/dist/hostTurnSettings.d.ts +110 -0
  123. package/dist/hostTurnSettings.js +692 -0
  124. package/dist/humanTurn.d.ts +15 -1
  125. package/dist/humanTurn.js +100 -12
  126. package/dist/humanTurnRead.d.ts +2 -0
  127. package/dist/humanTurnRead.js +22 -1
  128. package/dist/i18n/messages.en.d.ts +713 -0
  129. package/dist/i18n/messages.en.js +713 -0
  130. package/dist/i18n/messages.zh.js +854 -1
  131. package/dist/index.d.ts +45 -13
  132. package/dist/index.js +27 -9
  133. package/dist/inheritEnvCapability.d.ts +4 -2
  134. package/dist/inheritEnvCapability.js +12 -5
  135. package/dist/inheritEnvWire.d.ts +3 -2
  136. package/dist/inheritEnvWire.js +14 -16
  137. package/dist/injectionLaneNotice.d.ts +5 -0
  138. package/dist/injectionLaneNotice.js +46 -0
  139. package/dist/interactiveHalt.js +17 -6
  140. package/dist/liveModelCatalog.d.ts +2 -1
  141. package/dist/liveModelCatalog.js +14 -8
  142. package/dist/mcpPanel.d.ts +10 -1
  143. package/dist/mcpPanel.js +42 -13
  144. package/dist/mcpProbeCapability.d.ts +2 -1
  145. package/dist/mcpProbeCapability.js +7 -11
  146. package/dist/mcpProbeWire.d.ts +3 -1
  147. package/dist/mcpProbeWire.js +5 -0
  148. package/dist/mcpReconnect.js +2 -2
  149. package/dist/mcpToolToggles.d.ts +6 -0
  150. package/dist/mcpToolToggles.js +46 -0
  151. package/dist/mcpWireCaps.d.ts +43 -3
  152. package/dist/mcpWireCaps.js +194 -59
  153. package/dist/mcpWireTransport.d.ts +4 -0
  154. package/dist/mcpWireTransport.js +18 -0
  155. package/dist/memoryEntriesWire.js +5 -10
  156. package/dist/model/onboardJudgement.d.ts +93 -0
  157. package/dist/model/onboardJudgement.js +415 -0
  158. package/dist/model/tierVocabulary.d.ts +2 -0
  159. package/dist/model/tierVocabulary.js +17 -5
  160. package/dist/modelCapabilityProbe.d.ts +65 -0
  161. package/dist/modelCapabilityProbe.js +601 -0
  162. package/dist/modelIdentityResolvability.d.ts +5 -0
  163. package/dist/modelIdentityResolvability.js +49 -22
  164. package/dist/ownKey.d.ts +33 -0
  165. package/dist/ownKey.js +109 -0
  166. package/dist/panelReduce.d.ts +11 -1
  167. package/dist/panelReduce.js +95 -16
  168. package/dist/panelStateHolder.d.ts +1 -0
  169. package/dist/panelStateHolder.js +10 -1
  170. package/dist/permissionRuleIssue.d.ts +2 -1
  171. package/dist/permissionRuleIssue.js +23 -20
  172. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  173. package/dist/permissionRulesWriteCapability.js +8 -6
  174. package/dist/pluginHooksWire.d.ts +46 -3
  175. package/dist/pluginHooksWire.js +220 -12
  176. package/dist/prepareRefusal.d.ts +8 -0
  177. package/dist/prepareRefusal.js +72 -0
  178. package/dist/printModelStatus.d.ts +63 -0
  179. package/dist/printModelStatus.js +155 -0
  180. package/dist/request/taskRequest.d.ts +16 -10
  181. package/dist/request/taskRequest.js +195 -58
  182. package/dist/resumeRefusalCopy.d.ts +14 -9
  183. package/dist/resumeRefusalCopy.js +89 -144
  184. package/dist/retryStatus.d.ts +55 -0
  185. package/dist/retryStatus.js +155 -19
  186. package/dist/ruleRefusalSentence.d.ts +4 -0
  187. package/dist/ruleRefusalSentence.js +58 -0
  188. package/dist/sandboxWire.d.ts +2 -1
  189. package/dist/sandboxWire.js +55 -21
  190. package/dist/scenarioRefusal.d.ts +10 -0
  191. package/dist/scenarioRefusal.js +111 -0
  192. package/dist/seam.d.ts +48 -9
  193. package/dist/seam.js +54 -5
  194. package/dist/seatContract.d.ts +272 -14
  195. package/dist/seatContract.js +711 -23
  196. package/dist/selfOrchestrationDenial.js +7 -19
  197. package/dist/sessionIdSegment.d.ts +6 -0
  198. package/dist/sessionIdSegment.js +24 -0
  199. package/dist/sessionMemoryStatus.js +6 -11
  200. package/dist/sessionPolicyCapability.d.ts +2 -1
  201. package/dist/sessionPolicyCapability.js +8 -6
  202. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  203. package/dist/settingsCredentialKeyPaths.js +219 -0
  204. package/dist/settingsHooksSalvage.d.ts +44 -0
  205. package/dist/settingsHooksSalvage.js +211 -0
  206. package/dist/skillToolListsCapability.d.ts +2 -1
  207. package/dist/skillToolListsCapability.js +8 -6
  208. package/dist/skillsWireCaps.d.ts +0 -3
  209. package/dist/skillsWireCaps.js +1 -2
  210. package/dist/sseIdleTriage.js +3 -2
  211. package/dist/subagent/engineSubagentResume.js +15 -9
  212. package/dist/subagentContentStore.d.ts +4 -0
  213. package/dist/subagentContentStore.js +157 -27
  214. package/dist/toolHistoryMismatch.js +3 -2
  215. package/dist/toolRoster.d.ts +3 -2
  216. package/dist/toolRoster.js +21 -20
  217. package/dist/toolsFlagNames.d.ts +8 -0
  218. package/dist/toolsFlagNames.js +110 -0
  219. package/dist/turnFailurePresentation.d.ts +12 -1
  220. package/dist/turnFailurePresentation.js +220 -15
  221. package/dist/usageAnalytics.js +6 -11
  222. package/dist/userAttachmentEnvelope.d.ts +1 -0
  223. package/dist/userAttachmentEnvelope.js +37 -7
  224. package/dist/userAttachmentSeat.d.ts +21 -0
  225. package/dist/userAttachmentSeat.js +75 -0
  226. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  227. package/dist/userInvokedSkillsCapability.js +31 -7
  228. package/dist/wireErrorTriage.d.ts +7 -0
  229. package/dist/wireErrorTriage.js +23 -1
  230. package/dist/wireFailureShape.js +2 -1
  231. package/dist/wireRefusalCopy.d.ts +62 -16
  232. package/dist/wireRefusalCopy.js +307 -148
  233. package/dist/workflowsJournalCapability.d.ts +2 -1
  234. package/dist/workflowsJournalCapability.js +8 -6
  235. package/docs/INTEGRATION-CLIENTS.md +951 -42
  236. package/package.json +5 -5
package/dist/mcpPanel.js CHANGED
@@ -3,6 +3,7 @@ import { isSessionIdPathSegment } from './sessionIdSegment.js';
3
3
  import { projectMcpSection } from './adapter/downstream/eventToSdkMessage.js';
4
4
  import { capForDisplay } from './fleetTaskDesc.js';
5
5
  import { mcpLivenessRollupOf } from './mcpLiveness.js';
6
+ import { scenarioRefusalOf } from './scenarioRefusal.js';
6
7
  const MCP_PANEL_ERROR_MAX = 200;
7
8
  const MCP_PANEL_WORD_MAX = 40;
8
9
  const MCP_PANEL_NAMES_MAX = 8;
@@ -40,19 +41,29 @@ export function projectMcpPanel(body) {
40
41
  return undefined;
41
42
  if (!nonEmpty(body.asOf))
42
43
  return undefined;
43
- if (!Array.isArray(body.servers))
44
+ const refusal = scenarioRefusalOf(body);
45
+ if (refusal === null)
44
46
  return undefined;
45
- const servers = [];
46
- for (const r of body.servers) {
47
- const row = projectServerRow(r);
48
- if (row !== undefined)
49
- servers.push(row);
47
+ let view;
48
+ if (refusal !== undefined) {
49
+ view = { asOf: body.asOf, scenarioRefusal: refusal };
50
+ }
51
+ else {
52
+ if (!Array.isArray(body.servers))
53
+ return undefined;
54
+ const servers = [];
55
+ for (const r of body.servers) {
56
+ const row = projectServerRow(r);
57
+ if (row !== undefined)
58
+ servers.push(row);
59
+ }
60
+ if (body.servers.length > 0 && servers.length === 0)
61
+ return undefined;
62
+ const sv = { asOf: body.asOf, servers };
63
+ if (body.degraded === true)
64
+ sv.degraded = true;
65
+ view = sv;
50
66
  }
51
- if (body.servers.length > 0 && servers.length === 0)
52
- return undefined;
53
- const view = { asOf: body.asOf, servers };
54
- if (body.degraded === true)
55
- view.degraded = true;
56
67
  if ('lastLegMcp' in body) {
57
68
  const leg = projectLastLeg(body.lastLegMcp);
58
69
  if (leg !== undefined)
@@ -62,6 +73,20 @@ export function projectMcpPanel(body) {
62
73
  }
63
74
  return view;
64
75
  }
76
+ export function mcpPanelRefusalOf(view) {
77
+ try {
78
+ if (view === null || typeof view !== 'object')
79
+ return undefined;
80
+ const d = Object.getOwnPropertyDescriptor(view, 'scenarioRefusal');
81
+ if (d === undefined || !('value' in d))
82
+ return undefined;
83
+ const r = d.value;
84
+ return r !== null && typeof r === 'object' && !Array.isArray(r) ? r : undefined;
85
+ }
86
+ catch {
87
+ return undefined;
88
+ }
89
+ }
65
90
  export async function fetchMcpPanel(client, sessionId, opts) {
66
91
  if (!isSessionIdPathSegment(sessionId))
67
92
  return undefined;
@@ -95,15 +120,19 @@ export function mcpPanelLastLegDetail(view, opts) {
95
120
  }
96
121
  const _mcpPanelShapePin = (p) => p;
97
122
  void _mcpPanelShapePin;
123
+ const _mcpPanelRefusalPin = (p) => p;
124
+ void _mcpPanelRefusalPin;
98
125
  export function mcpEngineLegPresence(view) {
99
126
  if (view === undefined)
100
127
  return 'unknown';
101
- if (view.servers.length > 0)
102
- return 'present';
103
128
  if (view.lastLegMcp !== undefined)
104
129
  return 'present';
105
130
  if (view.lastLegMcpUnreadable === true)
106
131
  return 'present';
132
+ if (!('servers' in view))
133
+ return 'unknown';
134
+ if (view.servers.length > 0)
135
+ return 'present';
107
136
  if (view.degraded === true)
108
137
  return 'present';
109
138
  return 'absent';
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export type McpProbeReading = {
2
3
  kind: 'unobserved';
3
4
  } | {
@@ -12,4 +13,4 @@ export type McpProbeReading = {
12
13
  export declare function projectMcpProbeCapability(caps: unknown): McpProbeReading | undefined;
13
14
  export declare function observedMcpProbe(baseUrl?: string | undefined): McpProbeReading;
14
15
  export declare function mcpProbeAvailable(reading: McpProbeReading): 'yes' | 'no' | 'unknown';
15
- export declare function mcpProbeDoctorDetail(reading: McpProbeReading): string;
16
+ export declare function mcpProbeDoctorDetail(reading: McpProbeReading, lang?: UiLanguage): string;
@@ -1,5 +1,6 @@
1
1
  import { engineWireTarget } from './engineWireTarget.js';
2
2
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
3
+ import { msg, renderMessage } from './i18n/translate.js';
3
4
  import { ownDataField } from './ownKey.js';
4
5
  export function projectMcpProbeCapability(caps) {
5
6
  try {
@@ -30,22 +31,17 @@ export function mcpProbeAvailable(reading) {
30
31
  return 'no';
31
32
  return 'unknown';
32
33
  }
33
- export function mcpProbeDoctorDetail(reading) {
34
+ export function mcpProbeDoctorDetail(reading, lang) {
34
35
  switch (reading.kind) {
35
36
  case 'unreadable':
36
- return unreadableReadingDetail('per-server MCP status face');
37
+ return unreadableReadingDetail(renderMessage(msg('notice.capability.subject.mcpProbe'), lang), lang);
37
38
  case 'unobserved':
38
- return ('per-server MCP status face not observed — the engine reports whether it has one on /v1/capabilities; ' +
39
- '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)');
39
+ return renderMessage(msg('notice.capability.mcpProbe.unobserved'), lang);
40
40
  case 'not_reported':
41
- return ('per-server MCP status face not reported by this engine — this binary predates the face, so that path is not expected to exist here ' +
42
- '(asking it usually answers with a machine-readable route-not-found, though a timeout or an uncoded gateway answer still says nothing either way); ' +
43
- 'prefer the session panel last-leg roster where that panel carries one, and otherwise show this reason rather than an entry that cannot answer');
41
+ return renderMessage(msg('notice.capability.mcpProbe.notReported'), lang);
44
42
  case 'absent':
45
- return ('per-server MCP status face reported off on this deployment — this engine answers no readings there; ' +
46
- 'this client does not guess why, and whether caller-supplied declarations are honored is a separate position with its own answer');
43
+ return renderMessage(msg('notice.capability.mcpProbe.absent'), lang);
47
44
  case 'present':
48
- return ('per-server MCP status face on — this engine dials its own declared MCP servers on request, with no run, ' +
49
- 'and a probe of caller-supplied declarations answers with the very same body shape');
45
+ return renderMessage(msg('notice.capability.mcpProbe.present'), lang);
50
46
  }
51
47
  }
@@ -1,6 +1,7 @@
1
1
  import type { McpProbeFace, McpServerSpec } from '@sema-agent/sdk';
2
2
  import { type WiringManifestMcpEntryView } from './adapter/downstream/eventToSdkMessage.js';
3
3
  import { type McpProbeReading } from './mcpProbeCapability.js';
4
+ import { type ScenarioRefusalReading } from './scenarioRefusal.js';
4
5
  export interface McpProbeFacade {
5
6
  mcpCapabilities(opts?: {
6
7
  signal?: AbortSignal;
@@ -9,7 +10,7 @@ export interface McpProbeFacade {
9
10
  signal?: AbortSignal;
10
11
  }): Promise<McpProbeFace>;
11
12
  }
12
- export declare const MCP_PROBE_REFUSAL_CAUSES: readonly ["face_absent", "client_too_old", "unreadable_request", "injection_not_honored", "body_shape", "field_invalid", "body_unparseable", "payload_too_large", "rate_limited", "unauthorized", "principal_required", "principal_unverified"];
13
+ export declare const MCP_PROBE_REFUSAL_CAUSES: readonly ["face_absent", "client_too_old", "unreadable_request", "injection_not_honored", "body_shape", "field_invalid", "body_unparseable", "payload_too_large", "rate_limited", "unauthorized", "principal_required", "principal_unverified", "scenario_refused"];
13
14
  export type McpProbeRefusalCause = (typeof MCP_PROBE_REFUSAL_CAUSES)[number];
14
15
  export declare const MCP_PROBE_UNKNOWN_WHYS: readonly ["no_verdict", "probe_incomplete", "server_fault", "result_unreadable", "index_misaligned", "unclassified"];
15
16
  export type McpProbeUnknownWhy = (typeof MCP_PROBE_UNKNOWN_WHYS)[number];
@@ -18,6 +19,7 @@ export type McpProbeRefused = {
18
19
  cause: McpProbeRefusalCause;
19
20
  message: string;
20
21
  retryAfterSec?: number;
22
+ scenarioRefusal?: ScenarioRefusalReading;
21
23
  };
22
24
  export type McpProbeUnknown = {
23
25
  status: 'unknown';
@@ -1,6 +1,7 @@
1
1
  import { projectMcpSection } from './adapter/downstream/eventToSdkMessage.js';
2
2
  import { wireFailureShapeOf } from './wireFailureShape.js';
3
3
  import { mcpProbeAvailable } from './mcpProbeCapability.js';
4
+ import { scenarioRefusalFromError } from './scenarioRefusal.js';
4
5
  export const MCP_PROBE_REFUSAL_CAUSES = Object.freeze([
5
6
  'face_absent',
6
7
  'client_too_old',
@@ -14,6 +15,7 @@ export const MCP_PROBE_REFUSAL_CAUSES = Object.freeze([
14
15
  'unauthorized',
15
16
  'principal_required',
16
17
  'principal_unverified',
18
+ 'scenario_refused',
17
19
  ]);
18
20
  export const MCP_PROBE_UNKNOWN_WHYS = Object.freeze([
19
21
  'no_verdict',
@@ -168,6 +170,9 @@ export async function readMcpCapabilities(facade, call, opts) {
168
170
  res = await facade.mcpCapabilities(opts);
169
171
  }
170
172
  catch (e) {
173
+ const refusal = scenarioRefusalFromError(e);
174
+ if (refusal !== null)
175
+ return { ...refusedBy('scenario_refused', wireFailureShapeOf(e).message), scenarioRefusal: refusal };
171
176
  return classifyMcpProbeFailure(e);
172
177
  }
173
178
  const narrowed = narrowProbeFace(res);
@@ -187,14 +187,14 @@ export function mcpReconnectOutcomeDetail(view) {
187
187
  const name = capForDisplay(view.server, RECONNECT_WORD_MAX);
188
188
  switch (view.outcome) {
189
189
  case 'accepted':
190
- return `MCP server ${name} was re-dialed: ${view.toolCount} tool${view.toolCount === 1 ? '' : 's'} mounted (${view.added.length} added, ${view.removed.length} removed)`;
190
+ return `MCP server ${name} was re-dialed: ${view.toolCount} tool${view.toolCount === 1 ? '' : 's'} mounted for this run (${view.added.length} added, ${view.removed.length} removed)`;
191
191
  case 'refused': {
192
192
  const why = view.reason !== undefined ? ` — ${view.reason}` : '';
193
193
  if (view.toolNames === undefined) {
194
194
  return `MCP server ${name} was NOT re-dialed; its connection and tools were left untouched${why}`;
195
195
  }
196
196
  if (view.toolNames.length === 0) {
197
- return `MCP server ${name} was NOT re-dialed and its tools were withdrawn from the model until a later re-dial succeeds${why}`;
197
+ return `MCP server ${name} was NOT re-dialed; this run's tool list has no tools from it right now (the dial failed, or this run's tool settings let none of its tools through)${why}`;
198
198
  }
199
199
  return `MCP server ${name} was NOT re-dialed; the engine reports ${view.toolNames.length} tool${view.toolNames.length === 1 ? '' : 's'} for it after this attempt${why}`;
200
200
  }
@@ -0,0 +1,6 @@
1
+ export interface McpToolToggleKey {
2
+ readonly server: string;
3
+ readonly tool: string;
4
+ }
5
+ export type McpMountedServers = readonly string[] | 'unknown';
6
+ export declare function mcpToolTogglesToExcludeTools(keys: readonly McpToolToggleKey[], mountedServers: McpMountedServers): string[];
@@ -0,0 +1,46 @@
1
+ import { checkMcpToolToggleKey } from './seatContract.js';
2
+ function keyOf(key, index) {
3
+ const refuse = (why) => new TypeError(`mcpToolTogglesToExcludeTools: keys[${index}] 不是逐工具开关键 { server, tool }(${why})—— 值不回显。` +
4
+ '宿主存档读坏了请在读档处用 checkMcpToolToggleKey 判,不要交进来让它在每一回合被静默丢掉。');
5
+ const shape = checkMcpToolToggleKey(key);
6
+ if (shape !== true)
7
+ throw refuse(`${shape.reason}${shape.field !== undefined ? ` @ ${shape.field}` : ''}`);
8
+ let snap;
9
+ try {
10
+ snap = { server: Object.getOwnPropertyDescriptor(key, 'server')?.value, tool: Object.getOwnPropertyDescriptor(key, 'tool')?.value };
11
+ }
12
+ catch {
13
+ throw refuse('读不出');
14
+ }
15
+ const again = checkMcpToolToggleKey(snap);
16
+ if (again !== true)
17
+ throw refuse(`${again.reason}${again.field !== undefined ? ` @ ${again.field}` : ''};判形之后读到的值与判过的不一致`);
18
+ return Object.freeze({ server: snap.server, tool: snap.tool });
19
+ }
20
+ function mountedSetOf(mountedServers) {
21
+ if (mountedServers === 'unknown')
22
+ return 'unknown';
23
+ if (!Array.isArray(mountedServers) || !mountedServers.every((s) => typeof s === 'string')) {
24
+ throw new TypeError("mcpToolTogglesToExcludeTools: mountedServers 只接受服务器名(串)数组,或宿主判不出时交 'unknown' —— 收到别的形(值不回显)。" +
25
+ "不知道本回合挂了哪些时请交 'unknown'(全部出),不要交 [](那会把用户关掉的工具静默放回)。");
26
+ }
27
+ return new Set(mountedServers);
28
+ }
29
+ export function mcpToolTogglesToExcludeTools(keys, mountedServers) {
30
+ if (!Array.isArray(keys)) {
31
+ throw new TypeError('mcpToolTogglesToExcludeTools: keys 必须是逐工具开关键数组(值不回显)。');
32
+ }
33
+ const mounted = mountedSetOf(mountedServers);
34
+ const parts = keys.map((k, i) => keyOf(k, i));
35
+ const out = [];
36
+ const seen = new Set();
37
+ for (const { server, tool } of parts) {
38
+ if (mounted !== 'unknown' && !mounted.has(server))
39
+ continue;
40
+ if (seen.has(tool))
41
+ continue;
42
+ seen.add(tool);
43
+ out.push(tool);
44
+ }
45
+ return out;
46
+ }
@@ -1,8 +1,7 @@
1
1
  import type { McpServerSpec } from '@sema-agent/sdk';
2
+ import type { McpEntryKeyIssue } from './generated/settingsSchemaTypes.js';
3
+ import type { UiLanguage } from './env/uiLanguage.js';
2
4
  export type { McpServerSpec };
3
- export declare const MCP_CAPS: {
4
- readonly items: 32;
5
- };
6
5
  export interface McpConfigLike {
7
6
  type?: string;
8
7
  command?: string;
@@ -13,8 +12,10 @@ export interface McpConfigLike {
13
12
  principalHeader?: string;
14
13
  assertionHeader?: string;
15
14
  allowTools?: string[];
15
+ elicitation?: {} | null | undefined;
16
16
  toolFaces?: unknown;
17
17
  toolAxes?: unknown;
18
+ startupTimeoutMs?: number;
18
19
  }
19
20
  export type McpHttpIdentityHeaders = {
20
21
  readonly kind: 'ok';
@@ -26,4 +27,43 @@ export type McpHttpIdentityHeaders = {
26
27
  export declare function readMcpHttpIdentityHeaders(transport: object): McpHttpIdentityHeaders;
27
28
  export declare function mcpConfigToSpec(name: string, c: McpConfigLike): McpServerSpec | null;
28
29
  export declare function mcpConfigsToSpecs(servers: Record<string, McpConfigLike> | undefined): McpServerSpec[];
30
+ export type McpToolAxesVerdict = {
31
+ readonly kind: 'ok';
32
+ readonly toolAxes?: Readonly<Record<string, object>>;
33
+ } | {
34
+ readonly kind: 'bad';
35
+ readonly problem: string;
36
+ } | {
37
+ readonly kind: 'unavailable';
38
+ };
39
+ export declare function mcpToolAxesVerdict(declared: {} | null | undefined): McpToolAxesVerdict;
40
+ export declare function mcpElicitationVerdict(declared: {} | null | undefined): {
41
+ readonly kind: 'ok';
42
+ readonly elicitation?: boolean;
43
+ } | {
44
+ readonly kind: 'bad';
45
+ };
46
+ export type McpConfigDropReason = 'name_blank' | 'name_edge_whitespace' | 'name_collides_after_trim' | 'name_too_long' | 'transport_invalid' | 'identity_headers_both_set' | 'tool_axes_invalid' | 'elicitation_invalid';
47
+ export interface McpConfigDropped {
48
+ readonly name: string;
49
+ readonly reason: McpConfigDropReason;
50
+ readonly problem?: string;
51
+ readonly path?: string;
52
+ readonly notice: string;
53
+ }
54
+ export interface McpConfigDegraded {
55
+ readonly name: string;
56
+ readonly lost: readonly McpEntryKeyIssue[];
57
+ readonly notice: string;
58
+ }
59
+ export interface McpConfigProjection {
60
+ readonly specs: McpServerSpec[];
61
+ readonly dropped: readonly McpConfigDropped[];
62
+ readonly degraded: readonly McpConfigDegraded[];
63
+ }
64
+ export interface ProjectMcpConfigsOptions {
65
+ readonly sourceLabel?: (serverName: string) => string | undefined;
66
+ readonly lang?: UiLanguage;
67
+ }
68
+ export declare function projectMcpConfigs(servers: Record<string, McpConfigLike> | undefined, opts?: ProjectMcpConfigsOptions): McpConfigProjection;
29
69
  export declare function mcpAssertionHeaderNotSentNotice(specs: readonly McpServerSpec[]): string | undefined;
@@ -1,79 +1,214 @@
1
+ import { SETTINGS_DESCRIBE_BAD_WIRE_NAME, SETTINGS_IS_USABLE_WIRE_NAME, SETTINGS_READ_MCP_IDENTITY_HEADERS, SETTINGS_READ_REQUEST_MCP_TRANSPORT, } from './generated/settingsSchemaFns.js';
2
+ import { snapshotArgs, wireTransportOf } from './mcpWireTransport.js';
1
3
  import { guardedRead } from './ownKey.js';
4
+ import { readMcpToolAxes } from './coreValuePorts.js';
5
+ import { capForDisplay } from './fleetTaskDesc.js';
6
+ import { msg, renderMessage } from './i18n/translate.js';
2
7
  const _mcpServerSpecPin = true;
3
8
  void _mcpServerSpecPin;
4
- export const MCP_CAPS = { items: 32 };
5
- function transparentKeys(c) {
9
+ function transparentKeys(c, axes, elicitation) {
6
10
  return {
7
11
  ...(c.toolFaces !== undefined ? { toolFaces: c.toolFaces } : {}),
8
- ...(c.toolAxes !== undefined ? { toolAxes: c.toolAxes } : {}),
12
+ ...(axes !== undefined ? { toolAxes: axes } : {}),
13
+ ...(elicitation !== undefined ? { elicitation } : {}),
14
+ ...(c.startupTimeoutMs !== undefined ? { startupTimeoutMs: c.startupTimeoutMs } : {}),
9
15
  };
10
16
  }
11
- function presentHeaderName(v) {
12
- return typeof v === 'string' && v.length > 0 ? v : undefined;
13
- }
14
17
  export function readMcpHttpIdentityHeaders(transport) {
15
18
  const t = transport;
16
- const principalHeader = presentHeaderName(t.principalHeader);
17
- const assertionHeader = presentHeaderName(t.assertionHeader);
19
+ const principalHeader = t.principalHeader;
20
+ const assertionHeader = t.assertionHeader;
18
21
  if (principalHeader !== undefined && assertionHeader !== undefined)
19
22
  return { kind: 'both_set' };
20
- return {
21
- kind: 'ok',
22
- ...(principalHeader !== undefined ? { principalHeader } : {}),
23
- ...(assertionHeader !== undefined ? { assertionHeader } : {}),
24
- };
23
+ return { kind: 'ok', ...SETTINGS_READ_MCP_IDENTITY_HEADERS({ principalHeader, assertionHeader }) };
25
24
  }
26
25
  export function mcpConfigToSpec(name, c) {
27
- const n = (name ?? '').trim();
28
- if (!n)
29
- return null;
30
- const kind = c.type ?? 'stdio';
31
- if (kind === 'stdio') {
32
- if (!c.command)
33
- return null;
34
- return {
35
- name: n,
36
- transport: {
37
- kind: 'stdio',
38
- command: c.command,
39
- ...(c.args && c.args.length > 0 ? { args: c.args } : {}),
40
- ...(c.env ? { env: c.env } : {}),
41
- },
42
- ...(c.allowTools && c.allowTools.length > 0 ? { allowTools: c.allowTools } : {}),
43
- ...transparentKeys(c),
44
- };
26
+ return mcpConfigEntry(name, c).spec;
27
+ }
28
+ function mcpConfigEntry(name, c) {
29
+ if (!nameUsable(name))
30
+ return { spec: null };
31
+ const declared = c.toolAxes;
32
+ const verdict = mcpToolAxesVerdict(declared);
33
+ const elDeclared = c.elicitation;
34
+ const elVerdict = mcpElicitationVerdict(elDeclared);
35
+ if (verdict.kind === 'bad' || elVerdict.kind === 'bad') {
36
+ const rest = specOf(name, c, undefined, undefined);
37
+ if (rest.kind === 'skip')
38
+ return { spec: null };
39
+ if (rest.kind === 'both_set')
40
+ return { spec: null, identityBothSet: true };
41
+ if (rest.kind === 'bad')
42
+ return { spec: null, transportBad: rest.issue };
43
+ return verdict.kind === 'bad' ? { spec: null, axesProblem: verdict.problem } : { spec: null, elicitationInvalid: true };
44
+ }
45
+ const read = specOf(name, c, verdict.kind === 'ok' ? verdict.toolAxes : declared, elVerdict.elicitation);
46
+ if (read.kind === 'skip')
47
+ return { spec: null };
48
+ if (read.kind === 'both_set')
49
+ return { spec: null, identityBothSet: true };
50
+ if (read.kind === 'bad')
51
+ return { spec: null, transportBad: read.issue };
52
+ return { spec: read.spec, ...(read.lost.length > 0 ? { transportLost: read.lost } : {}) };
53
+ }
54
+ function specOf(name, c, axes, elicitation) {
55
+ let candidate;
56
+ try {
57
+ const kind = c.type ?? 'stdio';
58
+ if (kind === 'stdio') {
59
+ const command = c.command;
60
+ const head = SETTINGS_READ_REQUEST_MCP_TRANSPORT({ kind: 'stdio', command });
61
+ if (!head.ok)
62
+ return { kind: 'bad', issue: head.issue };
63
+ candidate = { kind: 'stdio', command, args: snapshotArgs(c.args), env: c.env };
64
+ }
65
+ else if (kind === 'http') {
66
+ const url = c.url;
67
+ const head = SETTINGS_READ_REQUEST_MCP_TRANSPORT({ kind: 'http', url });
68
+ if (!head.ok)
69
+ return { kind: 'bad', issue: head.issue };
70
+ const principalHeader = c.principalHeader;
71
+ const assertionHeader = c.assertionHeader;
72
+ if (readMcpHttpIdentityHeaders({ principalHeader, assertionHeader }).kind === 'both_set')
73
+ return { kind: 'both_set' };
74
+ candidate = { kind: 'http', url, headers: c.headers, principalHeader, assertionHeader };
75
+ }
76
+ else {
77
+ return { kind: 'skip' };
78
+ }
45
79
  }
46
- if (kind === 'http') {
47
- if (!c.url)
48
- return null;
49
- const id = readMcpHttpIdentityHeaders(c);
50
- if (id.kind === 'both_set')
51
- return null;
52
- return {
53
- name: n,
54
- transport: {
55
- kind: 'http',
56
- url: c.url,
57
- ...(c.headers ? { headers: c.headers } : {}),
58
- ...(id.principalHeader !== undefined ? { principalHeader: id.principalHeader } : {}),
59
- ...(id.assertionHeader !== undefined ? { assertionHeader: id.assertionHeader } : {}),
60
- },
61
- ...(c.allowTools && c.allowTools.length > 0 ? { allowTools: c.allowTools } : {}),
62
- ...transparentKeys(c),
63
- };
80
+ catch {
81
+ return { kind: 'bad', issue: { path: 'transport', reason: renderMessage(msg('config.mcp.transportUnreadable')) } };
64
82
  }
65
- return null;
83
+ const read = SETTINGS_READ_REQUEST_MCP_TRANSPORT(candidate);
84
+ if (!read.ok)
85
+ return { kind: 'bad', issue: read.issue };
86
+ const spec = {
87
+ name,
88
+ transport: wireTransportOf(read.transport),
89
+ ...(Array.isArray(c.allowTools) ? { allowTools: c.allowTools } : {}),
90
+ ...transparentKeys(c, axes, elicitation),
91
+ };
92
+ return { kind: 'ok', spec, lost: read.lost };
66
93
  }
67
94
  export function mcpConfigsToSpecs(servers) {
68
- const out = [];
69
- for (const [name, c] of Object.entries(servers ?? {})) {
70
- if (out.length >= MCP_CAPS.items)
71
- break;
72
- const spec = mcpConfigToSpec(name, c);
73
- if (spec)
74
- out.push(spec);
95
+ return projectMcpConfigs(servers).specs;
96
+ }
97
+ export function mcpToolAxesVerdict(declared) {
98
+ if (declared === undefined)
99
+ return Object.freeze({ kind: 'ok' });
100
+ const read = readMcpToolAxes(declared);
101
+ if (read === undefined || read === null || typeof read !== 'object')
102
+ return Object.freeze({ kind: 'unavailable' });
103
+ if (read.ok === true) {
104
+ const copy = read.toolAxes;
105
+ return Object.freeze(typeof copy === 'object' && copy !== null ? { kind: 'ok', toolAxes: copy } : { kind: 'ok' });
106
+ }
107
+ if (read.ok === false) {
108
+ const problem = read.problem;
109
+ return Object.freeze({ kind: 'bad', problem: typeof problem === 'string' && problem.length > 0 ? problem : renderMessage(msg('config.mcp.toolAxesFallbackProblem')) });
110
+ }
111
+ return Object.freeze({ kind: 'unavailable' });
112
+ }
113
+ export function mcpElicitationVerdict(declared) {
114
+ if (declared === undefined)
115
+ return Object.freeze({ kind: 'ok' });
116
+ return typeof declared === 'boolean' ? Object.freeze({ kind: 'ok', elicitation: declared }) : Object.freeze({ kind: 'bad' });
117
+ }
118
+ const nameUsable = (name) => SETTINGS_IS_USABLE_WIRE_NAME(name);
119
+ function mcpNameDropReasonOf(name) {
120
+ if (typeof name !== 'string' || name.trim().length === 0)
121
+ return 'name_blank';
122
+ return name.trim() !== name ? 'name_edge_whitespace' : 'name_too_long';
123
+ }
124
+ const DROP_NAME_SHOWN = 80;
125
+ const DROP_LABEL_SHOWN = 140;
126
+ const DROP_PROBLEM_SHOWN = 300;
127
+ const DROP_BAD_NAME_SHOWN = 160;
128
+ const DEGRADED_LOST_SHOWN = 400;
129
+ function dropNotice(name, reason, problem, opts, path) {
130
+ let label;
131
+ try {
132
+ label = opts?.sourceLabel?.(name);
133
+ }
134
+ catch {
135
+ label = undefined;
136
+ }
137
+ const where = typeof label === 'string' && label.length > 0 ? ` (${capForDisplay(label, DROP_LABEL_SHOWN)})` : '';
138
+ const quoted = `"${capForDisplay(name, DROP_NAME_SHOWN)}"`;
139
+ const badName = () => capForDisplay(SETTINGS_DESCRIBE_BAD_WIRE_NAME(name), DROP_BAD_NAME_SHOWN);
140
+ const ref = reason === 'tool_axes_invalid'
141
+ ? msg('config.mcp.toolAxesInvalid', { name: quoted, where, problem: capForDisplay(problem ?? renderMessage(msg('config.mcp.toolAxesFallbackProblem')), DROP_PROBLEM_SHOWN) })
142
+ : reason === 'elicitation_invalid'
143
+ ? msg('config.mcp.elicitationInvalid', { name: quoted, where })
144
+ : reason === 'identity_headers_both_set'
145
+ ? msg('config.mcp.identityHeadersBothSet', { name: quoted, where })
146
+ : reason === 'transport_invalid'
147
+ ? msg('config.mcp.transportInvalid', { name: quoted, where, path: capForDisplay(path ?? 'transport', DROP_NAME_SHOWN), problem: capForDisplay(problem ?? '', DROP_PROBLEM_SHOWN) })
148
+ : reason === 'name_blank'
149
+ ? msg('config.mcp.nameBlank', { name: badName(), where })
150
+ : reason === 'name_collides_after_trim'
151
+ ? msg('config.mcp.nameCollides', { name: badName(), where })
152
+ : reason === 'name_too_long'
153
+ ? msg('config.mcp.nameTooLong', { name: badName(), where })
154
+ : msg('config.mcp.nameEdgeWhitespace', { name: badName(), where });
155
+ return renderMessage(ref, opts?.lang);
156
+ }
157
+ function degradedNotice(name, lost, opts) {
158
+ let label;
159
+ try {
160
+ label = opts?.sourceLabel?.(name);
161
+ }
162
+ catch {
163
+ label = undefined;
164
+ }
165
+ const where = typeof label === 'string' && label.length > 0 ? ` (${capForDisplay(label, DROP_LABEL_SHOWN)})` : '';
166
+ const quoted = `"${capForDisplay(name, DROP_NAME_SHOWN)}"`;
167
+ const what = capForDisplay(lost.map((l) => `${l.path}: ${l.reason}`).join('; '), DEGRADED_LOST_SHOWN);
168
+ return renderMessage(msg('config.mcp.transportDegraded', { name: quoted, where, lost: what }), opts?.lang);
169
+ }
170
+ export function projectMcpConfigs(servers, opts) {
171
+ const specs = [];
172
+ const dropped = [];
173
+ const degraded = [];
174
+ const entries = Object.entries(servers ?? {});
175
+ const exactNames = new Set();
176
+ const trimmedCount = new Map();
177
+ for (const [name] of entries) {
178
+ if (nameUsable(name))
179
+ exactNames.add(name);
180
+ else if (mcpNameDropReasonOf(name) === 'name_edge_whitespace')
181
+ trimmedCount.set(name.trim(), (trimmedCount.get(name.trim()) ?? 0) + 1);
182
+ }
183
+ for (const [name, c] of entries) {
184
+ if (!nameUsable(name)) {
185
+ const flaw = mcpNameDropReasonOf(name);
186
+ const reason = flaw === 'name_edge_whitespace' && (exactNames.has(name.trim()) || (trimmedCount.get(name.trim()) ?? 0) > 1) ? 'name_collides_after_trim' : flaw;
187
+ dropped.push({ name, reason, notice: dropNotice(name, reason, undefined, opts) });
188
+ continue;
189
+ }
190
+ const out = mcpConfigEntry(name, c);
191
+ if (out.spec !== null) {
192
+ specs.push(out.spec);
193
+ if (out.transportLost !== undefined)
194
+ degraded.push({ name, lost: Object.freeze([...out.transportLost]), notice: degradedNotice(name, out.transportLost, opts) });
195
+ continue;
196
+ }
197
+ if (out.identityBothSet === true) {
198
+ dropped.push({ name, reason: 'identity_headers_both_set', notice: dropNotice(name, 'identity_headers_both_set', undefined, opts) });
199
+ }
200
+ else if (out.transportBad !== undefined) {
201
+ const { path, reason: problem } = out.transportBad;
202
+ dropped.push({ name, reason: 'transport_invalid', problem, path, notice: dropNotice(name, 'transport_invalid', problem, opts, path) });
203
+ }
204
+ else if (out.axesProblem !== undefined) {
205
+ dropped.push({ name, reason: 'tool_axes_invalid', problem: out.axesProblem, notice: dropNotice(name, 'tool_axes_invalid', out.axesProblem, opts) });
206
+ }
207
+ else if (out.elicitationInvalid === true) {
208
+ dropped.push({ name, reason: 'elicitation_invalid', notice: dropNotice(name, 'elicitation_invalid', undefined, opts) });
209
+ }
75
210
  }
76
- return out;
211
+ return { specs, dropped: Object.freeze(dropped), degraded: Object.freeze(degraded) };
77
212
  }
78
213
  function assertionDeclaringServerName(spec) {
79
214
  const t = spec?.transport;
@@ -97,6 +232,6 @@ export function mcpAssertionHeaderNotSentNotice(specs) {
97
232
  const parts = distinct.slice(0, ASSERTION_NOTICE_NAMES_SHOWN).map((x) => `"${x}"`);
98
233
  if (distinct.length > ASSERTION_NOTICE_NAMES_SHOWN)
99
234
  parts.push(`+${distinct.length - ASSERTION_NOTICE_NAMES_SHOWN} more`);
100
- return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.129.1 accept this setting but do not send the header, ` +
235
+ return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.132.0 accept this setting but do not send the header, ` +
101
236
  'and this client cannot tell whether the engine it uses sends it; a connector that requires the header will refuse requests from these servers');
102
237
  }
@@ -0,0 +1,4 @@
1
+ import type { McpServerSpec } from '@sema-agent/sdk';
2
+ import type { RequestMcpTransport } from './generated/settingsSchemaTypes.js';
3
+ export declare function snapshotArgs(v: {} | null | undefined): {} | null | undefined;
4
+ export declare function wireTransportOf(t: RequestMcpTransport): McpServerSpec['transport'];
@@ -0,0 +1,18 @@
1
+ const ARGS_SNAPSHOT_MAX = 65_536;
2
+ export function snapshotArgs(v) {
3
+ if (!Array.isArray(v))
4
+ return v;
5
+ const n = v.length;
6
+ if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0 || n > ARGS_SNAPSHOT_MAX)
7
+ return {};
8
+ const out = [];
9
+ for (let i = 0; i < n; i++)
10
+ out.push(v[i]);
11
+ return out;
12
+ }
13
+ export function wireTransportOf(t) {
14
+ if (t.kind === 'stdio') {
15
+ return { kind: 'stdio', command: t.command, ...(t.args !== undefined && t.args.length > 0 ? { args: t.args } : {}), ...(t.env !== undefined ? { env: t.env } : {}) };
16
+ }
17
+ return t;
18
+ }