@segmentstream/ontology 0.0.0-stage → 0.92.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +1655 -2
  4. package/dist/action.d.ts +193 -0
  5. package/dist/action.js +41 -0
  6. package/dist/agent-chat.d.ts +44 -0
  7. package/dist/agent-chat.js +91 -0
  8. package/dist/agent-task-contract.d.ts +64 -0
  9. package/dist/agent-task-contract.js +15 -0
  10. package/dist/agent-task.d.ts +39 -0
  11. package/dist/agent-task.js +112 -0
  12. package/dist/analyze.d.ts +215 -0
  13. package/dist/analyze.js +2438 -0
  14. package/dist/app-feedback.d.ts +167 -0
  15. package/dist/app-feedback.js +176 -0
  16. package/dist/authoring-input.d.ts +3 -0
  17. package/dist/authoring-input.js +107 -0
  18. package/dist/authoring-names.d.ts +4 -0
  19. package/dist/authoring-names.js +13 -0
  20. package/dist/authoring-records.d.ts +35 -0
  21. package/dist/authoring-records.js +264 -0
  22. package/dist/authoring.d.ts +15 -0
  23. package/dist/authoring.js +331 -0
  24. package/dist/bin/check.d.ts +30 -0
  25. package/dist/bin/check.js +99 -0
  26. package/dist/bin/load.d.ts +48 -0
  27. package/dist/bin/load.js +139 -0
  28. package/dist/bin/main.d.ts +31 -0
  29. package/dist/bin/main.js +121 -0
  30. package/dist/bin/migrate.d.ts +57 -0
  31. package/dist/bin/migrate.js +170 -0
  32. package/dist/bin/output.d.ts +31 -0
  33. package/dist/bin/output.js +84 -0
  34. package/dist/bin.d.ts +2 -0
  35. package/dist/bin.js +31 -0
  36. package/dist/blob.d.ts +52 -0
  37. package/dist/blob.js +87 -0
  38. package/dist/channel-session.d.ts +16 -0
  39. package/dist/channel-session.js +16 -0
  40. package/dist/chat.d.ts +43 -0
  41. package/dist/chat.js +34 -0
  42. package/dist/confirmation.d.ts +46 -0
  43. package/dist/confirmation.js +41 -0
  44. package/dist/connection.d.ts +213 -0
  45. package/dist/connection.js +289 -0
  46. package/dist/deployment.d.ts +35 -0
  47. package/dist/deployment.js +76 -0
  48. package/dist/diagnostics.d.ts +27 -0
  49. package/dist/diagnostics.js +106 -0
  50. package/dist/emails.d.ts +70 -0
  51. package/dist/emails.js +221 -0
  52. package/dist/entity.d.ts +331 -0
  53. package/dist/entity.js +153 -0
  54. package/dist/errors.d.ts +154 -0
  55. package/dist/errors.js +109 -0
  56. package/dist/feedback-config.d.ts +24 -0
  57. package/dist/feedback-config.js +126 -0
  58. package/dist/files.d.ts +39 -0
  59. package/dist/files.js +4 -0
  60. package/dist/groups.d.ts +95 -0
  61. package/dist/groups.js +280 -0
  62. package/dist/index.d.ts +109 -0
  63. package/dist/index.js +70 -0
  64. package/dist/internal/diagnostics.js +594 -0
  65. package/dist/legacy.d.ts +160 -0
  66. package/dist/legacy.js +270 -0
  67. package/dist/manifest-compatibility.d.ts +8 -0
  68. package/dist/manifest-compatibility.js +87 -0
  69. package/dist/manifest.d.ts +3329 -0
  70. package/dist/manifest.js +757 -0
  71. package/dist/me.d.ts +46 -0
  72. package/dist/me.js +109 -0
  73. package/dist/metric-filters.d.ts +48 -0
  74. package/dist/metric-filters.js +252 -0
  75. package/dist/metric-routes.d.ts +132 -0
  76. package/dist/metric-routes.js +498 -0
  77. package/dist/metric.d.ts +172 -0
  78. package/dist/metric.js +132 -0
  79. package/dist/migrate/apply.d.ts +94 -0
  80. package/dist/migrate/apply.js +526 -0
  81. package/dist/migrate/errors.d.ts +46 -0
  82. package/dist/migrate/errors.js +38 -0
  83. package/dist/migrate/index.d.ts +10 -0
  84. package/dist/migrate/index.js +7 -0
  85. package/dist/migrate/model.d.ts +2311 -0
  86. package/dist/migrate/model.js +148 -0
  87. package/dist/migrate/plan.d.ts +51 -0
  88. package/dist/migrate/plan.js +1856 -0
  89. package/dist/migrate/preview.d.ts +13 -0
  90. package/dist/migrate/preview.js +65 -0
  91. package/dist/migrate/storage.d.ts +226 -0
  92. package/dist/migrate/storage.js +774 -0
  93. package/dist/model-metrics.d.ts +22 -0
  94. package/dist/model-metrics.js +545 -0
  95. package/dist/names.d.ts +49 -0
  96. package/dist/names.js +110 -0
  97. package/dist/navigation-artifact.d.ts +13 -0
  98. package/dist/navigation-artifact.js +11 -0
  99. package/dist/navigation-catalog.d.ts +55 -0
  100. package/dist/navigation-catalog.js +297 -0
  101. package/dist/nitro-navigation.d.ts +3 -0
  102. package/dist/nitro-navigation.js +64 -0
  103. package/dist/nitro-workflows.d.ts +108 -0
  104. package/dist/nitro-workflows.js +286 -0
  105. package/dist/nitro.d.ts +40 -0
  106. package/dist/nitro.js +50 -0
  107. package/dist/ontology.d.ts +41 -0
  108. package/dist/ontology.js +46 -0
  109. package/dist/permissions.d.ts +198 -0
  110. package/dist/permissions.js +272 -0
  111. package/dist/property.d.ts +188 -0
  112. package/dist/property.js +301 -0
  113. package/dist/query.d.ts +245 -0
  114. package/dist/query.js +615 -0
  115. package/dist/relationship.d.ts +99 -0
  116. package/dist/relationship.js +33 -0
  117. package/dist/render.d.ts +81 -0
  118. package/dist/render.js +512 -0
  119. package/dist/replication/baseline.d.ts +51 -0
  120. package/dist/replication/baseline.js +215 -0
  121. package/dist/replication/bigquery.d.ts +37 -0
  122. package/dist/replication/bigquery.js +211 -0
  123. package/dist/replication/coverage.d.ts +14 -0
  124. package/dist/replication/coverage.js +53 -0
  125. package/dist/replication/evolution.d.ts +25 -0
  126. package/dist/replication/evolution.js +184 -0
  127. package/dist/replication/identities.d.ts +6 -0
  128. package/dist/replication/identities.js +47 -0
  129. package/dist/replication/legacy-baseline.d.ts +27 -0
  130. package/dist/replication/legacy-baseline.js +109 -0
  131. package/dist/replication/legacy-store.d.ts +19 -0
  132. package/dist/replication/legacy-store.js +63 -0
  133. package/dist/replication/lineage.d.ts +36 -0
  134. package/dist/replication/lineage.js +72 -0
  135. package/dist/replication/migrate.d.ts +21 -0
  136. package/dist/replication/migrate.js +84 -0
  137. package/dist/replication/model.d.ts +52 -0
  138. package/dist/replication/model.js +99 -0
  139. package/dist/replication/scans.d.ts +34 -0
  140. package/dist/replication/scans.js +158 -0
  141. package/dist/replication/schema.d.ts +11 -0
  142. package/dist/replication/schema.js +226 -0
  143. package/dist/replication/shadow-schema.d.ts +4 -0
  144. package/dist/replication/shadow-schema.js +61 -0
  145. package/dist/replication/shadow.d.ts +127 -0
  146. package/dist/replication/shadow.js +614 -0
  147. package/dist/replication/source-replacement.d.ts +33 -0
  148. package/dist/replication/source-replacement.js +76 -0
  149. package/dist/replication/store.d.ts +36 -0
  150. package/dist/replication/store.js +382 -0
  151. package/dist/replication/transaction.d.ts +23 -0
  152. package/dist/replication/transaction.js +88 -0
  153. package/dist/role.d.ts +61 -0
  154. package/dist/role.js +76 -0
  155. package/dist/runtime/action-deadlocks.d.ts +21 -0
  156. package/dist/runtime/action-deadlocks.js +130 -0
  157. package/dist/runtime/action-transactions.d.ts +35 -0
  158. package/dist/runtime/action-transactions.js +54 -0
  159. package/dist/runtime/agent-counters.d.ts +26 -0
  160. package/dist/runtime/agent-counters.js +98 -0
  161. package/dist/runtime/agent-tasks.d.ts +63 -0
  162. package/dist/runtime/agent-tasks.js +120 -0
  163. package/dist/runtime/agents.d.ts +15 -0
  164. package/dist/runtime/agents.js +457 -0
  165. package/dist/runtime/batch-diagnostics.d.ts +22 -0
  166. package/dist/runtime/batch-diagnostics.js +89 -0
  167. package/dist/runtime/batch.d.ts +52 -0
  168. package/dist/runtime/batch.js +534 -0
  169. package/dist/runtime/channel-session-revocation.d.ts +3 -0
  170. package/dist/runtime/channel-session-revocation.js +5 -0
  171. package/dist/runtime/channel-sessions.d.ts +4 -0
  172. package/dist/runtime/channel-sessions.js +61 -0
  173. package/dist/runtime/confirmations.d.ts +29 -0
  174. package/dist/runtime/confirmations.js +57 -0
  175. package/dist/runtime/cursor.d.ts +23 -0
  176. package/dist/runtime/cursor.js +100 -0
  177. package/dist/runtime/deployment.d.ts +7 -0
  178. package/dist/runtime/deployment.js +4 -0
  179. package/dist/runtime/errors.d.ts +118 -0
  180. package/dist/runtime/errors.js +109 -0
  181. package/dist/runtime/federation-tables.d.ts +2 -0
  182. package/dist/runtime/federation-tables.js +20 -0
  183. package/dist/runtime/federation.d.ts +42 -0
  184. package/dist/runtime/federation.js +222 -0
  185. package/dist/runtime/files.d.ts +39 -0
  186. package/dist/runtime/files.js +44 -0
  187. package/dist/runtime/generated-actions.d.ts +37 -0
  188. package/dist/runtime/generated-actions.js +307 -0
  189. package/dist/runtime/history.d.ts +91 -0
  190. package/dist/runtime/history.js +77 -0
  191. package/dist/runtime/ids.d.ts +6 -0
  192. package/dist/runtime/ids.js +39 -0
  193. package/dist/runtime/member-tables.d.ts +8 -0
  194. package/dist/runtime/member-tables.js +33 -0
  195. package/dist/runtime/member-writes.d.ts +78 -0
  196. package/dist/runtime/member-writes.js +202 -0
  197. package/dist/runtime/metric-query.d.ts +19 -0
  198. package/dist/runtime/metric-query.js +411 -0
  199. package/dist/runtime/model.d.ts +67 -0
  200. package/dist/runtime/model.js +150 -0
  201. package/dist/runtime/new-user-hook.d.ts +6 -0
  202. package/dist/runtime/new-user-hook.js +37 -0
  203. package/dist/runtime/oauth.d.ts +9 -0
  204. package/dist/runtime/oauth.js +299 -0
  205. package/dist/runtime/pipeline.d.ts +155 -0
  206. package/dist/runtime/pipeline.js +597 -0
  207. package/dist/runtime/postgres-tls.d.ts +10 -0
  208. package/dist/runtime/postgres-tls.js +14 -0
  209. package/dist/runtime/principals.d.ts +302 -0
  210. package/dist/runtime/principals.js +1307 -0
  211. package/dist/runtime/reads.d.ts +55 -0
  212. package/dist/runtime/reads.js +313 -0
  213. package/dist/runtime/records.d.ts +42 -0
  214. package/dist/runtime/records.js +245 -0
  215. package/dist/runtime/resolve-agent-identity.d.ts +6 -0
  216. package/dist/runtime/resolve-agent-identity.js +181 -0
  217. package/dist/runtime/service-binding.d.ts +18 -0
  218. package/dist/runtime/service-binding.js +266 -0
  219. package/dist/runtime/sign-in-links.d.ts +68 -0
  220. package/dist/runtime/sign-in-links.js +147 -0
  221. package/dist/runtime/sql-runtime.d.ts +131 -0
  222. package/dist/runtime/sql-runtime.js +362 -0
  223. package/dist/runtime/statement.d.ts +18 -0
  224. package/dist/runtime/statement.js +31 -0
  225. package/dist/runtime/user-identities.d.ts +66 -0
  226. package/dist/runtime/user-identities.js +106 -0
  227. package/dist/runtime/user-identity-sql.d.ts +86 -0
  228. package/dist/runtime/user-identity-sql.js +297 -0
  229. package/dist/runtime/user-roles.d.ts +16 -0
  230. package/dist/runtime/user-roles.js +32 -0
  231. package/dist/runtime/validation.d.ts +16 -0
  232. package/dist/runtime/validation.js +26 -0
  233. package/dist/runtime/where.d.ts +57 -0
  234. package/dist/runtime/where.js +404 -0
  235. package/dist/runtime/workflow-admission.d.ts +49 -0
  236. package/dist/runtime/workflow-admission.js +92 -0
  237. package/dist/runtime/workflow-argument-codec.d.ts +10 -0
  238. package/dist/runtime/workflow-argument-codec.js +120 -0
  239. package/dist/runtime/workflow-arguments.d.ts +17 -0
  240. package/dist/runtime/workflow-arguments.js +99 -0
  241. package/dist/runtime/workflow-starts.d.ts +203 -0
  242. package/dist/runtime/workflow-starts.js +493 -0
  243. package/dist/runtime/workflow-users.d.ts +9 -0
  244. package/dist/runtime/workflow-users.js +17 -0
  245. package/dist/runtime/workload.d.ts +25 -0
  246. package/dist/runtime/workload.js +24 -0
  247. package/dist/runtime/writes.d.ts +108 -0
  248. package/dist/runtime/writes.js +491 -0
  249. package/dist/runtime-source.d.ts +22 -0
  250. package/dist/runtime-source.js +28 -0
  251. package/dist/runtime.d.ts +310 -0
  252. package/dist/runtime.js +31 -0
  253. package/dist/server.d.ts +23 -0
  254. package/dist/server.js +107 -0
  255. package/dist/service/agent/attachments.d.ts +33 -0
  256. package/dist/service/agent/attachments.js +228 -0
  257. package/dist/service/agent/authentication.d.ts +22 -0
  258. package/dist/service/agent/authentication.js +58 -0
  259. package/dist/service/agent/confirmations.d.ts +5 -0
  260. package/dist/service/agent/confirmations.js +73 -0
  261. package/dist/service/agent/conversation-routes.d.ts +14 -0
  262. package/dist/service/agent/conversation-routes.js +45 -0
  263. package/dist/service/agent/conversations.d.ts +40 -0
  264. package/dist/service/agent/conversations.js +69 -0
  265. package/dist/service/agent/files.d.ts +12 -0
  266. package/dist/service/agent/files.js +69 -0
  267. package/dist/service/agent/protocol.d.ts +90 -0
  268. package/dist/service/agent/protocol.js +114 -0
  269. package/dist/service/agent/server.d.ts +28 -0
  270. package/dist/service/agent/server.js +374 -0
  271. package/dist/service/agent/task-caller.d.ts +21 -0
  272. package/dist/service/agent/task-caller.js +35 -0
  273. package/dist/service/agent/task-start.d.ts +53 -0
  274. package/dist/service/agent/task-start.js +161 -0
  275. package/dist/service/agent/tasks.d.ts +40 -0
  276. package/dist/service/agent/tasks.js +155 -0
  277. package/dist/service/api.d.ts +50 -0
  278. package/dist/service/api.js +288 -0
  279. package/dist/service/authentication.d.ts +227 -0
  280. package/dist/service/authentication.js +767 -0
  281. package/dist/service/caller-context.d.ts +24 -0
  282. package/dist/service/caller-context.js +6 -0
  283. package/dist/service/catalog.d.ts +42 -0
  284. package/dist/service/catalog.js +66 -0
  285. package/dist/service/channel/provider.d.ts +10 -0
  286. package/dist/service/channel/provider.js +1 -0
  287. package/dist/service/channel/providers/telegram.d.ts +18 -0
  288. package/dist/service/channel/providers/telegram.js +108 -0
  289. package/dist/service/channel/sessions.d.ts +5 -0
  290. package/dist/service/channel/sessions.js +53 -0
  291. package/dist/service/channel/sign-in.d.ts +7 -0
  292. package/dist/service/channel/sign-in.js +78 -0
  293. package/dist/service/chat/archive.d.ts +64 -0
  294. package/dist/service/chat/archive.js +62 -0
  295. package/dist/service/chat/attribution.d.ts +26 -0
  296. package/dist/service/chat/attribution.js +28 -0
  297. package/dist/service/chat/delivery.d.ts +18 -0
  298. package/dist/service/chat/delivery.js +251 -0
  299. package/dist/service/chat/diagnostics.d.ts +2 -0
  300. package/dist/service/chat/diagnostics.js +35 -0
  301. package/dist/service/chat/envelope.d.ts +96 -0
  302. package/dist/service/chat/envelope.js +39 -0
  303. package/dist/service/chat/idempotency.d.ts +19 -0
  304. package/dist/service/chat/idempotency.js +37 -0
  305. package/dist/service/chat/providers/telegram.d.ts +36 -0
  306. package/dist/service/chat/providers/telegram.js +133 -0
  307. package/dist/service/chat/reads.d.ts +25 -0
  308. package/dist/service/chat/reads.js +75 -0
  309. package/dist/service/chat/resolve.d.ts +34 -0
  310. package/dist/service/chat/resolve.js +150 -0
  311. package/dist/service/chat/routes.d.ts +23 -0
  312. package/dist/service/chat/routes.js +75 -0
  313. package/dist/service/chat/schemas.d.ts +43 -0
  314. package/dist/service/chat/schemas.js +31 -0
  315. package/dist/service/config.d.ts +218 -0
  316. package/dist/service/config.js +265 -0
  317. package/dist/service/connection-stream.d.ts +10 -0
  318. package/dist/service/connection-stream.js +191 -0
  319. package/dist/service/connections.d.ts +60 -0
  320. package/dist/service/connections.js +271 -0
  321. package/dist/service/decisions.d.ts +35 -0
  322. package/dist/service/decisions.js +63 -0
  323. package/dist/service/descriptions.d.ts +8 -0
  324. package/dist/service/descriptions.js +20 -0
  325. package/dist/service/discovery-schemas.d.ts +92 -0
  326. package/dist/service/discovery-schemas.js +59 -0
  327. package/dist/service/discovery-search.d.ts +30 -0
  328. package/dist/service/discovery-search.js +95 -0
  329. package/dist/service/discovery.d.ts +37 -0
  330. package/dist/service/discovery.js +436 -0
  331. package/dist/service/docs.d.ts +9 -0
  332. package/dist/service/docs.js +197 -0
  333. package/dist/service/errors.d.ts +145 -0
  334. package/dist/service/errors.js +704 -0
  335. package/dist/service/federation-provider.d.ts +36 -0
  336. package/dist/service/federation-provider.js +110 -0
  337. package/dist/service/federation-server.d.ts +20 -0
  338. package/dist/service/federation-server.js +249 -0
  339. package/dist/service/federation-status.d.ts +40 -0
  340. package/dist/service/federation-status.js +151 -0
  341. package/dist/service/handlers.d.ts +18 -0
  342. package/dist/service/handlers.js +287 -0
  343. package/dist/service/mcp/confirmation.d.ts +68 -0
  344. package/dist/service/mcp/confirmation.js +178 -0
  345. package/dist/service/mcp/find-input.d.ts +12 -0
  346. package/dist/service/mcp/find-input.js +122 -0
  347. package/dist/service/mcp/input-schema.d.ts +6 -0
  348. package/dist/service/mcp/input-schema.js +126 -0
  349. package/dist/service/mcp/listing.d.ts +26 -0
  350. package/dist/service/mcp/listing.js +92 -0
  351. package/dist/service/mcp/metric-tools.d.ts +85 -0
  352. package/dist/service/mcp/metric-tools.js +258 -0
  353. package/dist/service/mcp/request-log.d.ts +5 -0
  354. package/dist/service/mcp/request-log.js +53 -0
  355. package/dist/service/mcp/runtime-policy.d.ts +27 -0
  356. package/dist/service/mcp/runtime-policy.js +62 -0
  357. package/dist/service/mcp/server.d.ts +52 -0
  358. package/dist/service/mcp/server.js +861 -0
  359. package/dist/service/mcp/tools.d.ts +99 -0
  360. package/dist/service/mcp/tools.js +938 -0
  361. package/dist/service/member-file-routes.d.ts +22 -0
  362. package/dist/service/member-file-routes.js +52 -0
  363. package/dist/service/member-files.d.ts +245 -0
  364. package/dist/service/member-files.js +258 -0
  365. package/dist/service/metric-query-platform.d.ts +77 -0
  366. package/dist/service/metric-query-platform.js +198 -0
  367. package/dist/service/metric-query-scopes.d.ts +43 -0
  368. package/dist/service/metric-query-scopes.js +147 -0
  369. package/dist/service/metric-query.d.ts +48 -0
  370. package/dist/service/metric-query.js +200 -0
  371. package/dist/service/name-suggestions.d.ts +3 -0
  372. package/dist/service/name-suggestions.js +38 -0
  373. package/dist/service/navigation-schemas.d.ts +80 -0
  374. package/dist/service/navigation-schemas.js +49 -0
  375. package/dist/service/navigation.d.ts +20 -0
  376. package/dist/service/navigation.js +165 -0
  377. package/dist/service/oauth/protocol.d.ts +70 -0
  378. package/dist/service/oauth/protocol.js +157 -0
  379. package/dist/service/oauth/refresh-replay.d.ts +2 -0
  380. package/dist/service/oauth/refresh-replay.js +20 -0
  381. package/dist/service/oauth/server.d.ts +28 -0
  382. package/dist/service/oauth/server.js +769 -0
  383. package/dist/service/operations.d.ts +170 -0
  384. package/dist/service/operations.js +392 -0
  385. package/dist/service/plan.d.ts +57 -0
  386. package/dist/service/plan.js +96 -0
  387. package/dist/service/rate-limit.d.ts +22 -0
  388. package/dist/service/rate-limit.js +52 -0
  389. package/dist/service/record-reads.d.ts +21 -0
  390. package/dist/service/record-reads.js +155 -0
  391. package/dist/service/replication.d.ts +5 -0
  392. package/dist/service/replication.js +39 -0
  393. package/dist/service/runtime-contract.d.ts +508 -0
  394. package/dist/service/runtime-contract.js +18 -0
  395. package/dist/service/runtime-identity.d.ts +71 -0
  396. package/dist/service/runtime-identity.js +122 -0
  397. package/dist/service/schemas.d.ts +961 -0
  398. package/dist/service/schemas.js +639 -0
  399. package/dist/service/service.d.ts +21 -0
  400. package/dist/service/service.js +526 -0
  401. package/dist/service/warehouse-platform.d.ts +17 -0
  402. package/dist/service/warehouse-platform.js +122 -0
  403. package/dist/service/warehouse-query.d.ts +24 -0
  404. package/dist/service/warehouse-query.js +280 -0
  405. package/dist/service/webhooks.d.ts +106 -0
  406. package/dist/service/webhooks.js +233 -0
  407. package/dist/service/workflow-admission-provider.d.ts +31 -0
  408. package/dist/service/workflow-admission-provider.js +205 -0
  409. package/dist/service/workflow-argument-serialization.d.ts +2 -0
  410. package/dist/service/workflow-argument-serialization.js +14 -0
  411. package/dist/service/workflow-callback.d.ts +22 -0
  412. package/dist/service/workflow-callback.js +75 -0
  413. package/dist/service/workflow-deployment.d.ts +8 -0
  414. package/dist/service/workflow-deployment.js +131 -0
  415. package/dist/service/workflow-diagnostics.d.ts +23 -0
  416. package/dist/service/workflow-diagnostics.js +263 -0
  417. package/dist/service/workflow-errors.d.ts +26 -0
  418. package/dist/service/workflow-errors.js +181 -0
  419. package/dist/service/workflow-logging.d.ts +2 -0
  420. package/dist/service/workflow-logging.js +50 -0
  421. package/dist/service/workflow-queue-fence.d.ts +6 -0
  422. package/dist/service/workflow-queue-fence.js +66 -0
  423. package/dist/service/workflows.d.ts +200 -0
  424. package/dist/service/workflows.js +1549 -0
  425. package/dist/sign-in.d.ts +58 -0
  426. package/dist/sign-in.js +57 -0
  427. package/dist/source.d.ts +30 -0
  428. package/dist/source.js +107 -0
  429. package/dist/start-recovery-contract.d.ts +49 -0
  430. package/dist/start-recovery-contract.js +26 -0
  431. package/dist/start-recovery.d.ts +27 -0
  432. package/dist/start-recovery.js +81 -0
  433. package/dist/storage/api.d.ts +4 -0
  434. package/dist/storage/api.js +40 -0
  435. package/dist/storage/attachments.d.ts +146 -0
  436. package/dist/storage/attachments.js +733 -0
  437. package/dist/storage/authorization.d.ts +38 -0
  438. package/dist/storage/authorization.js +83 -0
  439. package/dist/storage/file-access.d.ts +17 -0
  440. package/dist/storage/file-access.js +8 -0
  441. package/dist/storage/limits.d.ts +12 -0
  442. package/dist/storage/limits.js +17 -0
  443. package/dist/storage/maintenance-auth.d.ts +20 -0
  444. package/dist/storage/maintenance-auth.js +24 -0
  445. package/dist/storage/maintenance.d.ts +11 -0
  446. package/dist/storage/maintenance.js +67 -0
  447. package/dist/storage/neon.d.ts +4 -0
  448. package/dist/storage/neon.js +318 -0
  449. package/dist/storage/operator.d.ts +11 -0
  450. package/dist/storage/operator.js +30 -0
  451. package/dist/storage/provider.d.ts +93 -0
  452. package/dist/storage/provider.js +36 -0
  453. package/dist/storage/sessions.d.ts +184 -0
  454. package/dist/storage/sessions.js +688 -0
  455. package/dist/storage/tables.d.ts +54 -0
  456. package/dist/storage/tables.js +205 -0
  457. package/dist/storage/transfers.d.ts +16 -0
  458. package/dist/storage/transfers.js +153 -0
  459. package/dist/storage/writes.d.ts +7 -0
  460. package/dist/storage/writes.js +88 -0
  461. package/dist/telegram.d.ts +35 -0
  462. package/dist/telegram.js +173 -0
  463. package/dist/user-identity.d.ts +28 -0
  464. package/dist/user-identity.js +106 -0
  465. package/dist/user.d.ts +75 -0
  466. package/dist/user.js +111 -0
  467. package/dist/warehouse-backed.d.ts +6 -0
  468. package/dist/warehouse-backed.js +495 -0
  469. package/dist/webhook-token.d.ts +11 -0
  470. package/dist/webhook-token.js +18 -0
  471. package/dist/webhooks.d.ts +40 -0
  472. package/dist/webhooks.js +55 -0
  473. package/dist/wire.d.ts +10 -0
  474. package/dist/wire.js +35 -0
  475. package/dist/workflow-runtime.d.ts +116 -0
  476. package/dist/workflow-runtime.js +109 -0
  477. package/dist/workflow-topics.d.ts +28 -0
  478. package/dist/workflow-topics.js +28 -0
  479. package/dist/workflow.d.ts +284 -0
  480. package/dist/workflow.js +259 -0
  481. package/dist/workflows.d.ts +24 -0
  482. package/dist/workflows.js +18 -0
  483. package/package.json +127 -4
@@ -0,0 +1,938 @@
1
+ import { Schema } from "effect";
2
+ import { METRIC_QUERY_NAME_PATTERN, isBuiltInUser } from "../../metric-routes.js";
3
+ import { InvalidOntology } from "../../diagnostics.js";
4
+ import { GENERATED_UPSERT_PREFIX, humanize, mcpToolName } from "../../names.js";
5
+ import { effectivePermissions, isAllowed, permissionOf, READ_VERB, } from "../../permissions.js";
6
+ import { FIND_CONDITIONS, findToolInput } from "./find-input.js";
7
+ import { metricDescription, metricsFor, modelMetricDescription, modelMetricsFor, reachesOf, RECORDS_OR_METRIC_QUERIES, } from "../../render.js";
8
+ import { actionInputJsonSchema } from "../../runtime/generated-actions.js";
9
+ import { uploadFields } from "../../storage/attachments.js";
10
+ import { MEMBER_FILE_SCHEMAS } from "../member-files.js";
11
+ import { ConversationSearch } from "../agent/conversations.js";
12
+ import { runtimeAllows } from "./runtime-policy.js";
13
+ import { confirmationFacts, needsConfirmation, withConfirmation, } from "./confirmation.js";
14
+ import { ChatList, ChatListResult, ChatHistory, ChatPostWire, RuntimeChatPostWire, } from "../chat/schemas.js";
15
+ import { ChatPostResult } from "../../chat.js";
16
+ import { actionDescription, requires } from "../descriptions.js";
17
+ import { DiscoverInput, DiscoverToolOutput } from "../discovery-schemas.js";
18
+ import { DIMENSIONS_LIMIT, hasMetrics, VALUES_DEFAULT, VALUES_LIMIT } from "./metric-tools.js";
19
+ import { NavigationInput, NavigationToolOutput } from "../navigation-schemas.js";
20
+ import { METRIC_QUERY_FILTER_OPERATORS, METRIC_QUERY_GRANULARITIES, METRIC_QUERY_LIMITS, METRIC_QUERY_PERIOD_UNITS, METRIC_QUERY_PERIODS, HistoryPage, MAXIMUM_TIMEZONE_LENGTH, Me, } from "../schemas.js";
21
+ const DEFS = "#/$defs/";
22
+ /**
23
+ * A JSON Schema whose root is an object schema, as MCP requires of tool inputs and outputs: a root
24
+ * `$ref` into `$defs` is replaced by the definition it names.
25
+ */
26
+ function rootObject(schema) {
27
+ const reference = schema.$ref;
28
+ const definitions = schema.$defs;
29
+ if (typeof reference !== "string" || !reference.startsWith(DEFS) || definitions === undefined) {
30
+ return schema;
31
+ }
32
+ const referenced = definitions[reference.slice(DEFS.length)];
33
+ if (referenced === undefined) {
34
+ return schema;
35
+ }
36
+ const rest = Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "$ref"));
37
+ return { ...rest, ...referenced };
38
+ }
39
+ /** The JSON Schema of what a schema encodes to: the shape the service sends. */
40
+ export function encodedJsonSchema(schema) {
41
+ const document = Schema.toJsonSchemaDocument(schema);
42
+ const root = document.schema;
43
+ return rootObject(Object.keys(document.definitions).length === 0
44
+ ? root
45
+ : { ...root, $defs: document.definitions });
46
+ }
47
+ const NO_INPUT = { type: "object", properties: {}, additionalProperties: false };
48
+ function idInput(label, warehouse = false) {
49
+ return {
50
+ type: "object",
51
+ properties: {
52
+ id: {
53
+ type: "string",
54
+ ...(warehouse ? {} : { format: "uuid" }),
55
+ description: `The ${label}'s id returned by find.`,
56
+ },
57
+ },
58
+ required: ["id"],
59
+ additionalProperties: false,
60
+ };
61
+ }
62
+ function historyInput(label) {
63
+ return {
64
+ type: "object",
65
+ properties: {
66
+ id: { type: "string", format: "uuid", description: `The ${label}'s id.` },
67
+ after: { type: "string", description: "The next_cursor of the previous page." },
68
+ limit: {
69
+ type: "integer",
70
+ minimum: 1,
71
+ maximum: 200,
72
+ description: "The page size, at most 200.",
73
+ },
74
+ },
75
+ required: ["id"],
76
+ additionalProperties: false,
77
+ };
78
+ }
79
+ const READ = { readOnlyHint: true, openWorldHint: false };
80
+ /**
81
+ * Upload sessions change no business record; the action that stores the ticket does. Beginning
82
+ * one without an idempotency key opens another session, so only completion is idempotent.
83
+ */
84
+ const UPLOAD = {
85
+ readOnlyHint: false,
86
+ destructiveHint: false,
87
+ irreversibleHint: false,
88
+ idempotentHint: false,
89
+ openWorldHint: false,
90
+ };
91
+ const GENERATED_HINTS = {
92
+ create: { destructive: false, irreversible: false, idempotent: false },
93
+ update: { destructive: false, irreversible: false, idempotent: true },
94
+ delete: { destructive: true, irreversible: false, idempotent: true },
95
+ link: { destructive: false, irreversible: false, idempotent: true },
96
+ unlink: { destructive: false, irreversible: false, idempotent: true },
97
+ };
98
+ /** MCP's defaults for a tool that writes: it may destroy, and repeating it may change more. */
99
+ const AUTHORED_DEFAULT = {
100
+ destructive: true,
101
+ irreversible: false,
102
+ idempotent: false,
103
+ };
104
+ function hintsOf(planned, { name, generated, action }) {
105
+ // The built-in user's generated actions declare their own.
106
+ if (generated && action.hints !== undefined) {
107
+ return { ...AUTHORED_DEFAULT, ...action.hints };
108
+ }
109
+ if (generated) {
110
+ return name.startsWith(GENERATED_UPSERT_PREFIX)
111
+ ? { destructive: false, irreversible: false, idempotent: true }
112
+ : (GENERATED_HINTS[name] ?? AUTHORED_DEFAULT);
113
+ }
114
+ const declared = planned.resolved.actions.find((candidate) => candidate.name === name)?.hints;
115
+ // A safety label classifies the action; idempotence alone does not opt out of confirmation.
116
+ const classified = declared?.readOnly === true ||
117
+ declared?.destructive !== undefined ||
118
+ declared?.irreversible !== undefined;
119
+ return { ...AUTHORED_DEFAULT, ...(classified ? { destructive: false } : {}), ...declared };
120
+ }
121
+ /** How an agent reaches the records a relationship leads to, with the tools it has. */
122
+ function relatedHint(planned, traversal) {
123
+ if (traversal.match !== undefined) {
124
+ return (`${traversal.name}: include ["${traversal.name}"], or ${mcpToolName(traversal.target, "find")} ` +
125
+ `with where {"${traversal.match.target}": {"eq": "<${traversal.match.source}>"}}.`);
126
+ }
127
+ const id = `<${planned.resolved.entity.definition.label.toLowerCase()} id>`;
128
+ const find = mcpToolName(traversal.target, "find");
129
+ switch (traversal.kind) {
130
+ case "one":
131
+ return (`${traversal.name}: include ["${traversal.name}"], or ` +
132
+ `${mcpToolName(traversal.target, "get")} with ${traversal.name}_id.`);
133
+ case "inverseOfOne":
134
+ return `${traversal.name}: ${find} with where {"${traversal.opposite}": {"id": {"eq": "${id}"}}}.`;
135
+ case "many":
136
+ case "inverseOfMany":
137
+ return (`${traversal.name}: ${find} with where ` +
138
+ `{"${traversal.opposite}": {"some": {"id": {"eq": "${id}"}}}}.`);
139
+ }
140
+ }
141
+ /**
142
+ * An entity's metrics and what can group them, for its `find` description: an agent that finds
143
+ * the entity learns the metrics it can ask `query_metrics` for without another lookup. It names
144
+ * only the entities, and routes through them, that the reader may read.
145
+ */
146
+ function metricsHint(manifest, entity, permissions) {
147
+ const metrics = entity.metrics ?? [];
148
+ if (metrics.length === 0) {
149
+ return undefined;
150
+ }
151
+ const named = metrics.map((metric) => `${entity.name}.${metric.name} (${metricDescription(entity, metric).replace(/\.$/, "")}` +
152
+ `${metric.unit === "number" ? "" : `; ${metric.unit}`})`);
153
+ const reaches = reachesOf(manifest, entity.name, permissions).map(({ target, routes, ambiguous }) => `${target} (${routes.join(" or ")}${ambiguous ? "; write the route" : ""})`);
154
+ const users = entity.relationships.some((relationship) => isBuiltInUser(relationship.to));
155
+ return (`Metrics, counted, summed or compared with query_metrics rather than by paging find: ` +
156
+ `${named.join("; ")}. Group and filter them by ${entity.name} properties` +
157
+ (reaches.length === 0 ? "" : `, or by properties of ${reaches.join(", ")}`) +
158
+ "." +
159
+ (users
160
+ ? " Users are not reachable: query_metrics cannot split them by a user relationship."
161
+ : ""));
162
+ }
163
+ /** At most `maximum` code points of `text`, ending with an ellipsis when it was cut. */
164
+ function clip(text, maximum) {
165
+ const points = Array.from(text.trim());
166
+ return points.length <= maximum ? points.join("") : `${points.slice(0, maximum - 1).join("")}…`;
167
+ }
168
+ /**
169
+ * What the entity's fields and their values mean, as the ontology describes them: the find
170
+ * input names each field's type only, so that clients do not cut it short. Only fields the
171
+ * author described are listed.
172
+ */
173
+ function fieldsHint(entity) {
174
+ const lines = entity.properties.flatMap((property) => {
175
+ const description = property.description?.trim() ?? "";
176
+ const values = (property.options ?? []).filter((option) => option.description.trim() !== "");
177
+ if (description === "" && values.length === 0) {
178
+ return [];
179
+ }
180
+ const meaning = description === "" ? "" : ` ${clip(description, 200)}`;
181
+ const options = values.length === 0
182
+ ? ""
183
+ : ` Values: ${values
184
+ .map((option) => `${option.value} (${clip(option.description, 100).replace(/\.$/, "")})`)
185
+ .join(", ")}.`;
186
+ return [`- ${property.name}:${meaning}${options}`];
187
+ });
188
+ return lines.length === 0 ? undefined : `Fields:\n${lines.join("\n")}`;
189
+ }
190
+ function readTools(planned, schemas, built) {
191
+ const { manifest } = built.plan.ontology;
192
+ const { definition } = planned.resolved.entity;
193
+ const label = definition.label.toLowerCase();
194
+ const read = permissionOf(planned.name, READ_VERB);
195
+ const related = [...planned.traversals.map((traversal) => relatedHint(planned, traversal))].map((hint) => `- ${hint}`);
196
+ const includable = planned.traversals.slice(0, 2).map((traversal) => `"${traversal.name}"`);
197
+ const entity = manifest.entities.find((candidate) => candidate.name === planned.name);
198
+ const including = includable.length === 0
199
+ ? ""
200
+ : ` Pass include as a list of relationship names, as in [${includable.join(", ")}].`;
201
+ const findDescription = (permissions) => {
202
+ const metrics = metricsHint(manifest, entity, permissions);
203
+ const fields = fieldsHint(entity);
204
+ return (`Filter, sort and page through ${definition.plural.toLowerCase()}, at most 200 at a ` +
205
+ `time; pass next_cursor as after to read the next page.${including} ` +
206
+ `${definition.description}\n\n` +
207
+ `${FIND_CONDITIONS}\n\n` +
208
+ `${requires([read])} Including a relationship, or filtering through one, requires ` +
209
+ "reading its entity too." +
210
+ (fields === undefined ? "" : `\n\n${fields}`) +
211
+ (related.length > 0 ? `\n\nRelated records:\n${related.join("\n")}` : "") +
212
+ (metrics === undefined ? "" : `\n\n${metrics}`));
213
+ };
214
+ return [
215
+ {
216
+ name: mcpToolName(planned.name, "find"),
217
+ title: `Find ${definition.plural.toLowerCase()}`,
218
+ description: findDescription([read]),
219
+ ...((entity.metrics ?? []).length === 0
220
+ ? {}
221
+ : {
222
+ descriptionFor: (caller) => findDescription(effectivePermissions(caller)),
223
+ }),
224
+ // The query of POST /<entity>/query, published compactly. The server decodes it with the
225
+ // closed schema: an unknown field or operator is an error.
226
+ inputSchema: findToolInput(manifest, planned.name),
227
+ outputSchema: { type: "object", ...encodedJsonSchema(schemas.findResult) },
228
+ annotations: READ,
229
+ permissions: [read],
230
+ target: { kind: "find", planned },
231
+ },
232
+ {
233
+ name: mcpToolName(planned.name, "get"),
234
+ title: `Get a ${label}`,
235
+ description: `One ${label} by its id. ${definition.description}\n\n${requires([read])}`,
236
+ inputSchema: idInput(label, definition.source !== undefined),
237
+ outputSchema: encodedJsonSchema(schemas.record),
238
+ annotations: READ,
239
+ permissions: [read],
240
+ target: { kind: "get", planned },
241
+ },
242
+ ...(definition.source === undefined
243
+ ? [
244
+ {
245
+ name: mcpToolName(planned.name, "history"),
246
+ title: `History of a ${label}`,
247
+ description: `What each action changed on a ${label}, newest first, with who ran it and the values ` +
248
+ `before and after. ${requires([read])}`,
249
+ inputSchema: historyInput(label),
250
+ outputSchema: encodedJsonSchema(HistoryPage),
251
+ annotations: READ,
252
+ permissions: [read],
253
+ target: { kind: "history", planned },
254
+ },
255
+ ]
256
+ : []),
257
+ ];
258
+ }
259
+ /**
260
+ * The argument an action that consumes or stages an upload takes beside its input: the idempotency key the
261
+ * runtime requires of it, and the create intent the upload was begun with. The service removes it
262
+ * before the input is validated.
263
+ */
264
+ export const ACTION_OPTIONS_ARGUMENT = "_options";
265
+ /** The `me` tool's marker: tool calls accept the runtime envelope's chat source. */
266
+ export const RUNTIME_SOURCE_META = "segmentstream/runtime-source";
267
+ /** The `chat_post_message` tool's marker: the deployment posts exact messages to its chat. */
268
+ export const CHAT_POST_META = "segmentstream/chat-post";
269
+ const ACTION_OPTIONS_SCHEMA = {
270
+ type: "object",
271
+ description: "Options of an action that stores or stages a file: idempotency_key, required for file writes, " +
272
+ "and create_intent, the one the upload was begun with when it creates a record.",
273
+ properties: {
274
+ idempotency_key: { type: "string", minLength: 1, maxLength: 128 },
275
+ create_intent: { type: "string", format: "uuid" },
276
+ },
277
+ additionalProperties: false,
278
+ };
279
+ /** File-writing action tools expose their options even when preparation creates the upload. */
280
+ function actionToolInput(action) {
281
+ // Empty Effect structs omit the root type, but MCP requires an explicit object input schema.
282
+ const schema = {
283
+ type: "object",
284
+ ...rootObject(actionInputJsonSchema(action.input)),
285
+ };
286
+ const properties = schema.properties;
287
+ if ((uploadFields(action.input).length === 0 && (action.files?.length ?? 0) === 0) ||
288
+ (schema.type !== undefined && schema.type !== "object") ||
289
+ (properties !== undefined && ACTION_OPTIONS_ARGUMENT in properties)) {
290
+ return schema;
291
+ }
292
+ return {
293
+ ...schema,
294
+ type: "object",
295
+ properties: { ...(properties ?? {}), [ACTION_OPTIONS_ARGUMENT]: ACTION_OPTIONS_SCHEMA },
296
+ };
297
+ }
298
+ function actionTool(planned, plannedAction) {
299
+ const { name, action, permissions } = plannedAction;
300
+ const hints = hintsOf(planned, plannedAction);
301
+ return {
302
+ name: mcpToolName(planned.name, name),
303
+ title: `${planned.resolved.entity.definition.label}: ${humanize(name).toLowerCase()}`,
304
+ description: actionDescription(plannedAction),
305
+ inputSchema: actionToolInput(action),
306
+ annotations: {
307
+ readOnlyHint: hints.readOnly === true && action.prepare !== undefined && !action.transactional,
308
+ destructiveHint: hints.destructive,
309
+ irreversibleHint: hints.irreversible,
310
+ idempotentHint: hints.idempotent,
311
+ openWorldHint: action.connections.length > 0 && hints.connectionsReadOnly !== true,
312
+ },
313
+ permissions,
314
+ target: { kind: "action", planned, action: plannedAction },
315
+ };
316
+ }
317
+ /** `discover` of an ontology that ranks entities by meaning with its decision model. */
318
+ const DISCOVER_BY_MEANING = "Find which entities a request concerns, ranked by meaning: pass as query the member's request " +
319
+ "in their words, and what you understand they want. Each match is an entity with its " +
320
+ "relevance, the tools you may call for it and its metrics; call one by its exact name. With " +
321
+ "kind action or metric, or after, it matches words in names and descriptions instead. Search " +
322
+ "reads metadata, not records.";
323
+ const GLOBAL_TOOLS = [
324
+ {
325
+ name: "discover",
326
+ title: "Search ontology definitions",
327
+ description: "Find entities, permitted actions, and computable metrics by their names and descriptions. " +
328
+ "Entity matches also search properties, options, and relationships. Auto ranks literal and " +
329
+ "token matches before spelling approximations; literal is a substring search with no regex. " +
330
+ "Results are summaries. Search reads metadata, not records. " +
331
+ "Use next_cursor as after only when more matches are relevant to the task.",
332
+ inputSchema: encodedJsonSchema(DiscoverInput),
333
+ outputSchema: { type: "object", ...encodedJsonSchema(DiscoverToolOutput) },
334
+ annotations: READ,
335
+ permissions: [],
336
+ target: { kind: "discover" },
337
+ },
338
+ {
339
+ name: "me",
340
+ _meta: { [RUNTIME_SOURCE_META]: 1 },
341
+ title: "Who am I",
342
+ description: "Who you are in this app: your user, your roles and the permissions they grant. History " +
343
+ "names you by the user id.",
344
+ inputSchema: NO_INPUT,
345
+ outputSchema: encodedJsonSchema(Me),
346
+ annotations: READ,
347
+ permissions: [],
348
+ target: { kind: "me" },
349
+ },
350
+ ];
351
+ const METRIC_QUERY_NAME = {
352
+ type: "string",
353
+ pattern: METRIC_QUERY_NAME_PATTERN,
354
+ description: "<entity>.<property>, or a route from a metric's entity when it reaches the property's " +
355
+ "entity in several ways: <entity>.<relationship>.<property>, at most two relationships.",
356
+ };
357
+ const METRIC_QUERY_VALUE = {
358
+ anyOf: [{ type: "string" }, { type: "number" }, { type: "boolean" }],
359
+ };
360
+ /** `a, b or c`. */
361
+ function alternatives(values) {
362
+ return values.length < 2
363
+ ? values.join("")
364
+ : `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`;
365
+ }
366
+ const PERIODS = `${alternatives(METRIC_QUERY_PERIODS)}; or last N ${alternatives(METRIC_QUERY_PERIOD_UNITS)}, N at ` +
367
+ "least 1. Write a period exactly so: lowercase, single spaces, plural units even for 1 (last 1 " +
368
+ "days). last N days ends yesterday; last N weeks, months, quarters or years are whole units " +
369
+ "before the current one. Weeks start on Monday.";
370
+ const FILTER_OPERATOR_DESCRIPTION = "equals, notEquals, gt, gte, lt, lte, contains, startsWith, endsWith and inPeriod take value; " +
371
+ "in, notIn and between take values; isNull and isNotNull take neither. notEquals and notIn also " +
372
+ "match null values and rows a route finds nothing for, so equals and notEquals together cover " +
373
+ "every row.";
374
+ const FILTER_VALUE_DESCRIPTION = "equals, notEquals: the value. gt, gte, lt, lte: the bound, of a date, timestamp or number " +
375
+ "dimension; a date covers whole days on a timestamp. contains, startsWith, endsWith: a " +
376
+ "non-empty string, matched case-sensitively, without wildcards. inPeriod: a date or timestamp " +
377
+ `dimension's period, today being the date in the request's timezone: ${PERIODS}`;
378
+ /** The query_metrics tool's input: the request of `POST /api/ontology/query_metrics`, as it is. */
379
+ function metricQueryInput() {
380
+ return {
381
+ type: "object",
382
+ properties: {
383
+ metrics: {
384
+ type: "array",
385
+ minItems: 1,
386
+ maxItems: METRIC_QUERY_LIMITS.metrics,
387
+ uniqueItems: true,
388
+ items: { type: "string" },
389
+ description: "What to compute, as <entity>.<metric>, or a model metric by its name. " +
390
+ "Metrics of several entities are each computed over their own entity's rows, then " +
391
+ "combined on the dimensions; a model metric is computed on the combined rows " +
392
+ "from the entity metrics it reads.",
393
+ },
394
+ dimensions: {
395
+ type: "array",
396
+ maxItems: METRIC_QUERY_LIMITS.dimensions,
397
+ uniqueItems: true,
398
+ items: METRIC_QUERY_NAME,
399
+ description: "What to group by. Every dimension must be reachable from every metric's entity.",
400
+ },
401
+ filters: {
402
+ type: "array",
403
+ maxItems: METRIC_QUERY_LIMITS.filters,
404
+ description: "All must hold. A filter applies to each metric's entity that reaches it; the answer " +
405
+ "warns about the others.",
406
+ items: {
407
+ type: "object",
408
+ properties: {
409
+ dimension: METRIC_QUERY_NAME,
410
+ operator: {
411
+ enum: [...METRIC_QUERY_FILTER_OPERATORS],
412
+ description: FILTER_OPERATOR_DESCRIPTION,
413
+ },
414
+ value: { ...METRIC_QUERY_VALUE, description: FILTER_VALUE_DESCRIPTION },
415
+ values: {
416
+ type: "array",
417
+ minItems: 1,
418
+ maxItems: METRIC_QUERY_LIMITS.values,
419
+ items: METRIC_QUERY_VALUE,
420
+ description: "The values of in and notIn, or the two inclusive bounds of between, for example " +
421
+ '["2026-09-01", "2026-09-30"]; dates cover whole days on a timestamp.',
422
+ },
423
+ },
424
+ required: ["dimension", "operator"],
425
+ additionalProperties: false,
426
+ },
427
+ },
428
+ granularity: {
429
+ enum: [...METRIC_QUERY_GRANULARITIES],
430
+ description: "Buckets the date or timestamp dimension granularityOf names; hour applies to " +
431
+ "timestamps only. Weeks start on Monday.",
432
+ },
433
+ granularityOf: {
434
+ ...METRIC_QUERY_NAME,
435
+ description: "A requested date or timestamp dimension.",
436
+ },
437
+ timezone: {
438
+ type: "string",
439
+ maxLength: MAXIMUM_TIMEZONE_LENGTH,
440
+ description: "An IANA timezone, such as Europe/Moscow, or UTC. Buckets of timestamps, date bounds on " +
441
+ "timestamps and inPeriod's today follow it; without it, the timezone of the entity that " +
442
+ "owns the dimension.",
443
+ },
444
+ orderBy: {
445
+ type: "array",
446
+ maxItems: METRIC_QUERY_LIMITS.orderBy,
447
+ items: {
448
+ type: "object",
449
+ properties: {
450
+ metric: { type: "string", description: "A requested metric." },
451
+ dimension: { type: "string", description: "A requested dimension." },
452
+ direction: { enum: ["asc", "desc"] },
453
+ },
454
+ required: ["direction"],
455
+ additionalProperties: false,
456
+ },
457
+ },
458
+ limit: {
459
+ type: "integer",
460
+ minimum: 1,
461
+ maximum: METRIC_QUERY_LIMITS.rows,
462
+ description: "At most 1000 rows; 100 by default.",
463
+ },
464
+ },
465
+ required: ["metrics"],
466
+ additionalProperties: false,
467
+ };
468
+ }
469
+ const QUERY_METRICS_DESCRIPTION = "Compute metrics of one or several entities, grouped and filtered by properties " +
470
+ `of related entities. The rule: ${RECORDS_OR_METRIC_QUERIES}.\n\n` +
471
+ "list_metrics lists every metric you may compute, and each entity's <entity>_find names its " +
472
+ "own; get_dimensions says what metrics can be grouped and filtered by, and " +
473
+ "get_dimension_values the values a dimension takes. The shapes, with placeholders:\n" +
474
+ '- A total by a property: {"metrics": ["<entity>.<metric>"], "dimensions": ' +
475
+ '["<entity>.<property>"]}\n' +
476
+ '- A period, by week: {"metrics": ["<entity>.<metric>"], "dimensions": ["<entity>.<date>"], ' +
477
+ '"granularity": "week", "granularityOf": "<entity>.<date>", "filters": [{"dimension": ' +
478
+ '"<entity>.<date>", "operator": "inPeriod", "value": "last 4 weeks"}]}\n' +
479
+ '- By a property of a related entity: {"metrics": ["<entity>.<metric>"], "dimensions": ' +
480
+ '["<related entity>.<property>"], "filters": [{"dimension": "<entity>.<date>", "operator": ' +
481
+ '"between", "values": ["2026-09-01", "2026-09-30"]}]}\n\n' +
482
+ "Partitioned warehouse entities require a between or inPeriod filter on their date property; " +
483
+ "the error names it. Currency metrics need a single-currency filter, unless the metric is " +
484
+ "pinned to one currency. Use inPeriod for relative dates; the answer's execution.periods says " +
485
+ "which dates were used. " +
486
+ "Answers come from the warehouse, and stored records from its eventually consistent replica. " +
487
+ "There is no destination freshness watermark. execution.warnings says when a filter did not apply to a metric. " +
488
+ "Requires reading every entity the request reads, path intermediates included, and every " +
489
+ "entity a model metric reads. A model metric is named without an entity; a " +
490
+ "filter must reach every entity it reads or none of them, unless its alignment gives an entity " +
491
+ "no counterpart. A route never passes through or ends at User.";
492
+ const SEARCH = {
493
+ type: "string",
494
+ minLength: 1,
495
+ maxLength: 200,
496
+ description: "Words that must all occur in the name, label or description, ignoring case.",
497
+ };
498
+ const METRIC_NAMES = {
499
+ type: "array",
500
+ minItems: 1,
501
+ maxItems: METRIC_QUERY_LIMITS.metrics,
502
+ uniqueItems: true,
503
+ items: { type: "string" },
504
+ description: "Metric names as list_metrics gives them: <entity>.<metric>, or a model metric's.",
505
+ };
506
+ const METRIC = {
507
+ type: "object",
508
+ properties: {
509
+ name: { type: "string" },
510
+ label: { type: "string" },
511
+ unit: { enum: ["number", "currency", "ratio", "percent"] },
512
+ description: { type: "string" },
513
+ entity: { type: "string" },
514
+ reads: { type: "array", items: { type: "string" } },
515
+ },
516
+ required: ["name", "label", "unit", "description"],
517
+ };
518
+ const DIMENSION = {
519
+ type: "object",
520
+ properties: {
521
+ name: { type: "string" },
522
+ label: { type: "string" },
523
+ type: { enum: ["string", "decimal", "boolean", "date", "timestamp"] },
524
+ description: { type: "string" },
525
+ values: { type: "array", items: { type: "string" } },
526
+ },
527
+ required: ["name", "label", "type"],
528
+ };
529
+ /** The metric tools, named as dbt names its MCP tools: see `./metric-tools.ts`. */
530
+ function metricTools(manifest) {
531
+ const query = metricQueryInput();
532
+ const listed = (schema) => (caller) => hasMetrics(manifest, caller.permissions) ? schema : undefined;
533
+ const lookup = { ...READ, idempotentHint: true };
534
+ const listInput = {
535
+ type: "object",
536
+ properties: { search: SEARCH },
537
+ additionalProperties: false,
538
+ };
539
+ const dimensionsInput = {
540
+ type: "object",
541
+ properties: { metrics: METRIC_NAMES, search: SEARCH },
542
+ required: ["metrics"],
543
+ additionalProperties: false,
544
+ };
545
+ const valuesInput = {
546
+ type: "object",
547
+ properties: {
548
+ dimension: {
549
+ ...METRIC_QUERY_NAME,
550
+ description: "A dimension name, as get_dimensions gives it.",
551
+ },
552
+ metrics: {
553
+ ...METRIC_NAMES,
554
+ description: "The metrics whose rows the values come from; by default one of the dimension's own " +
555
+ "entity, else one that reaches it.",
556
+ },
557
+ search: {
558
+ type: "string",
559
+ minLength: 1,
560
+ maxLength: 200,
561
+ description: "Only values containing this text, matched case-sensitively.",
562
+ },
563
+ filters: {
564
+ ...query.properties.filters,
565
+ description: "As in query_metrics. A partitioned warehouse entity needs a date filter; the error names it.",
566
+ },
567
+ limit: {
568
+ type: "integer",
569
+ minimum: 1,
570
+ maximum: VALUES_LIMIT,
571
+ description: `At most ${VALUES_LIMIT} values; ${VALUES_DEFAULT} by default.`,
572
+ },
573
+ },
574
+ required: ["dimension"],
575
+ additionalProperties: false,
576
+ };
577
+ return [
578
+ {
579
+ name: "list_metrics",
580
+ title: "List metrics",
581
+ description: "List the metrics you may compute: each entity's metrics, and model metrics, which " +
582
+ "combine several entities' metrics. Each has its name, label, unit and meaning, with its " +
583
+ "conditions, balance rule or the metrics it reads; the ontology's code declares them as " +
584
+ "metrics. search narrows them. Then get_dimensions says what they can be grouped by, " +
585
+ "and query_metrics computes them.",
586
+ inputSchema: listInput,
587
+ inputSchemaFor: listed(listInput),
588
+ outputSchema: {
589
+ type: "object",
590
+ properties: { metrics: { type: "array", items: METRIC } },
591
+ required: ["metrics"],
592
+ },
593
+ annotations: lookup,
594
+ permissions: [],
595
+ target: { kind: "list-metrics" },
596
+ },
597
+ {
598
+ name: "get_dimensions",
599
+ title: "Get dimensions of metrics",
600
+ description: "What the given metrics can be grouped and filtered by in query_metrics: the properties " +
601
+ "of their entities and of the entities those reach, each reachable from every given " +
602
+ "metric, with its type, meaning and, for a choice field, its values. A property reached " +
603
+ "in several ways is named by its route. A route never passes through or ends at User. " +
604
+ `At most ${DIMENSIONS_LIMIT}; search narrows them.`,
605
+ inputSchema: dimensionsInput,
606
+ inputSchemaFor: listed(dimensionsInput),
607
+ outputSchema: {
608
+ type: "object",
609
+ properties: {
610
+ dimensions: { type: "array", items: DIMENSION },
611
+ truncated: { type: "boolean" },
612
+ },
613
+ required: ["dimensions", "truncated"],
614
+ },
615
+ annotations: lookup,
616
+ permissions: [],
617
+ target: { kind: "get-dimensions" },
618
+ },
619
+ {
620
+ name: "get_dimension_values",
621
+ title: "Get dimension values",
622
+ description: "The values a dimension takes, to write a filter that matches the data: a choice " +
623
+ "field's options and a boolean's true and false at once; any other dimension's distinct " +
624
+ "values among a metric's rows, sorted. Requires reading what that metric reads.",
625
+ inputSchema: valuesInput,
626
+ inputSchemaFor: listed(valuesInput),
627
+ outputSchema: {
628
+ type: "object",
629
+ properties: {
630
+ dimension: { type: "string" },
631
+ values: { type: "array", items: { type: ["string", "number", "boolean", "null"] } },
632
+ options: {
633
+ type: "array",
634
+ items: {
635
+ type: "object",
636
+ properties: {
637
+ value: { type: "string" },
638
+ label: { type: "string" },
639
+ description: { type: "string" },
640
+ },
641
+ required: ["value", "label"],
642
+ },
643
+ },
644
+ metrics: { type: "array", items: { type: "string" } },
645
+ truncated: { type: "boolean" },
646
+ warnings: { type: "array", items: { type: "string" } },
647
+ },
648
+ required: ["dimension", "values", "truncated"],
649
+ },
650
+ annotations: lookup,
651
+ permissions: [],
652
+ target: { kind: "get-dimension-values" },
653
+ },
654
+ {
655
+ name: "query_metrics",
656
+ title: "Query metrics",
657
+ description: QUERY_METRICS_DESCRIPTION,
658
+ // The model metrics this caller may compute, which belong to no entity's find.
659
+ descriptionFor: (caller) => {
660
+ const model = modelMetricsFor(manifest, effectivePermissions(caller));
661
+ return model.length === 0
662
+ ? QUERY_METRICS_DESCRIPTION
663
+ : `${QUERY_METRICS_DESCRIPTION}\n\nModel metrics:\n${model
664
+ .map((metric) => `- ${metric.name} (${metric.label}` +
665
+ `${metric.unit === "number" ? "" : `; ${metric.unit}`}): ` +
666
+ modelMetricDescription(metric))
667
+ .join("\n")}`;
668
+ },
669
+ inputSchema: query,
670
+ inputSchemaFor: listed(query),
671
+ annotations: READ,
672
+ permissions: [],
673
+ target: { kind: "query-metrics" },
674
+ },
675
+ ];
676
+ }
677
+ /**
678
+ * The MCP tools of an ontology: `me`, `discover` when it ranks by meaning, opt-in `navigation`,
679
+ * and the metric tools when the ontology has metrics,
680
+ * then for every stored entity `find`, `get`,
681
+ * `history` and a tool per generated and authored action. Entities with a warehouse source have none,
682
+ * as they have no record routes. Throws {@link InvalidOntology} when two tools share a name, which
683
+ * `check` already refuses.
684
+ */
685
+ export function mcpTools(built, conversations = false, storage = {}, navigation = false) {
686
+ const { manifest } = built.plan.ontology;
687
+ const tools = [
688
+ ...GLOBAL_TOOLS,
689
+ ...(navigation
690
+ ? [
691
+ {
692
+ name: "navigation",
693
+ title: "Discover application pages",
694
+ description: "List published application pages, optionally filtered by entity and title/description keywords. " +
695
+ "Read descriptions to choose a page. Static pages have url; parameterized pages have url_pattern and " +
696
+ "parameter hints. Patterns require established values, encoded by path segment. " +
697
+ "This reads metadata only; " +
698
+ "it does not open pages, select records, or grant access. " +
699
+ "Use next_cursor as after to continue.",
700
+ inputSchema: encodedJsonSchema(NavigationInput),
701
+ outputSchema: { type: "object", ...encodedJsonSchema(NavigationToolOutput) },
702
+ annotations: { ...READ, destructiveHint: false, idempotentHint: true },
703
+ permissions: [],
704
+ target: { kind: "navigation" },
705
+ },
706
+ ]
707
+ : []),
708
+ ...(metricsFor(manifest).length > 0 ? metricTools(manifest) : []),
709
+ ];
710
+ for (const planned of built.plan.entities) {
711
+ const schemas = built.schemas.get(planned.name);
712
+ const reads = readTools(planned, schemas, built);
713
+ const actions = planned.actions.map((action) => actionTool(planned, action));
714
+ tools.push(...(planned.name === "agent_chat"
715
+ ? [...reads.filter((tool) => tool.target.kind === "get"), ...actions].map((tool) => ({
716
+ ...tool,
717
+ name: tool.name.replace(/^agent_chat_/, "chat_"),
718
+ }))
719
+ : [...reads, ...actions]));
720
+ }
721
+ const discover = tools.findIndex((tool) => tool.name === "discover");
722
+ // Word search duplicates the client's own tool search; ranking by meaning does not.
723
+ if (discover >= 0) {
724
+ if (built.plan.ontology.config.discovery === undefined) {
725
+ tools.splice(discover, 1);
726
+ }
727
+ else {
728
+ tools[discover] = { ...tools[discover], description: DISCOVER_BY_MEANING };
729
+ }
730
+ }
731
+ const post = tools.findIndex((tool) => tool.name === "chat_post_message");
732
+ if (post >= 0) {
733
+ const original = tools[post];
734
+ const replacement = {
735
+ ...original,
736
+ inputSchema: encodedJsonSchema(ChatPostWire),
737
+ outputSchema: encodedJsonSchema(ChatPostResult),
738
+ ...(manifest.chat?.telegram === undefined ? {} : { _meta: { [CHAT_POST_META]: 1 } }),
739
+ annotations: {
740
+ readOnlyHint: false,
741
+ destructiveHint: false,
742
+ irreversibleHint: true,
743
+ idempotentHint: true,
744
+ openWorldHint: true,
745
+ },
746
+ };
747
+ tools[post] = replacement;
748
+ }
749
+ tools.push({
750
+ name: "chat_list",
751
+ title: "List eligible chats",
752
+ description: "List eligible chat destinations and server attribution. query filters titles by a case-insensitive " +
753
+ "substring before pagination; chat selects an exact ID/title. Posting does not grant history access.",
754
+ inputSchema: encodedJsonSchema(ChatList),
755
+ outputSchema: encodedJsonSchema(ChatListResult),
756
+ annotations: READ,
757
+ permissions: [],
758
+ target: { kind: "chat-list" },
759
+ inputSchemaFor: (caller) => isAllowed("agent_chat:read", caller) ||
760
+ isAllowed("agent_chat:post_message", caller) ||
761
+ ("kind" in caller && caller.kind === "member")
762
+ ? encodedJsonSchema(ChatList)
763
+ : undefined,
764
+ });
765
+ tools.push({
766
+ name: "chat_history",
767
+ title: "Read chat conversation",
768
+ description: "Read messages for an exact chat ID/title, with independent conversation pagination. " +
769
+ "Reads a group chat you are in (every group with agent_chat:read) or your own private chat.",
770
+ inputSchema: encodedJsonSchema(ChatHistory),
771
+ annotations: READ,
772
+ permissions: [],
773
+ target: { kind: "chat-history" },
774
+ inputSchemaFor: (caller) => "kind" in caller && caller.kind === "member" ? encodedJsonSchema(ChatHistory) : undefined,
775
+ });
776
+ tools.push({
777
+ name: "chat_search",
778
+ title: "Search stored conversations",
779
+ description: conversations
780
+ ? "Search retained conversation messages, decisions and tool calls by text, provider chat ID, " +
781
+ "sender ID, topic and date range. Returns the group chats you are in (every group with " +
782
+ "agent_chat:read) and DMs in which you participated. Dates are ISO 8601; before is the " +
783
+ "nextCursor of the previous page. " +
784
+ "Workspace administrators can read all DMs through the platform API."
785
+ : "Search retained conversations. Requires an available archive and independent conversation read access.",
786
+ inputSchema: encodedJsonSchema(ConversationSearch),
787
+ annotations: READ,
788
+ permissions: [],
789
+ target: { kind: "conversation-search" },
790
+ inputSchemaFor: (caller) => "kind" in caller && caller.kind === "member"
791
+ ? encodedJsonSchema(ConversationSearch)
792
+ : undefined,
793
+ });
794
+ const descriptions = {
795
+ "attachments-list": "List chat attachments by conversation (provider:chat ID), sender member UUID and ISO time range. " +
796
+ "Returns a bounded page and nextCursor; use before to resume. Includes expired metadata. " +
797
+ "Administrators with agent_chat:update may access any workspace chat; active group participants " +
798
+ "and DM senders may access their files.",
799
+ "attachments-get": "Read metadata of an accessible chat attachment. Expired or purged attachments return a clear error.",
800
+ "attachments-download": "Download an accessible chat attachment. Returns filename, content type, size, SHA-256 and a " +
801
+ "short-lived GET grant. Stream the URL's bytes with its supplied headers before expiry; do not " +
802
+ "forward your app bearer token.",
803
+ "attachments-promote": "Keep a chat attachment through an ontology action such as document.upload. Supply the action " +
804
+ "input without the file; the platform adopts the stored revision, fills SHA-256 when declared, " +
805
+ "and enforces your current action permissions. Retries reuse the promotion result.",
806
+ "files-download": "Download a stored blob property of a record you may read. property defaults to content. Returns " +
807
+ "immutable revision metadata, filename, content type, size, SHA-256 and a short-lived GET grant. " +
808
+ "Stream bytes from the URL with its supplied headers before expiry; do not forward your app " +
809
+ "bearer token.",
810
+ "files-upload-list": "List your open upload sessions and the pending/max slot counts. Includes IDs, filenames, " +
811
+ "target actions, expiry and awaiting_action. A ready upload has transferred its bytes but " +
812
+ "has not saved a record: call its action with the ticket, or cancel it if abandoned. " +
813
+ "Expired sessions and sessions from earlier deployments do not occupy current slots.",
814
+ "files-upload-get": "Inspect one of your uploads by ID. A ready session returns a ticket for its target action. " +
815
+ "Completing the transfer alone does not save a record. Keep the original action input and " +
816
+ "options for retries, and cancel an upload after a permanent rejection if you will not retry.",
817
+ "files-upload": "Begin storing a file through the action that takes it, such as an upload action. Give " +
818
+ "entity, action, filename, content_type and the exact size in bytes; property when the action " +
819
+ "takes several uploads of the entity, and record_id when the action changes an existing " +
820
+ "record. Returns upload.id, a short-lived transfer grant and options. Send the file's bytes " +
821
+ "as the request body to transfer.url with transfer.method and exactly transfer.headers before " +
822
+ "expiry; do not forward your app bearer token. Then call files_upload_complete with " +
823
+ "upload.id, and call the action with its file field set to the returned ticket and _options " +
824
+ "set to options. Give your own idempotency_key, a new UUID for each file, so any failure can " +
825
+ "be retried: after a lost response or an error with retryable: true, repeat the same call " +
826
+ "with the same key, waiting retry_after seconds when the error gives them, and it resumes " +
827
+ "the upload. Begin again with a new key only after a conflict without retryable, which means " +
828
+ "the upload can no longer resume. Open uploads per caller are limited: store each file " +
829
+ "with its action before beginning many, and cancel with files_upload_cancel an upload you " +
830
+ "will not use. Recover IDs with files_upload_list, and inspect a session with files_upload_get. " +
831
+ "A rejected action keeps its upload for a retry; cancel it after a permanent rejection " +
832
+ "when you will not retry. An action that succeeds without keeping its file, for example because the " +
833
+ "same file is already stored, releases the upload itself.",
834
+ "files-upload-complete": "Finish an upload once its bytes are transferred. The service checks the stored size and " +
835
+ "content type, then returns upload.ticket, {upload_id}, for the action's file field. " +
836
+ "An action that succeeds releases the ticket whether or not it keeps the file; a ticket no " +
837
+ "action takes expires after 24 hours unless you cancel it. Repeat the call after an error " +
838
+ "with retryable: true, waiting retry_after seconds when given; completing twice is safe.",
839
+ "files-upload-cancel": "Cancel one of your open uploads that no action will take, such as a file you found already " +
840
+ "stored, so it stops counting towards your open-upload limit and its bytes are removed. " +
841
+ "Give the upload.id from files_upload. An upload an action already stored cannot be " +
842
+ "canceled; canceling twice is safe.",
843
+ };
844
+ for (const operation of Object.keys(MEMBER_FILE_SCHEMAS)) {
845
+ if (operation.startsWith("files-") ? !storage.files : !storage.attachments) {
846
+ continue;
847
+ }
848
+ tools.push({
849
+ name: operation.replaceAll("-", "_"),
850
+ title: operation.replaceAll("-", " "),
851
+ description: descriptions[operation],
852
+ inputSchema: encodedJsonSchema(MEMBER_FILE_SCHEMAS[operation]),
853
+ annotations: operation === "attachments-promote"
854
+ ? { readOnlyHint: false, idempotentHint: true, openWorldHint: true }
855
+ : operation === "files-upload"
856
+ ? UPLOAD
857
+ : operation === "files-upload-complete" || operation === "files-upload-cancel"
858
+ ? { ...UPLOAD, idempotentHint: true }
859
+ : READ,
860
+ ...(operation === "attachments-promote"
861
+ ? {
862
+ _meta: {
863
+ "segmentstream/nested-action": {
864
+ version: 1,
865
+ entityArgument: "entity",
866
+ actionArgument: "action",
867
+ inputArgument: "input",
868
+ recordArgument: "record_id",
869
+ },
870
+ },
871
+ }
872
+ : {}),
873
+ permissions: [],
874
+ target: { kind: "member-file", operation },
875
+ });
876
+ }
877
+ const seen = new Set();
878
+ const duplicates = tools.filter(({ name }) => seen.size === seen.add(name).size);
879
+ if (duplicates.length > 0) {
880
+ throw new InvalidOntology({
881
+ message: `The ontology's MCP tools collide: ${duplicates.map(({ name }) => name).join(", ")}.`,
882
+ diagnostics: duplicates.map(({ name }) => ({
883
+ severity: "error",
884
+ code: "invalid-tool-name",
885
+ path: name,
886
+ message: `${name} is the name of two MCP tools.`,
887
+ })),
888
+ });
889
+ }
890
+ return tools.map((tool) => ({
891
+ ...tool,
892
+ inputSchema: withConfirmation(tool.inputSchema, tool.annotations),
893
+ // Exact chat posting confirms its own preview of the destination and the posted text.
894
+ ...(tool.target.kind === "action" &&
895
+ tool.name !== "chat_post_message" &&
896
+ needsConfirmation(tool.annotations)
897
+ ? {
898
+ confirmation: confirmationFacts({
899
+ title: tool.title,
900
+ description: tool.description,
901
+ inputSchema: tool.inputSchema,
902
+ manifest,
903
+ entity: tool.target.planned.name,
904
+ omit: [ACTION_OPTIONS_ARGUMENT],
905
+ preview: tool.target.action.action.confirm !== undefined,
906
+ }),
907
+ }
908
+ : {}),
909
+ }));
910
+ }
911
+ /**
912
+ * The tools a caller may see: those whose every permission the caller's roles grant, each with the
913
+ * caller's input schema.
914
+ */
915
+ export function visibleTools(tools, caller, provenance = { kind: "unverified" }) {
916
+ return tools.flatMap((tool) => {
917
+ if (!runtimeAllows(provenance, tool) ||
918
+ !tool.permissions.every((required) => isAllowed(required, caller))) {
919
+ return [];
920
+ }
921
+ const description = tool.descriptionFor?.(caller) ?? tool.description;
922
+ if (tool.inputSchemaFor === undefined) {
923
+ return [
924
+ {
925
+ ...tool,
926
+ description,
927
+ ...(tool.name === "chat_post_message" && provenance.kind === "runtime"
928
+ ? {
929
+ inputSchema: withConfirmation(encodedJsonSchema(RuntimeChatPostWire), tool.annotations),
930
+ }
931
+ : {}),
932
+ },
933
+ ];
934
+ }
935
+ const inputSchema = tool.inputSchemaFor(caller);
936
+ return inputSchema === undefined ? [] : [{ ...tool, description, inputSchema }];
937
+ });
938
+ }