@sema-agent/client-core 0.97.1 → 0.98.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 (281) hide show
  1. package/CHANGELOG.md +408 -0
  2. package/README.md +74 -37
  3. package/dist/adapt/arms.d.ts +1 -0
  4. package/dist/adapt/arms.js +128 -34
  5. package/dist/adapt/ids.d.ts +12 -1
  6. package/dist/adapt/ids.js +59 -8
  7. package/dist/adapt/instanceLedger.d.ts +50 -0
  8. package/dist/adapt/instanceLedger.js +147 -0
  9. package/dist/adapt/textStream.d.ts +1 -0
  10. package/dist/adapt/textStream.js +24 -7
  11. package/dist/adapt/toolCards.d.ts +27 -5
  12. package/dist/adapt/toolCards.js +39 -6
  13. package/dist/adapt/wireShapes.js +6 -2
  14. package/dist/adapt.d.ts +2 -0
  15. package/dist/adapt.js +8 -3
  16. package/dist/adapter/activeRunSelfHeal.d.ts +5 -0
  17. package/dist/adapter/activeRunSelfHeal.js +51 -28
  18. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
  19. package/dist/adapter/downstream/eventToSdkMessage.js +27 -34
  20. package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
  21. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
  22. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
  23. package/dist/adapter/runStream.js +29 -13
  24. package/dist/adapter/types.d.ts +4 -4
  25. package/dist/agentSession/backgroundView.js +2 -1
  26. package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
  27. package/dist/agentSession/engineAgentRegistryRead.js +12 -13
  28. package/dist/agentsWireCaps.d.ts +8 -8
  29. package/dist/agentsWireCaps.js +168 -175
  30. package/dist/approvalDecidedByCapability.d.ts +0 -4
  31. package/dist/approvalDecidedByCapability.js +0 -6
  32. package/dist/approvalsStreamLiveCapability.d.ts +0 -4
  33. package/dist/approvalsStreamLiveCapability.js +0 -6
  34. package/dist/assistantInbox.d.ts +34 -0
  35. package/dist/assistantInbox.js +118 -0
  36. package/dist/centerWiringCapability.js +9 -1
  37. package/dist/clientSlice.d.ts +0 -9
  38. package/dist/clientSlice.js +0 -3
  39. package/dist/cloudConfigWireCaps.d.ts +4 -2
  40. package/dist/cloudConfigWireCaps.js +81 -61
  41. package/dist/compensations.js +1 -1
  42. package/dist/connectorStatus.d.ts +21 -0
  43. package/dist/connectorStatus.js +112 -0
  44. package/dist/controlRouter.d.ts +14 -1
  45. package/dist/controlRouter.js +68 -17
  46. package/dist/coreValuePorts.d.ts +3 -3
  47. package/dist/decideReceipt.d.ts +2 -2
  48. package/dist/decideReceipt.js +5 -2
  49. package/dist/declared/supportFloorDeclared.js +3 -3
  50. package/dist/deviceExecutorManagementCapability.d.ts +0 -4
  51. package/dist/deviceExecutorManagementCapability.js +0 -6
  52. package/dist/deviceRebind.d.ts +49 -1
  53. package/dist/deviceRebind.js +221 -3
  54. package/dist/displayUntrusted.d.ts +1 -0
  55. package/dist/displayUntrusted.js +250 -76
  56. package/dist/engineAgentAbsence.d.ts +1 -1
  57. package/dist/engineAgentPanelStore.d.ts +5 -4
  58. package/dist/engineAgentPanelStore.js +3 -12
  59. package/dist/engineCapReader.d.ts +0 -4
  60. package/dist/engineCapReader.js +1 -5
  61. package/dist/engineCapsCache.d.ts +4 -0
  62. package/dist/engineCapsCache.js +17 -12
  63. package/dist/engineClosedSets.d.ts +1 -0
  64. package/dist/engineClosedSets.js +4 -1
  65. package/dist/engineErrorCodes.d.ts +9 -2
  66. package/dist/engineErrorCodes.js +9 -1
  67. package/dist/engineIdentity.d.ts +1 -0
  68. package/dist/engineIdentity.js +8 -0
  69. package/dist/engineRowRef.d.ts +28 -0
  70. package/dist/engineRowRef.js +111 -0
  71. package/dist/engineSessionMessages.d.ts +67 -0
  72. package/dist/engineSessionMessages.js +364 -0
  73. package/dist/engineToolDirectory.d.ts +0 -9
  74. package/dist/engineToolDirectory.js +1 -94
  75. package/dist/engineUrl.d.ts +18 -0
  76. package/dist/engineUrl.js +52 -0
  77. package/dist/env/uiLanguage.d.ts +9 -0
  78. package/dist/env/uiLanguage.js +35 -0
  79. package/dist/eventLeg.d.ts +92 -0
  80. package/dist/eventLeg.js +285 -0
  81. package/dist/executionLaneCapability.d.ts +0 -4
  82. package/dist/executionLaneCapability.js +3 -16
  83. package/dist/fileHistoryCaptureCapability.d.ts +0 -4
  84. package/dist/fileHistoryCaptureCapability.js +5 -7
  85. package/dist/fleet/fleetLedger.d.ts +0 -3
  86. package/dist/fleet/fleetLedger.js +21 -36
  87. package/dist/fleet/fleetProjection.d.ts +2 -2
  88. package/dist/fleet/fleetProjection.js +10 -8
  89. package/dist/frameBinding.d.ts +5 -0
  90. package/dist/frameBinding.js +23 -0
  91. package/dist/gateFailureCodes.d.ts +2 -0
  92. package/dist/gateFailureCodes.js +15 -0
  93. package/dist/gateOutcome.d.ts +3 -1
  94. package/dist/gateOutcome.js +25 -6
  95. package/dist/gateVocabulary.d.ts +5 -0
  96. package/dist/gateVocabulary.js +64 -2
  97. package/dist/generated/engineAskFaceTables.js +2 -2
  98. package/dist/generated/engineFactTables.d.ts +6 -3
  99. package/dist/generated/engineFactTables.js +22 -4
  100. package/dist/generated/engineNoticeTables.js +9 -0
  101. package/dist/generated/toolNameTables.d.ts +1 -0
  102. package/dist/generated/toolNameTables.js +1 -0
  103. package/dist/hitl/allowRuleShadow.d.ts +6 -1
  104. package/dist/hitl/allowRuleShadow.js +21 -17
  105. package/dist/hitl/approvalCardReading.d.ts +15 -0
  106. package/dist/hitl/approvalCardReading.js +154 -0
  107. package/dist/hitl/approvalCardReasons.d.ts +13 -0
  108. package/dist/hitl/approvalCardReasons.js +120 -0
  109. package/dist/hitl/approvalHolds.d.ts +47 -15
  110. package/dist/hitl/approvalHolds.js +134 -28
  111. package/dist/hitl/approvalResolution.d.ts +51 -26
  112. package/dist/hitl/approvalResolution.js +86 -122
  113. package/dist/hitl/approvalsFeed.js +6 -18
  114. package/dist/hitl/askClassPair.d.ts +2 -0
  115. package/dist/hitl/askClassPair.js +1 -0
  116. package/dist/hitl/askGateWire.d.ts +20 -2
  117. package/dist/hitl/askGateWire.js +49 -1
  118. package/dist/hitl/askParkRowRouting.d.ts +5 -0
  119. package/dist/hitl/askParkRowRouting.js +32 -1
  120. package/dist/hitl/askSettlementLine.d.ts +18 -0
  121. package/dist/hitl/askSettlementLine.js +79 -0
  122. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  123. package/dist/hitl/automaticAnswerVerdict.js +21 -5
  124. package/dist/hitl/crashConverged.d.ts +11 -20
  125. package/dist/hitl/crashConverged.js +56 -0
  126. package/dist/hitl/crashConvergedNotice.d.ts +3 -1
  127. package/dist/hitl/crashConvergedNotice.js +48 -11
  128. package/dist/hitl/decisionConflict.js +3 -10
  129. package/dist/hitl/decisionRefusal.d.ts +40 -1
  130. package/dist/hitl/decisionRefusal.js +199 -42
  131. package/dist/hitl/frameRouter.d.ts +5 -2
  132. package/dist/hitl/frameRouter.js +20 -16
  133. package/dist/hitl/gateLedger.d.ts +2 -0
  134. package/dist/hitl/gateLedger.js +50 -13
  135. package/dist/hitl/hitlBridge.d.ts +1 -2
  136. package/dist/hitl/hitlBridge.js +10 -7
  137. package/dist/hitl/livePendingAsk.d.ts +3 -3
  138. package/dist/hitl/livePendingAsk.js +7 -18
  139. package/dist/hitl/parkResolver.d.ts +2 -24
  140. package/dist/hitl/parkResolver.js +61 -97
  141. package/dist/hitl/persistedRulesWire.d.ts +24 -0
  142. package/dist/hitl/persistedRulesWire.js +122 -2
  143. package/dist/hitl/planReviewWire.d.ts +26 -13
  144. package/dist/hitl/planReviewWire.js +112 -78
  145. package/dist/hitl/refusedToolNameProse.d.ts +0 -1
  146. package/dist/hitl/refusedToolNameProse.js +0 -3
  147. package/dist/hitl/replayedApproval.d.ts +4 -3
  148. package/dist/hitl/replayedApproval.js +7 -4
  149. package/dist/hitl/sessionPolicyDeliverable.js +2 -4
  150. package/dist/hitl/sessionPolicyWire.d.ts +32 -20
  151. package/dist/hitl/sessionPolicyWire.js +162 -52
  152. package/dist/hitl/standingRows.d.ts +20 -2
  153. package/dist/hitl/standingRows.js +69 -8
  154. package/dist/hitl/toolApprovalWire.d.ts +87 -152
  155. package/dist/hitl/toolApprovalWire.js +591 -380
  156. package/dist/hookMatcherVerdict.d.ts +6 -1
  157. package/dist/hookMatcherVerdict.js +14 -7
  158. package/dist/hooksWireCaps.d.ts +2 -2
  159. package/dist/hooksWireCaps.js +59 -55
  160. package/dist/i18n/messages.en.d.ts +121 -0
  161. package/dist/i18n/messages.en.js +119 -0
  162. package/dist/i18n/messages.zh.d.ts +3 -0
  163. package/dist/i18n/messages.zh.js +120 -0
  164. package/dist/i18n/translate.d.ts +25 -0
  165. package/dist/i18n/translate.js +127 -0
  166. package/dist/index.d.ts +53 -20
  167. package/dist/index.js +38 -11
  168. package/dist/inheritEnvCapability.d.ts +31 -0
  169. package/dist/inheritEnvCapability.js +104 -0
  170. package/dist/liveModelCatalog.d.ts +1 -2
  171. package/dist/liveModelCatalog.js +2 -6
  172. package/dist/liveQuestionStore.d.ts +2 -21
  173. package/dist/mcpLiveness.d.ts +2 -1
  174. package/dist/mcpProbeWire.d.ts +6 -1
  175. package/dist/mcpProbeWire.js +1 -1
  176. package/dist/mcpWireCaps.d.ts +13 -2
  177. package/dist/mcpWireCaps.js +48 -0
  178. package/dist/memoryEntriesWire.d.ts +4 -9
  179. package/dist/model/modelSupplyRules.d.ts +0 -2
  180. package/dist/model/modelSupplyRules.js +3 -12
  181. package/dist/model/modelsPolicy.d.ts +0 -5
  182. package/dist/model/modelsPolicy.js +6 -36
  183. package/dist/model/subagentModelWord.d.ts +31 -0
  184. package/dist/model/subagentModelWord.js +261 -0
  185. package/dist/notifications.d.ts +6 -0
  186. package/dist/notifications.js +71 -23
  187. package/dist/outputStyleSeatCapability.d.ts +0 -3
  188. package/dist/outputStyleSeatCapability.js +0 -3
  189. package/dist/ownKey.d.ts +15 -0
  190. package/dist/ownKey.js +60 -3
  191. package/dist/panelReduce.d.ts +15 -9
  192. package/dist/panelReduce.js +680 -549
  193. package/dist/panelStateHolder.d.ts +3 -7
  194. package/dist/panelStateHolder.js +14 -130
  195. package/dist/peerLaneCapability.d.ts +0 -4
  196. package/dist/peerLaneCapability.js +0 -6
  197. package/dist/permissionRulesWriteCapability.d.ts +0 -4
  198. package/dist/permissionRulesWriteCapability.js +0 -6
  199. package/dist/permissionWireCaps.d.ts +2 -2
  200. package/dist/permissionWireCaps.js +2 -0
  201. package/dist/permissionsAllowGrantCapability.d.ts +0 -4
  202. package/dist/permissionsAllowGrantCapability.js +0 -6
  203. package/dist/permissionsDeclaration.d.ts +0 -11
  204. package/dist/permissionsDeclaration.js +60 -53
  205. package/dist/pluginHooksWire.d.ts +1 -1
  206. package/dist/pluginHooksWire.js +3 -6
  207. package/dist/preemptWire.d.ts +44 -0
  208. package/dist/preemptWire.js +83 -0
  209. package/dist/printToolResultFrame.js +15 -4
  210. package/dist/replayBody.d.ts +3 -0
  211. package/dist/replayBody.js +14 -0
  212. package/dist/request/taskRequest.d.ts +0 -1
  213. package/dist/request/taskRequest.js +0 -3
  214. package/dist/resumeRefusalCopy.d.ts +2 -1
  215. package/dist/resumeRefusalCopy.js +38 -2
  216. package/dist/retryStatus.d.ts +8 -0
  217. package/dist/retryStatus.js +106 -1
  218. package/dist/rewindArchiveCapability.d.ts +0 -4
  219. package/dist/rewindArchiveCapability.js +2 -10
  220. package/dist/rewindArchiveReading.d.ts +0 -1
  221. package/dist/rewindArchiveReading.js +0 -3
  222. package/dist/runCancelContext.d.ts +2 -1
  223. package/dist/runCancelContext.js +4 -2
  224. package/dist/runReattachPolicy.d.ts +31 -0
  225. package/dist/runReattachPolicy.js +46 -0
  226. package/dist/runTerminal.d.ts +3 -6
  227. package/dist/runTerminal.js +8 -9
  228. package/dist/sandboxWire.d.ts +3 -1
  229. package/dist/sandboxWire.js +76 -27
  230. package/dist/scenarioWire.js +1 -1
  231. package/dist/seam.d.ts +24 -2
  232. package/dist/seam.js +15 -3
  233. package/dist/seatContract.d.ts +53 -10
  234. package/dist/seatContract.js +132 -81
  235. package/dist/sessionPolicyCapability.d.ts +0 -4
  236. package/dist/sessionPolicyCapability.js +0 -6
  237. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
  238. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  239. package/dist/skillToolListsCapability.d.ts +0 -3
  240. package/dist/skillToolListsCapability.js +0 -3
  241. package/dist/sqlEngineCapability.d.ts +0 -4
  242. package/dist/sqlEngineCapability.js +0 -6
  243. package/dist/steerPriorityCapability.d.ts +0 -3
  244. package/dist/steerPriorityCapability.js +0 -3
  245. package/dist/streamDrainingLegs.d.ts +4 -0
  246. package/dist/streamDrainingLegs.js +6 -1
  247. package/dist/subagent/engineCompactWire.d.ts +0 -1
  248. package/dist/subagent/engineCompactWire.js +7 -5
  249. package/dist/subagent/engineTaskHandleWire.js +4 -7
  250. package/dist/subagentContentStore.js +1 -11
  251. package/dist/submitReopen.d.ts +24 -0
  252. package/dist/submitReopen.js +75 -0
  253. package/dist/terminalStatuses.d.ts +3 -0
  254. package/dist/terminalStatuses.js +10 -2
  255. package/dist/toolResult.d.ts +10 -1
  256. package/dist/toolResult.js +34 -6
  257. package/dist/toolRoster.d.ts +0 -2
  258. package/dist/toolRoster.js +0 -2
  259. package/dist/turnFailurePresentation.d.ts +28 -0
  260. package/dist/turnFailurePresentation.js +205 -0
  261. package/dist/userInvokedSkillsCapability.d.ts +0 -3
  262. package/dist/userInvokedSkillsCapability.js +0 -3
  263. package/dist/webSearchBackendCapability.d.ts +0 -4
  264. package/dist/webSearchBackendCapability.js +0 -6
  265. package/dist/wireErrorTriage.js +5 -24
  266. package/dist/wireFailureShape.d.ts +62 -5
  267. package/dist/wireFailureShape.js +105 -5
  268. package/dist/wireRefusalCopy.d.ts +12 -2
  269. package/dist/wireRefusalCopy.js +50 -52
  270. package/dist/workflowsJournalCapability.d.ts +0 -4
  271. package/dist/workflowsJournalCapability.js +0 -6
  272. package/dist/writeProtectionCapability.d.ts +0 -4
  273. package/dist/writeProtectionCapability.js +0 -6
  274. package/docs/INTEGRATION-CLIENTS.md +1253 -46
  275. package/package.json +5 -4
  276. package/dist/attachmentSeatCapability.d.ts +0 -12
  277. package/dist/attachmentSeatCapability.js +0 -23
  278. package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
  279. package/dist/hitl/approvalOutcomeNote.js +0 -29
  280. package/dist/sessionReadRedactionCapability.d.ts +0 -13
  281. package/dist/sessionReadRedactionCapability.js +0 -35
@@ -0,0 +1,364 @@
1
+ import { ownDataField, ownSendableField } from './ownKey.js';
2
+ const isObjectLike = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
3
+ function optionalOwn(o, key) {
4
+ try {
5
+ return ownDataField(o, key);
6
+ }
7
+ catch {
8
+ return undefined;
9
+ }
10
+ }
11
+ function itemsOf(a) {
12
+ if (!Array.isArray(a))
13
+ return undefined;
14
+ const n = ownDataField(a, 'length');
15
+ if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0)
16
+ return undefined;
17
+ const out = [];
18
+ for (let i = 0; i < n; i += 1)
19
+ out.push(ownDataField(a, String(i)));
20
+ return out;
21
+ }
22
+ const JSON_MAX_DEPTH = 64;
23
+ const JSON_MAX_NODES = 200_000;
24
+ const NOT_JSON = Symbol('not-json');
25
+ function isPlainShape(o) {
26
+ const proto = Object.getPrototypeOf(o);
27
+ return proto === null || (typeof proto === 'object' && Object.getPrototypeOf(proto) === null);
28
+ }
29
+ function jsonSnapshot(v, depth, budget) {
30
+ budget.nodes += 1;
31
+ if (budget.nodes > JSON_MAX_NODES || depth > JSON_MAX_DEPTH)
32
+ return NOT_JSON;
33
+ if (v === null || typeof v === 'string' || typeof v === 'boolean')
34
+ return v;
35
+ if (typeof v === 'number')
36
+ return Number.isFinite(v) ? v : NOT_JSON;
37
+ if (typeof v !== 'object')
38
+ return NOT_JSON;
39
+ if (Array.isArray(v)) {
40
+ const n = ownDataField(v, 'length');
41
+ if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0)
42
+ return NOT_JSON;
43
+ const out = [];
44
+ for (let i = 0; i < n; i += 1) {
45
+ const item = jsonSnapshot(ownSendableField(v, String(i)), depth + 1, budget);
46
+ if (item === NOT_JSON)
47
+ return NOT_JSON;
48
+ out.push(item);
49
+ }
50
+ return out;
51
+ }
52
+ if (!isPlainShape(v))
53
+ return NOT_JSON;
54
+ const out = {};
55
+ for (const k of Reflect.ownKeys(v)) {
56
+ if (typeof k !== 'string')
57
+ continue;
58
+ const item = jsonSnapshot(ownSendableField(v, k), depth + 1, budget);
59
+ if (item === NOT_JSON)
60
+ return NOT_JSON;
61
+ Object.defineProperty(out, k, { value: item, enumerable: true, writable: true, configurable: true });
62
+ }
63
+ return out;
64
+ }
65
+ function jsonSnapshotOf(v) {
66
+ try {
67
+ const snap = jsonSnapshot(v, 0, { nodes: 0 });
68
+ return snap === NOT_JSON ? undefined : snap;
69
+ }
70
+ catch {
71
+ return undefined;
72
+ }
73
+ }
74
+ function mapBlock(b) {
75
+ if (!isObjectLike(b))
76
+ return undefined;
77
+ const type = ownDataField(b, 'type');
78
+ if (typeof type !== 'string')
79
+ return undefined;
80
+ switch (type) {
81
+ case 'text': {
82
+ const text = ownDataField(b, 'text');
83
+ return typeof text === 'string' ? { type: 'text', text } : undefined;
84
+ }
85
+ case 'thinking': {
86
+ const thinking = ownDataField(b, 'thinking');
87
+ if (typeof thinking !== 'string')
88
+ return undefined;
89
+ const signature = optionalOwn(b, 'thinkingSignature');
90
+ return typeof signature === 'string' ? { type: 'thinking', thinking, signature } : { type: 'thinking', thinking };
91
+ }
92
+ case 'toolCall': {
93
+ const id = ownDataField(b, 'id');
94
+ const name = ownDataField(b, 'name');
95
+ if (typeof id !== 'string' || id.length === 0 || typeof name !== 'string' || name.length === 0)
96
+ return undefined;
97
+ const args = ownDataField(b, 'arguments');
98
+ if (!isObjectLike(args))
99
+ return { type: 'tool_use', id, name, input: {} };
100
+ const input = jsonSnapshotOf(args);
101
+ if (input === undefined || input === null || typeof input !== 'object' || Array.isArray(input))
102
+ return undefined;
103
+ return { type: 'tool_use', id, name, input: input };
104
+ }
105
+ case 'image':
106
+ case 'document': {
107
+ const data = ownDataField(b, 'data');
108
+ const mimeType = ownDataField(b, 'mimeType');
109
+ if (typeof data !== 'string' || typeof mimeType !== 'string' || mimeType.length === 0)
110
+ return undefined;
111
+ return { type, source: { type: 'base64', media_type: mimeType, data } };
112
+ }
113
+ default: {
114
+ const opaque = jsonSnapshotOf(b);
115
+ return opaque !== undefined && opaque !== null && typeof opaque === 'object' && !Array.isArray(opaque) ? opaque : undefined;
116
+ }
117
+ }
118
+ }
119
+ function mapBlockCounted(raw, tally) {
120
+ let mapped;
121
+ try {
122
+ mapped = mapBlock(raw);
123
+ }
124
+ catch {
125
+ mapped = undefined;
126
+ }
127
+ if (mapped === undefined)
128
+ tally.droppedBlocks += 1;
129
+ return mapped;
130
+ }
131
+ function mapBlocks(items, tally) {
132
+ const out = [];
133
+ for (const raw of items) {
134
+ const mapped = mapBlockCounted(raw, tally);
135
+ if (mapped !== undefined)
136
+ out.push(mapped);
137
+ }
138
+ return out;
139
+ }
140
+ function engineRegionsOf(row, flatLength) {
141
+ if (optionalOwn(row, 'engineMinted') === true)
142
+ return 'whole';
143
+ const segments = optionalOwn(row, 'engineSegments');
144
+ if (segments !== undefined) {
145
+ let items;
146
+ try {
147
+ items = itemsOf(segments);
148
+ }
149
+ catch {
150
+ items = undefined;
151
+ }
152
+ if (items === undefined)
153
+ return 'verbatim';
154
+ const out = [];
155
+ let floor = 0;
156
+ for (const item of items) {
157
+ if (!isObjectLike(item))
158
+ return 'verbatim';
159
+ const start = optionalOwn(item, 'start');
160
+ const end = optionalOwn(item, 'end');
161
+ if (typeof start !== 'number' || typeof end !== 'number' || !Number.isInteger(start) || !Number.isInteger(end))
162
+ return 'verbatim';
163
+ if (start < floor || end <= start || end > flatLength)
164
+ return 'verbatim';
165
+ out.push([start, end]);
166
+ floor = end;
167
+ }
168
+ return out;
169
+ }
170
+ const prefix = optionalOwn(row, 'enginePrefixChars');
171
+ if (prefix === undefined)
172
+ return 'verbatim';
173
+ if (typeof prefix !== 'number' || !Number.isInteger(prefix) || prefix <= 0 || prefix > flatLength)
174
+ return 'verbatim';
175
+ return [[0, prefix]];
176
+ }
177
+ function cutRegions(text, offset, regions) {
178
+ const end = offset + text.length;
179
+ let out = '';
180
+ let cursor = offset;
181
+ let touched = false;
182
+ for (const [rs, re] of regions) {
183
+ if (re <= offset || rs >= end)
184
+ continue;
185
+ touched = true;
186
+ const cutStart = Math.max(rs, offset);
187
+ const cutEnd = Math.min(re, end);
188
+ out += text.slice(cursor - offset, cutStart - offset);
189
+ cursor = cutEnd;
190
+ }
191
+ if (!touched)
192
+ return text;
193
+ out += text.slice(cursor - offset);
194
+ const kept = out.trim();
195
+ return kept === '' ? undefined : kept;
196
+ }
197
+ const unreadable = () => ({ kind: 'skip', why: 'unreadable' });
198
+ const invisible = () => ({ kind: 'skip', why: 'noVisibleContent' });
199
+ function flatTextOf(item) {
200
+ if (!isObjectLike(item))
201
+ return '';
202
+ const type = optionalOwn(item, 'type');
203
+ if (type !== 'text')
204
+ return '';
205
+ const text = optionalOwn(item, 'text');
206
+ return text === undefined || text === null ? '' : String(text);
207
+ }
208
+ function userBody(row, tally) {
209
+ const content = ownDataField(row, 'content');
210
+ if (typeof content === 'string') {
211
+ if (content === '')
212
+ return invisible();
213
+ const regions = engineRegionsOf(row, content.length);
214
+ if (regions === 'whole')
215
+ return invisible();
216
+ if (regions === 'verbatim')
217
+ return { kind: 'message', role: 'user', body: { role: 'user', content } };
218
+ const kept = cutRegions(content, 0, regions);
219
+ return kept === undefined ? invisible() : { kind: 'message', role: 'user', body: { role: 'user', content: kept } };
220
+ }
221
+ const items = itemsOf(content);
222
+ if (items === undefined)
223
+ return unreadable();
224
+ if (items.length === 0)
225
+ return invisible();
226
+ const texts = items.map(flatTextOf);
227
+ const flatLength = texts.reduce((n, t) => n + t.length, 0) + (items.length - 1);
228
+ const regions = engineRegionsOf(row, flatLength);
229
+ if (regions === 'whole')
230
+ return invisible();
231
+ const out = [];
232
+ let offset = 0;
233
+ for (let i = 0; i < items.length; i += 1) {
234
+ const text = texts[i];
235
+ const at = offset;
236
+ offset += text.length + 1;
237
+ const mapped = mapBlockCounted(items[i], tally);
238
+ if (mapped === undefined)
239
+ continue;
240
+ if (mapped.type === 'text' && regions !== 'verbatim') {
241
+ const kept = cutRegions(text, at, regions);
242
+ if (kept === undefined)
243
+ continue;
244
+ out.push(kept === text ? mapped : { type: 'text', text: kept });
245
+ continue;
246
+ }
247
+ out.push(mapped);
248
+ }
249
+ return out.length === 0 ? invisible() : { kind: 'message', role: 'user', body: { role: 'user', content: out } };
250
+ }
251
+ function assistantBody(row, tally) {
252
+ const content = ownDataField(row, 'content');
253
+ let blocks;
254
+ if (typeof content === 'string') {
255
+ blocks = [{ type: 'text', text: content }];
256
+ }
257
+ else {
258
+ const items = itemsOf(content);
259
+ if (items === undefined)
260
+ return unreadable();
261
+ blocks = mapBlocks(items, tally);
262
+ }
263
+ const model = optionalOwn(row, 'model');
264
+ return {
265
+ kind: 'message',
266
+ role: 'assistant',
267
+ body: typeof model === 'string' && model.length > 0 ? { role: 'assistant', content: blocks, model } : { role: 'assistant', content: blocks },
268
+ };
269
+ }
270
+ function toolResultBody(row, tally) {
271
+ const id = ownDataField(row, 'toolCallId');
272
+ if (typeof id !== 'string' || id.length === 0)
273
+ return unreadable();
274
+ const content = ownDataField(row, 'content');
275
+ let blocks;
276
+ if (content === undefined) {
277
+ blocks = [];
278
+ }
279
+ else if (typeof content === 'string') {
280
+ blocks = [{ type: 'text', text: content }];
281
+ }
282
+ else {
283
+ const items = itemsOf(content);
284
+ if (items === undefined)
285
+ return unreadable();
286
+ blocks = mapBlocks(items, tally);
287
+ }
288
+ const isError = ownDataField(row, 'isError') === true;
289
+ return { kind: 'message', role: 'user', body: { role: 'user', content: [{ type: 'tool_result', tool_use_id: id, content: blocks, is_error: isError }] } };
290
+ }
291
+ function projectRow(row, tally) {
292
+ if (!isObjectLike(row))
293
+ return unreadable();
294
+ const role = ownDataField(row, 'role');
295
+ if (role === 'user')
296
+ return userBody(row, tally);
297
+ if (role === 'assistant')
298
+ return assistantBody(row, tally);
299
+ if (role === 'toolResult')
300
+ return toolResultBody(row, tally);
301
+ return { kind: 'skip', why: 'unknownRole' };
302
+ }
303
+ function timestampOf(row) {
304
+ const ms = optionalOwn(row, 'timestamp');
305
+ if (typeof ms !== 'number' || !Number.isFinite(ms))
306
+ return undefined;
307
+ const at = new Date(ms);
308
+ return Number.isNaN(at.getTime()) ? undefined : at.toISOString();
309
+ }
310
+ function sessionIdOf(opts) {
311
+ let sessionId;
312
+ try {
313
+ sessionId = typeof opts === 'object' && opts !== null ? ownDataField(opts, 'sessionId') : undefined;
314
+ }
315
+ catch {
316
+ sessionId = undefined;
317
+ }
318
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
319
+ throw new TypeError('projectEngineSessionMessages: opts.sessionId must be a non-empty string (the engine session id)');
320
+ }
321
+ return sessionId;
322
+ }
323
+ export function projectEngineSessionMessages(rows, opts) {
324
+ if (!Array.isArray(rows))
325
+ throw new TypeError('projectEngineSessionMessages: rows must be an array');
326
+ const sessionId = sessionIdOf(opts);
327
+ let count;
328
+ try {
329
+ count = ownDataField(rows, 'length');
330
+ }
331
+ catch {
332
+ count = undefined;
333
+ }
334
+ if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0)
335
+ throw new TypeError('projectEngineSessionMessages: rows length could not be read');
336
+ const tally = { unreadable: 0, unknownRole: 0, noVisibleContent: 0, droppedBlocks: 0 };
337
+ const messages = [];
338
+ for (let i = 0; i < count; i += 1) {
339
+ let outcome;
340
+ let timestamp;
341
+ try {
342
+ const row = ownDataField(rows, String(i));
343
+ outcome = projectRow(row, tally);
344
+ timestamp = outcome.kind === 'message' && isObjectLike(row) ? timestampOf(row) : undefined;
345
+ }
346
+ catch {
347
+ outcome = unreadable();
348
+ timestamp = undefined;
349
+ }
350
+ if (outcome.kind === 'skip') {
351
+ tally[outcome.why] += 1;
352
+ continue;
353
+ }
354
+ messages.push({
355
+ type: outcome.role,
356
+ uuid: `restored-${sessionId}-${messages.length + 1}`,
357
+ session_id: sessionId,
358
+ ...(timestamp !== undefined ? { timestamp } : {}),
359
+ message: outcome.body,
360
+ parent_tool_use_id: null,
361
+ });
362
+ }
363
+ return Object.freeze({ messages, skipped: Object.freeze({ ...tally }) });
364
+ }
@@ -15,13 +15,4 @@ export type EngineToolDirectory = {
15
15
  readonly mcpServerPrefixes: ReadonlySet<string>;
16
16
  };
17
17
  export declare function engineToolDirectoryOf(source: EngineToolDirectorySource | null | undefined): EngineToolDirectory;
18
- export type McpEntryReading = 'outside' | 'unchecked' | 'unparsable' | 'answers' | 'unanswered';
19
- export declare function mcpEntryReadingOf(toolName: string, directory: EngineToolDirectory | undefined): McpEntryReading;
20
18
  export declare function deniedEntryToolName(entry: string): string | undefined;
21
- export interface ExcludeToolsAgainstDirectory {
22
- readonly send: string[];
23
- readonly omitted: string[];
24
- readonly verdict: 'directory_absent' | 'filtered';
25
- readonly disclosure?: string;
26
- }
27
- export declare function excludeToolsAgainstDirectory(exclude: readonly string[], directory: EngineToolDirectory | undefined): ExcludeToolsAgainstDirectory;
@@ -1,7 +1,6 @@
1
1
  import { frozenSet } from './frozenSet.js';
2
2
  import { ownDataField } from './ownKey.js';
3
- import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix, protocolOf } from './coreValuePorts.js';
4
- import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
3
+ import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix } from './coreValuePorts.js';
5
4
  const notLanded = () => Object.freeze({ state: 'not_landed' });
6
5
  const unreadable = () => Object.freeze({ state: 'unreadable' });
7
6
  function readHalf(half) {
@@ -54,77 +53,11 @@ export function engineToolDirectoryOf(source) {
54
53
  return unreadable();
55
54
  }
56
55
  }
57
- export function mcpEntryReadingOf(toolName, directory) {
58
- let ns;
59
- try {
60
- const mcp = namingPorts();
61
- if (mcp === undefined)
62
- return CORE_PROTOCOL_PREFIXES.some((p) => toolName.startsWith(p)) ? 'unchecked' : 'outside';
63
- ns = protocolOf(toolName);
64
- if (ns === undefined || ns.id !== mcp.id)
65
- return 'outside';
66
- }
67
- catch {
68
- return CORE_PROTOCOL_PREFIXES.some((p) => toolName.startsWith(p)) ? 'unchecked' : 'outside';
69
- }
70
- const prefixes = prefixesInHand(directory);
71
- if (prefixes === undefined)
72
- return 'unchecked';
73
- let prefix;
74
- try {
75
- const peer = peerSegmentOf(ns, toolName);
76
- if (peer === undefined || peer.includes('*'))
77
- return 'unparsable';
78
- prefix = mintNamespacePrefix(ns, peer);
79
- }
80
- catch {
81
- return 'unparsable';
82
- }
83
- if (typeof prefix !== 'string' || prefix.length === 0)
84
- return 'unchecked';
85
- try {
86
- return prefixes.has(prefix) ? 'answers' : 'unanswered';
87
- }
88
- catch {
89
- return 'unchecked';
90
- }
91
- }
92
- function prefixesInHand(directory) {
93
- try {
94
- if (directory === undefined || directory === null || typeof directory !== 'object' || directory.state !== 'directory')
95
- return undefined;
96
- const prefixes = directory.mcpServerPrefixes;
97
- if (prefixes === null || typeof prefixes !== 'object' || typeof prefixes.has !== 'function')
98
- return undefined;
99
- return prefixes;
100
- }
101
- catch {
102
- return undefined;
103
- }
104
- }
105
56
  function namingPorts() {
106
57
  if (!hasCoreValuePort('protocolOf') || !hasCoreValuePort('mintNamespacePrefix'))
107
58
  return undefined;
108
59
  return mcpNamespace();
109
60
  }
110
- function peerSegmentOf(ns, toolName) {
111
- const read = (n) => {
112
- const parsed = ns.parse(n);
113
- if (parsed === null || typeof parsed !== 'object')
114
- return undefined;
115
- const peer = ownDataField(parsed, 'peer');
116
- return typeof peer === 'string' && peer.length > 0 ? peer : undefined;
117
- };
118
- const direct = read(toolName);
119
- if (direct !== undefined)
120
- return direct;
121
- if (!toolName.startsWith(ns.prefix))
122
- return undefined;
123
- const rest = toolName.slice(ns.prefix.length);
124
- if (rest.length === 0)
125
- return undefined;
126
- return read(ns.makeName(rest, 'x')) === rest ? rest : undefined;
127
- }
128
61
  function unescapedIndexOf(s, ch, last) {
129
62
  for (let k = 0; k < s.length; k++) {
130
63
  const i = last ? s.length - 1 - k : k;
@@ -150,29 +83,3 @@ export function deniedEntryToolName(entry) {
150
83
  const name = entry.substring(0, open);
151
84
  return name.length === 0 ? entry : name.trim();
152
85
  }
153
- export function excludeToolsAgainstDirectory(exclude, directory) {
154
- if (!Array.isArray(exclude))
155
- throw new TypeError('excludeToolsAgainstDirectory: exclude must be an array of tool names');
156
- const verdict = prefixesInHand(directory) !== undefined ? 'filtered' : 'directory_absent';
157
- const send = [];
158
- const omitted = [];
159
- for (const entry of exclude) {
160
- if (verdict === 'filtered' && typeof entry === 'string') {
161
- const name = deniedEntryToolName(entry);
162
- if (name !== undefined && mcpEntryReadingOf(name, directory) === 'unanswered') {
163
- omitted.push(entry);
164
- continue;
165
- }
166
- }
167
- send.push(entry);
168
- }
169
- if (omitted.length === 0)
170
- return { send, omitted, verdict };
171
- const one = omitted.length === 1;
172
- return {
173
- send,
174
- omitted,
175
- verdict,
176
- disclosure: `excludeTools: ${omitted.map((e) => JSON.stringify(e)).join(', ')} ${one ? 'names' : 'name'} no tool this deployment answers to (no MCP server of that name is declared for this session) — omitted. Excluding a tool that cannot be mounted changes nothing; the engine refuses a request that names one.`,
177
- };
178
- }
@@ -0,0 +1,18 @@
1
+ export type EngineBaseUrlRefusalReason = 'empty' | 'scheme' | 'unparseable' | 'userinfo' | 'query_or_fragment';
2
+ export type EngineBaseUrlReading = {
3
+ readonly ok: true;
4
+ readonly url: string;
5
+ } | {
6
+ readonly ok: false;
7
+ readonly reason: EngineBaseUrlRefusalReason;
8
+ };
9
+ export type EngineUrlTransportRefusalReason = 'plaintext_remote' | 'not_http_url';
10
+ export type EngineUrlTransportVerdict = {
11
+ readonly ok: true;
12
+ readonly loopback: boolean;
13
+ } | {
14
+ readonly ok: false;
15
+ readonly reason: EngineUrlTransportRefusalReason;
16
+ };
17
+ export declare function normalizeEngineBaseUrl(raw: string | null | undefined): EngineBaseUrlReading;
18
+ export declare function engineUrlTransportVerdict(url: string): EngineUrlTransportVerdict;
@@ -0,0 +1,52 @@
1
+ import { isLoopbackWireUrl } from './engineWireSdk.js';
2
+ const SLASH = 47;
3
+ function refusedBase(reason) {
4
+ return Object.freeze({ ok: false, reason });
5
+ }
6
+ function refusedTransport(reason) {
7
+ return Object.freeze({ ok: false, reason });
8
+ }
9
+ function withoutTrailingSlashes(s) {
10
+ let end = s.length;
11
+ while (end > 0 && s.charCodeAt(end - 1) === SLASH)
12
+ end--;
13
+ return s.slice(0, end);
14
+ }
15
+ export function normalizeEngineBaseUrl(raw) {
16
+ if (typeof raw !== 'string')
17
+ return refusedBase('empty');
18
+ const trimmed = raw.trim();
19
+ if (trimmed.length === 0)
20
+ return refusedBase('empty');
21
+ if (!/^https?:\/\//i.test(trimmed))
22
+ return refusedBase('scheme');
23
+ let parsed;
24
+ try {
25
+ parsed = new URL(trimmed);
26
+ }
27
+ catch {
28
+ return refusedBase('unparseable');
29
+ }
30
+ if (parsed.username !== '' || parsed.password !== '')
31
+ return refusedBase('userinfo');
32
+ if (trimmed.includes('?') || trimmed.includes('#'))
33
+ return refusedBase('query_or_fragment');
34
+ return Object.freeze({ ok: true, url: withoutTrailingSlashes(trimmed) });
35
+ }
36
+ export function engineUrlTransportVerdict(url) {
37
+ if (typeof url !== 'string')
38
+ return refusedTransport('not_http_url');
39
+ let parsed;
40
+ try {
41
+ parsed = new URL(url);
42
+ }
43
+ catch {
44
+ return refusedTransport('not_http_url');
45
+ }
46
+ const loopback = isLoopbackWireUrl(url);
47
+ if (parsed.protocol === 'https:')
48
+ return Object.freeze({ ok: true, loopback });
49
+ if (parsed.protocol === 'http:')
50
+ return loopback ? Object.freeze({ ok: true, loopback: true }) : refusedTransport('plaintext_remote');
51
+ return refusedTransport('not_http_url');
52
+ }
@@ -3,3 +3,12 @@ export declare const UI_LANGUAGES: readonly UiLanguage[];
3
3
  export declare const UI_LANGUAGE_ENDONYMS: Record<UiLanguage, string>;
4
4
  export declare function isUiLanguage(v: unknown): v is UiLanguage;
5
5
  export declare function pickUiLanguage(localeTag: string | undefined): UiLanguage;
6
+ export type UiLanguageSource = 'saved' | 'host' | 'default';
7
+ export interface UiLanguageResolution {
8
+ readonly language: UiLanguage;
9
+ readonly source: UiLanguageSource;
10
+ }
11
+ export declare function resolveUiLanguageFrom(input: {
12
+ readonly saved?: string | null | undefined;
13
+ readonly hostTags?: readonly (string | null | undefined)[] | null | undefined;
14
+ } | null | undefined): UiLanguageResolution;
@@ -10,3 +10,38 @@ export function isUiLanguage(v) {
10
10
  export function pickUiLanguage(localeTag) {
11
11
  return parseLocaleTag(localeTag).language === 'zh' ? 'zh' : 'en';
12
12
  }
13
+ const HOST_TAGS_READ_LIMIT = 64;
14
+ function ownDataOf(v, key) {
15
+ if (v === null || typeof v !== 'object')
16
+ return undefined;
17
+ try {
18
+ const d = Object.getOwnPropertyDescriptor(v, key);
19
+ return d !== undefined && 'value' in d ? d.value : undefined;
20
+ }
21
+ catch {
22
+ return undefined;
23
+ }
24
+ }
25
+ export function resolveUiLanguageFrom(input) {
26
+ const saved = ownDataOf(input, 'saved');
27
+ if (isUiLanguage(saved))
28
+ return Object.freeze({ language: saved, source: 'saved' });
29
+ const tags = ownDataOf(input, 'hostTags');
30
+ let isList = false;
31
+ try {
32
+ isList = Array.isArray(tags);
33
+ }
34
+ catch {
35
+ isList = false;
36
+ }
37
+ if (isList) {
38
+ const n = ownDataOf(tags, 'length');
39
+ const limit = typeof n === 'number' && Number.isSafeInteger(n) && n > 0 ? Math.min(n, HOST_TAGS_READ_LIMIT) : 0;
40
+ for (let i = 0; i < limit; i += 1) {
41
+ const tag = ownDataOf(tags, String(i));
42
+ if (typeof tag === 'string' && tag.length > 0)
43
+ return Object.freeze({ language: pickUiLanguage(tag), source: 'host' });
44
+ }
45
+ }
46
+ return Object.freeze({ language: 'en', source: 'default' });
47
+ }