@vertesia/common 1.6.0-dev.20260923.085325Z → 1.6.0-dev.20261004.085740Z

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 (405) hide show
  1. package/lib/access-control-values.d.ts +2 -2
  2. package/lib/access-control-values.d.ts.map +1 -1
  3. package/lib/access-control-values.js +2 -2
  4. package/lib/access-control-values.js.map +1 -1
  5. package/lib/access-control.d.ts +7 -8
  6. package/lib/access-control.d.ts.map +1 -1
  7. package/lib/access-control.js +5 -0
  8. package/lib/access-control.js.map +1 -1
  9. package/lib/analytics.d.ts +6 -7
  10. package/lib/analytics.d.ts.map +1 -1
  11. package/lib/api-contract/components.generated.json +1389 -45
  12. package/lib/api-schemas/access-control.d.ts +33 -10
  13. package/lib/api-schemas/access-control.d.ts.map +1 -1
  14. package/lib/api-schemas/access-control.js +7 -6
  15. package/lib/api-schemas/access-control.js.map +1 -1
  16. package/lib/api-schemas/account.d.ts +5 -4
  17. package/lib/api-schemas/account.d.ts.map +1 -1
  18. package/lib/api-schemas/account.js.map +1 -1
  19. package/lib/api-schemas/agent-budget.d.ts +15 -0
  20. package/lib/api-schemas/agent-budget.d.ts.map +1 -0
  21. package/lib/api-schemas/agent-budget.js +55 -0
  22. package/lib/api-schemas/agent-budget.js.map +1 -0
  23. package/lib/api-schemas/agent-runs.d.ts +1525 -100
  24. package/lib/api-schemas/agent-runs.d.ts.map +1 -1
  25. package/lib/api-schemas/agent-runs.js +60 -28
  26. package/lib/api-schemas/agent-runs.js.map +1 -1
  27. package/lib/api-schemas/apikey.d.ts +11 -10
  28. package/lib/api-schemas/apikey.d.ts.map +1 -1
  29. package/lib/api-schemas/apikey.js.map +1 -1
  30. package/lib/api-schemas/app-lifecycle.d.ts +13 -0
  31. package/lib/api-schemas/app-lifecycle.d.ts.map +1 -1
  32. package/lib/api-schemas/app-lifecycle.js +4 -0
  33. package/lib/api-schemas/app-lifecycle.js.map +1 -1
  34. package/lib/api-schemas/app-runtime.d.ts +1821 -108
  35. package/lib/api-schemas/app-runtime.d.ts.map +1 -1
  36. package/lib/api-schemas/audit-trail.d.ts +20 -0
  37. package/lib/api-schemas/audit-trail.d.ts.map +1 -1
  38. package/lib/api-schemas/audit-trail.js +7 -1
  39. package/lib/api-schemas/audit-trail.js.map +1 -1
  40. package/lib/api-schemas/content.d.ts +665 -30
  41. package/lib/api-schemas/content.d.ts.map +1 -1
  42. package/lib/api-schemas/content.js +47 -0
  43. package/lib/api-schemas/content.js.map +1 -1
  44. package/lib/api-schemas/cost-analytics.d.ts +18 -0
  45. package/lib/api-schemas/cost-analytics.d.ts.map +1 -1
  46. package/lib/api-schemas/cost-analytics.js +31 -2
  47. package/lib/api-schemas/cost-analytics.js.map +1 -1
  48. package/lib/api-schemas/document-processing.d.ts +381 -18
  49. package/lib/api-schemas/document-processing.d.ts.map +1 -1
  50. package/lib/api-schemas/environment.d.ts +0 -5
  51. package/lib/api-schemas/environment.d.ts.map +1 -1
  52. package/lib/api-schemas/environment.js +0 -1
  53. package/lib/api-schemas/environment.js.map +1 -1
  54. package/lib/api-schemas/events.d.ts +1143 -54
  55. package/lib/api-schemas/events.d.ts.map +1 -1
  56. package/lib/api-schemas/group.d.ts +2 -1
  57. package/lib/api-schemas/group.d.ts.map +1 -1
  58. package/lib/api-schemas/group.js.map +1 -1
  59. package/lib/api-schemas/index.d.ts +1 -0
  60. package/lib/api-schemas/index.d.ts.map +1 -1
  61. package/lib/api-schemas/index.js +1 -0
  62. package/lib/api-schemas/index.js.map +1 -1
  63. package/lib/api-schemas/inference-profile.d.ts +5017 -0
  64. package/lib/api-schemas/inference-profile.d.ts.map +1 -0
  65. package/lib/api-schemas/inference-profile.js +135 -0
  66. package/lib/api-schemas/inference-profile.js.map +1 -0
  67. package/lib/api-schemas/integrations.d.ts +6 -6
  68. package/lib/api-schemas/interaction.d.ts +34391 -703
  69. package/lib/api-schemas/interaction.d.ts.map +1 -1
  70. package/lib/api-schemas/interaction.js +34 -1
  71. package/lib/api-schemas/interaction.js.map +1 -1
  72. package/lib/api-schemas/invites.d.ts +10 -9
  73. package/lib/api-schemas/invites.d.ts.map +1 -1
  74. package/lib/api-schemas/invites.js.map +1 -1
  75. package/lib/api-schemas/process.d.ts +653 -34
  76. package/lib/api-schemas/process.d.ts.map +1 -1
  77. package/lib/api-schemas/process.js +66 -0
  78. package/lib/api-schemas/process.js.map +1 -1
  79. package/lib/api-schemas/project-configuration.d.ts +1323 -62
  80. package/lib/api-schemas/project-configuration.d.ts.map +1 -1
  81. package/lib/api-schemas/project-configuration.js +15 -1
  82. package/lib/api-schemas/project-configuration.js.map +1 -1
  83. package/lib/api-schemas/project.d.ts +2031 -116
  84. package/lib/api-schemas/project.d.ts.map +1 -1
  85. package/lib/api-schemas/project.js +9 -1
  86. package/lib/api-schemas/project.js.map +1 -1
  87. package/lib/api-schemas/quota.d.ts +7 -6
  88. package/lib/api-schemas/quota.d.ts.map +1 -1
  89. package/lib/api-schemas/quota.js.map +1 -1
  90. package/lib/api-schemas/registry.d.ts +27820 -35892
  91. package/lib/api-schemas/registry.d.ts.map +1 -1
  92. package/lib/api-schemas/registry.js +55 -5
  93. package/lib/api-schemas/registry.js.map +1 -1
  94. package/lib/api-schemas/run-budget.d.ts +52 -0
  95. package/lib/api-schemas/run-budget.d.ts.map +1 -0
  96. package/lib/api-schemas/run-budget.js +55 -0
  97. package/lib/api-schemas/run-budget.js.map +1 -0
  98. package/lib/api-schemas/store.d.ts +6388 -338
  99. package/lib/api-schemas/store.d.ts.map +1 -1
  100. package/lib/api-schemas/store.js +11 -0
  101. package/lib/api-schemas/store.js.map +1 -1
  102. package/lib/api-schemas/user.d.ts +9 -8
  103. package/lib/api-schemas/user.d.ts.map +1 -1
  104. package/lib/api-schemas/user.js.map +1 -1
  105. package/lib/api-schemas/view-execution.d.ts +8 -0
  106. package/lib/api-schemas/view-execution.d.ts.map +1 -1
  107. package/lib/api-schemas/views.d.ts +14 -0
  108. package/lib/api-schemas/views.d.ts.map +1 -1
  109. package/lib/api-schemas/workflow-runs.d.ts +335 -12
  110. package/lib/api-schemas/workflow-runs.d.ts.map +1 -1
  111. package/lib/api-schemas/workflow-runs.js +2 -0
  112. package/lib/api-schemas/workflow-runs.js.map +1 -1
  113. package/lib/apikey.d.ts +30 -25
  114. package/lib/apikey.d.ts.map +1 -1
  115. package/lib/apikey.js.map +1 -1
  116. package/lib/apps.d.ts +116 -121
  117. package/lib/apps.d.ts.map +1 -1
  118. package/lib/apps.js.map +1 -1
  119. package/lib/audit-trail.d.ts +17 -18
  120. package/lib/audit-trail.d.ts.map +1 -1
  121. package/lib/audit-trail.js +2 -0
  122. package/lib/audit-trail.js.map +1 -1
  123. package/lib/browser-credentials.d.ts +11 -12
  124. package/lib/browser-credentials.d.ts.map +1 -1
  125. package/lib/common.d.ts +17 -24
  126. package/lib/common.d.ts.map +1 -1
  127. package/lib/content-query.d.ts +3 -4
  128. package/lib/content-query.d.ts.map +1 -1
  129. package/lib/cost-analytics.d.ts +13 -21
  130. package/lib/cost-analytics.d.ts.map +1 -1
  131. package/lib/cost-analytics.js +0 -7
  132. package/lib/cost-analytics.js.map +1 -1
  133. package/lib/data-platform.d.ts +79 -88
  134. package/lib/data-platform.d.ts.map +1 -1
  135. package/lib/data-platform.js.map +1 -1
  136. package/lib/delegation.d.ts +4 -5
  137. package/lib/delegation.d.ts.map +1 -1
  138. package/lib/email.d.ts +15 -17
  139. package/lib/email.d.ts.map +1 -1
  140. package/lib/email.js.map +1 -1
  141. package/lib/embeddings.d.ts +25 -26
  142. package/lib/embeddings.d.ts.map +1 -1
  143. package/lib/environment.d.ts +16 -17
  144. package/lib/environment.d.ts.map +1 -1
  145. package/lib/environment.js.map +1 -1
  146. package/lib/facets.d.ts +3 -4
  147. package/lib/facets.d.ts.map +1 -1
  148. package/lib/group.d.ts +6 -7
  149. package/lib/group.d.ts.map +1 -1
  150. package/lib/group.js.map +1 -1
  151. package/lib/index.d.ts +3 -1
  152. package/lib/index.d.ts.map +1 -1
  153. package/lib/index.js.map +1 -1
  154. package/lib/inference-profile.d.ts +17 -0
  155. package/lib/inference-profile.d.ts.map +1 -0
  156. package/lib/inference-profile.js +2 -0
  157. package/lib/inference-profile.js.map +1 -0
  158. package/lib/integrations.d.ts +19 -20
  159. package/lib/integrations.d.ts.map +1 -1
  160. package/lib/integrations.js.map +1 -1
  161. package/lib/interaction.d.ts +68 -73
  162. package/lib/interaction.d.ts.map +1 -1
  163. package/lib/interaction.js.map +1 -1
  164. package/lib/meters.d.ts +4 -5
  165. package/lib/meters.d.ts.map +1 -1
  166. package/lib/oauth-server.d.ts +40 -41
  167. package/lib/oauth-server.d.ts.map +1 -1
  168. package/lib/oauth.d.ts +9 -10
  169. package/lib/oauth.d.ts.map +1 -1
  170. package/lib/payload.d.ts +11 -14
  171. package/lib/payload.d.ts.map +1 -1
  172. package/lib/pending-asks.d.ts +8 -13
  173. package/lib/pending-asks.d.ts.map +1 -1
  174. package/lib/pending-asks.js +0 -4
  175. package/lib/pending-asks.js.map +1 -1
  176. package/lib/platform-event.d.ts +48 -51
  177. package/lib/platform-event.d.ts.map +1 -1
  178. package/lib/platform-event.js.map +1 -1
  179. package/lib/principal-context.d.ts +3 -3
  180. package/lib/principal-context.d.ts.map +1 -1
  181. package/lib/project.d.ts +42 -43
  182. package/lib/project.d.ts.map +1 -1
  183. package/lib/project.js.map +1 -1
  184. package/lib/prompt.d.ts +14 -16
  185. package/lib/prompt.d.ts.map +1 -1
  186. package/lib/prompt.js.map +1 -1
  187. package/lib/query.d.ts +10 -13
  188. package/lib/query.d.ts.map +1 -1
  189. package/lib/rate-limiter.d.ts +7 -11
  190. package/lib/rate-limiter.d.ts.map +1 -1
  191. package/lib/refs.d.ts +2 -3
  192. package/lib/refs.d.ts.map +1 -1
  193. package/lib/refs.js.map +1 -1
  194. package/lib/roles/types.d.ts +5 -6
  195. package/lib/roles/types.d.ts.map +1 -1
  196. package/lib/roles/types.js.map +1 -1
  197. package/lib/run-budget.d.ts +8 -0
  198. package/lib/run-budget.d.ts.map +1 -0
  199. package/lib/run-budget.js +2 -0
  200. package/lib/run-budget.js.map +1 -0
  201. package/lib/runs.d.ts +9 -10
  202. package/lib/runs.d.ts.map +1 -1
  203. package/lib/secrets.d.ts +20 -21
  204. package/lib/secrets.d.ts.map +1 -1
  205. package/lib/store/agent-approval.d.ts +4 -5
  206. package/lib/store/agent-approval.d.ts.map +1 -1
  207. package/lib/store/agent-approval.js.map +1 -1
  208. package/lib/store/agent-run.d.ts +50 -52
  209. package/lib/store/agent-run.d.ts.map +1 -1
  210. package/lib/store/agent-run.js.map +1 -1
  211. package/lib/store/collections.d.ts +11 -12
  212. package/lib/store/collections.d.ts.map +1 -1
  213. package/lib/store/collections.js.map +1 -1
  214. package/lib/store/conversation-state.d.ts +14 -8
  215. package/lib/store/conversation-state.d.ts.map +1 -1
  216. package/lib/store/doc-analyzer.d.ts +7 -8
  217. package/lib/store/doc-analyzer.d.ts.map +1 -1
  218. package/lib/store/dsl-workflow.d.ts +10 -12
  219. package/lib/store/dsl-workflow.d.ts.map +1 -1
  220. package/lib/store/dsl-workflow.js.map +1 -1
  221. package/lib/store/duration.d.ts +12 -0
  222. package/lib/store/duration.d.ts.map +1 -0
  223. package/lib/store/duration.js +2 -0
  224. package/lib/store/duration.js.map +1 -0
  225. package/lib/store/grounded-extraction.d.ts +6 -7
  226. package/lib/store/grounded-extraction.d.ts.map +1 -1
  227. package/lib/store/intake-policy-schema.generated.d.ts.map +1 -1
  228. package/lib/store/intake-policy-schema.generated.js +143 -2
  229. package/lib/store/intake-policy-schema.generated.js.map +1 -1
  230. package/lib/store/process.d.ts +70 -69
  231. package/lib/store/process.d.ts.map +1 -1
  232. package/lib/store/process.js.map +1 -1
  233. package/lib/store/rendering.d.ts +6 -12
  234. package/lib/store/rendering.d.ts.map +1 -1
  235. package/lib/store/rendering.js +0 -5
  236. package/lib/store/rendering.js.map +1 -1
  237. package/lib/store/signals.d.ts +43 -0
  238. package/lib/store/signals.d.ts.map +1 -1
  239. package/lib/store/signals.js +6 -1
  240. package/lib/store/signals.js.map +1 -1
  241. package/lib/store/store.d.ts +92 -91
  242. package/lib/store/store.d.ts.map +1 -1
  243. package/lib/store/store.js.map +1 -1
  244. package/lib/store/task.d.ts +10 -14
  245. package/lib/store/task.d.ts.map +1 -1
  246. package/lib/store/workflow.d.ts +35 -41
  247. package/lib/store/workflow.d.ts.map +1 -1
  248. package/lib/store/workflow.js.map +1 -1
  249. package/lib/sts-token-types.d.ts +14 -19
  250. package/lib/sts-token-types.d.ts.map +1 -1
  251. package/lib/tools.d.ts +12 -13
  252. package/lib/tools.d.ts.map +1 -1
  253. package/lib/transient-tokens.d.ts +3 -3
  254. package/lib/transient-tokens.d.ts.map +1 -1
  255. package/lib/user.d.ts +17 -20
  256. package/lib/user.d.ts.map +1 -1
  257. package/lib/user.js.map +1 -1
  258. package/lib/vertesia-common.js +2 -2
  259. package/lib/vertesia-common.js.map +1 -1
  260. package/lib/views.d.ts +61 -64
  261. package/lib/views.d.ts.map +1 -1
  262. package/lib/views.js.map +1 -1
  263. package/lib/wire-types.generated.d.ts +11231 -0
  264. package/lib/wire-types.generated.d.ts.map +1 -0
  265. package/lib/wire-types.generated.js +4 -0
  266. package/lib/wire-types.generated.js.map +1 -0
  267. package/lib/workflow-analytics.d.ts +21 -19
  268. package/lib/workflow-analytics.d.ts.map +1 -1
  269. package/lib/workflow-analytics.js +2 -2
  270. package/lib/workflow-analytics.js.map +1 -1
  271. package/package.json +15 -10
  272. package/src/access-control-values.ts +2 -2
  273. package/src/access-control.ts +7 -15
  274. package/src/analytics.ts +6 -13
  275. package/src/api-contract/components.generated.json +1389 -45
  276. package/src/api-schemas/access-control.ts +18 -16
  277. package/src/api-schemas/account.ts +5 -4
  278. package/src/api-schemas/agent-budget.ts +60 -0
  279. package/src/api-schemas/agent-runs.ts +63 -27
  280. package/src/api-schemas/apikey.ts +11 -10
  281. package/src/api-schemas/app-lifecycle.ts +5 -0
  282. package/src/api-schemas/audit-trail.ts +7 -1
  283. package/src/api-schemas/content.ts +55 -0
  284. package/src/api-schemas/cost-analytics.ts +34 -2
  285. package/src/api-schemas/environment.ts +0 -1
  286. package/src/api-schemas/group.ts +2 -1
  287. package/src/api-schemas/index.ts +1 -0
  288. package/src/api-schemas/inference-profile.ts +151 -0
  289. package/src/api-schemas/interaction.ts +40 -1
  290. package/src/api-schemas/invites.ts +10 -9
  291. package/src/api-schemas/process.ts +78 -2
  292. package/src/api-schemas/project-configuration.ts +19 -1
  293. package/src/api-schemas/project.ts +19 -10
  294. package/src/api-schemas/quota.ts +7 -6
  295. package/src/api-schemas/registry.ts +131 -33
  296. package/src/api-schemas/run-budget.ts +60 -0
  297. package/src/api-schemas/store.ts +12 -0
  298. package/src/api-schemas/user.ts +9 -8
  299. package/src/api-schemas/workflow-runs.ts +2 -0
  300. package/src/apikey.ts +30 -39
  301. package/src/apps.ts +116 -239
  302. package/src/audit-trail.ts +18 -33
  303. package/src/browser-credentials.ts +11 -23
  304. package/src/common.ts +17 -37
  305. package/src/content-query.ts +3 -4
  306. package/src/cost-analytics.ts +13 -35
  307. package/src/data-platform.ts +79 -168
  308. package/src/delegation.ts +4 -9
  309. package/src/email.ts +15 -29
  310. package/src/embeddings.ts +25 -51
  311. package/src/environment.ts +16 -33
  312. package/src/facets.ts +3 -4
  313. package/src/group.ts +6 -13
  314. package/src/index.ts +27 -0
  315. package/src/inference-profile.ts +20 -0
  316. package/src/integrations.ts +21 -41
  317. package/src/interaction.ts +68 -137
  318. package/src/meters.ts +4 -9
  319. package/src/oauth-server.ts +40 -81
  320. package/src/oauth.ts +9 -19
  321. package/src/payload.ts +11 -25
  322. package/src/pending-asks.ts +8 -22
  323. package/src/platform-event.ts +48 -97
  324. package/src/principal-context.ts +3 -3
  325. package/src/project.ts +43 -86
  326. package/src/prompt.ts +14 -31
  327. package/src/query.ts +10 -20
  328. package/src/rate-limiter.ts +7 -19
  329. package/src/refs.ts +2 -3
  330. package/src/roles/types.ts +5 -11
  331. package/src/run-budget.ts +8 -0
  332. package/src/runs.ts +9 -19
  333. package/src/secrets.ts +20 -41
  334. package/src/store/agent-approval.ts +4 -9
  335. package/src/store/agent-run.ts +53 -99
  336. package/src/store/collections.ts +11 -23
  337. package/src/store/conversation-state.ts +15 -15
  338. package/src/store/doc-analyzer.ts +7 -15
  339. package/src/store/dsl-workflow.ts +10 -23
  340. package/src/store/duration.ts +45 -0
  341. package/src/store/grounded-extraction.ts +6 -13
  342. package/src/store/intake-policy-schema.generated.ts +148 -2
  343. package/src/store/process.ts +70 -140
  344. package/src/store/rendering.ts +6 -19
  345. package/src/store/signals.ts +48 -0
  346. package/src/store/store.ts +92 -181
  347. package/src/store/task.ts +10 -24
  348. package/src/store/workflow.ts +35 -71
  349. package/src/sts-token-types.ts +14 -33
  350. package/src/tools.ts +12 -25
  351. package/src/transient-tokens.ts +3 -3
  352. package/src/user.ts +17 -39
  353. package/src/views.ts +61 -125
  354. package/src/wire-types.generated.ts +11889 -0
  355. package/src/workflow-analytics.ts +21 -19
  356. package/src/agent-resources.test.ts +0 -89
  357. package/src/api-contract/components.contract.test.ts +0 -99
  358. package/src/api-schemas/access-control.contract.test.ts +0 -209
  359. package/src/api-schemas/account-apikey.test.ts +0 -60
  360. package/src/api-schemas/account.contract.test.ts +0 -319
  361. package/src/api-schemas/adapter-edge-cases.test.ts +0 -499
  362. package/src/api-schemas/agent-communication.contract.test.ts +0 -90
  363. package/src/api-schemas/agent-history.contract.test.ts +0 -42
  364. package/src/api-schemas/agent-runs.contract.test.ts +0 -240
  365. package/src/api-schemas/api-discriminators.test.ts +0 -185
  366. package/src/api-schemas/apikey.contract.test.ts +0 -270
  367. package/src/api-schemas/app-delete-summary.contract.test.ts +0 -67
  368. package/src/api-schemas/bulk-operation.contract.test.ts +0 -39
  369. package/src/api-schemas/bundle-isolation.test.ts +0 -44
  370. package/src/api-schemas/commands.contract.test.ts +0 -51
  371. package/src/api-schemas/cost-analytics.contract.test.ts +0 -64
  372. package/src/api-schemas/dashboard.contract.test.ts +0 -138
  373. package/src/api-schemas/data-store.contract.test.ts +0 -97
  374. package/src/api-schemas/document-processing.contract.test.ts +0 -76
  375. package/src/api-schemas/emit-json-schema.test.ts +0 -36
  376. package/src/api-schemas/environment.contract.test.ts +0 -202
  377. package/src/api-schemas/group.contract.test.ts +0 -205
  378. package/src/api-schemas/indexing.contract.test.ts +0 -122
  379. package/src/api-schemas/interaction.contract.test.ts +0 -307
  380. package/src/api-schemas/invites.contract.test.ts +0 -268
  381. package/src/api-schemas/llumiverse.contract.test.ts +0 -179
  382. package/src/api-schemas/mcp-api-key.contract.test.ts +0 -125
  383. package/src/api-schemas/oauth.contract.test.ts +0 -181
  384. package/src/api-schemas/parameters.test.ts +0 -402
  385. package/src/api-schemas/process.contract.test.ts +0 -115
  386. package/src/api-schemas/project.contract.test.ts +0 -472
  387. package/src/api-schemas/pruning-limits.test.ts +0 -189
  388. package/src/api-schemas/quota.contract.test.ts +0 -147
  389. package/src/api-schemas/registry-groups.test.ts +0 -99
  390. package/src/api-schemas/response-pruning.test.ts +0 -260
  391. package/src/api-schemas/store.contract.test.ts +0 -378
  392. package/src/api-schemas/sts.contract.test.ts +0 -112
  393. package/src/api-schemas/user.contract.test.ts +0 -197
  394. package/src/api-schemas/views.contract.test.ts +0 -112
  395. package/src/api-schemas/zeno-response-contracts.test.ts +0 -380
  396. package/src/apps.test.ts +0 -89
  397. package/src/oauth-scopes.test.ts +0 -15
  398. package/src/roles.test.ts +0 -33
  399. package/src/schema-for-extraction.test.ts +0 -191
  400. package/src/store/agent-approval.test.ts +0 -18
  401. package/src/store/content-type-editing.test.ts +0 -17
  402. package/src/store/ms.d.ts +0 -42
  403. package/src/store/schedule.test.ts +0 -59
  404. package/src/store/workflow.test.ts +0 -640
  405. package/src/versions.test.ts +0 -13
@@ -1,205 +0,0 @@
1
- import { Ajv2020 } from 'ajv/dist/2020.js';
2
- import { describe, expect, it } from 'vitest';
3
- import type { CreateUserGroupPayload, UpdateUserGroupPayload, UserGroup } from '../group.js';
4
- import type { User, UserRef } from '../user.js';
5
- import type { JsonObject } from './adapter.js';
6
- import type { UserGroupArrayFromSchema } from './group.js';
7
- import { ApiSchemaComponents, apiComponentRef, validateApiRequest, validateApiResponse } from './registry.js';
8
- import type { UserRefArrayFromSchema } from './user.js';
9
-
10
- /** Exact type identity — `extends` in both directions is too weak (any/unknown slip through). */
11
- type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
12
- function assertType<T extends true>(_ok: T): void {}
13
-
14
- function compile(name: string, components: Readonly<Record<string, JsonObject>> = ApiSchemaComponents) {
15
- const ajv = new Ajv2020({ strictSchema: false, allErrors: true });
16
- ajv.addSchema({ $id: 'vertesia://openapi', components: { schemas: components } });
17
- return ajv.compile({ $ref: `vertesia://openapi${apiComponentRef(name as never)}` });
18
- }
19
-
20
- const VALID_GROUP = {
21
- id: 'g1',
22
- account: 'a1',
23
- name: 'Engineering',
24
- tags: ['eng'],
25
- created_at: '2026-07-30T10:00:00.000Z',
26
- updated_at: '2026-07-30T10:00:00.000Z',
27
- };
28
-
29
- const VALID_REF = { id: 'u1', name: 'Someone', email: 'someone@acme.com' };
30
-
31
- describe('gate 1 — the schema is the single source of truth for the public group types', () => {
32
- it('publishes the exact schema-derived type, not a hand-written twin', () => {
33
- assertType<Equals<UserGroupArrayFromSchema, UserGroup[]>>(true);
34
- assertType<Equals<UserRefArrayFromSchema, UserRef[]>>(true);
35
- expect(true).toBe(true);
36
- });
37
-
38
- it('types the timestamps as the strings a client actually receives', () => {
39
- // They were `Date` on the public type while the document published `format: date-time`
40
- // strings. JSON has no date type, so the old declaration described the Mongoose document
41
- // rather than the response — this is the correction, and the reason it is a compile-time
42
- // break for anyone who was calling `.getTime()` on one.
43
- assertType<Equals<UserGroup['created_at'], string>>(true);
44
- assertType<Equals<UserGroup['updated_at'], string>>(true);
45
- assertType<Equals<UserGroup['tags'], string[]>>(true);
46
- assertType<Equals<UserGroup['allowed_projects'], string[] | undefined>>(true);
47
- expect(true).toBe(true);
48
- });
49
-
50
- it('derives UserRef from User rather than restating four fields', () => {
51
- // `.pick()` on UserSchema, so a change to how `User` declares one of these follows through
52
- // instead of leaving a twin behind. The requiredness comes with it: `email` is required on
53
- // both, which is why the members listing has to map rather than serialize.
54
- assertType<Equals<UserRef['id'], User['id']>>(true);
55
- assertType<Equals<UserRef['name'], User['name']>>(true);
56
- assertType<Equals<UserRef['email'], User['email']>>(true);
57
- assertType<Equals<UserRef['picture'], User['picture']>>(true);
58
- // And nothing else came across.
59
- assertType<Equals<keyof UserRef, 'id' | 'name' | 'email' | 'picture'>>(true);
60
- expect(true).toBe(true);
61
- });
62
-
63
- it('derives both payloads from the group rather than restating its fields', () => {
64
- // Same reasoning as UserRef, applied to the write side: each payload is a subset of the
65
- // group, so the field types follow the response. Only requiredness differs, and only where
66
- // it should — `tags` is required on a group the server always populates and optional in a
67
- // payload the caller need not send.
68
- assertType<Equals<CreateUserGroupPayload['name'], UserGroup['name']>>(true);
69
- assertType<Equals<CreateUserGroupPayload['description'], UserGroup['description']>>(true);
70
- assertType<Equals<CreateUserGroupPayload['tags'], string[] | undefined>>(true);
71
- assertType<Equals<keyof CreateUserGroupPayload, 'name' | 'description' | 'tags' | 'allowed_projects'>>(true);
72
- assertType<Equals<UpdateUserGroupPayload['properties'], UserGroup['properties']>>(true);
73
- assertType<Equals<UpdateUserGroupPayload['clearance'], UserGroup['clearance']>>(true);
74
- assertType<Equals<UpdateUserGroupPayload['compartments'], UserGroup['compartments']>>(true);
75
- // The whitelist is what the pick leaves out: nothing server-owned is writable.
76
- assertType<
77
- Equals<
78
- keyof UpdateUserGroupPayload,
79
- 'name' | 'description' | 'tags' | 'properties' | 'clearance' | 'compartments' | 'allowed_projects'
80
- >
81
- >(true);
82
- expect(true).toBe(true);
83
- });
84
- });
85
-
86
- describe('gate 2 — the published components match the closure the types come from', () => {
87
- it('does not declare members on the group component', () => {
88
- // Three handlers were shipping `members` — two by populating a `select: false` path, one by
89
- // returning the in-memory document — while the component is closed and has never declared
90
- // it. Members are published by their own route as UserRef[].
91
- expect(Object.keys(ApiSchemaComponents.UserGroup.properties as JsonObject)).not.toContain('members');
92
- expect(ApiSchemaComponents.UserGroup.additionalProperties).toBe(false);
93
- });
94
-
95
- it('publishes UserRef as its own component, not a $ref back to User', () => {
96
- // `.pick()` drops the `id: 'User'` metadata, which is what keeps the projection a separate
97
- // component. If it carried the id across, every UserRef slot would suddenly promise a whole
98
- // User to generated clients.
99
- expect(JSON.stringify(ApiSchemaComponents.UserRef)).not.toContain('$ref');
100
- expect(ApiSchemaComponents.UserRef.required).toEqual(['id', 'name', 'email']);
101
- expect(ApiSchemaComponents.UserRefArray).toEqual({
102
- type: 'array',
103
- items: { $ref: '#/components/schemas/UserRef' },
104
- });
105
- });
106
-
107
- it('keeps the timestamps enforceable rather than merely documented', () => {
108
- const props = ApiSchemaComponents.UserGroup.properties as Record<string, JsonObject>;
109
- expect(props.created_at).toEqual({ type: 'string', format: 'date-time' });
110
- expect(ApiSchemaComponents.UserGroup.required).toEqual([
111
- 'id',
112
- 'account',
113
- 'name',
114
- 'tags',
115
- 'created_at',
116
- 'updated_at',
117
- ]);
118
- });
119
- });
120
-
121
- describe('gate 3 — AJV validates the same canonical objects that are published', () => {
122
- it('accepts a minimal group and rejects a missing required field', () => {
123
- const validate = compile('UserGroup');
124
- expect(validate(VALID_GROUP)).toBe(true);
125
- const { tags: _dropped, ...incomplete } = VALID_GROUP;
126
- expect(validate(incomplete)).toBe(false);
127
- });
128
-
129
- it('rejects the internal fields a serialized document would have leaked', () => {
130
- const validate = compile('UserGroup');
131
- expect(validate({ ...VALID_GROUP, members: ['u1'] })).toBe(false);
132
- expect(validate({ ...VALID_GROUP, _id: 'deadbeef' })).toBe(false);
133
- expect(validate({ ...VALID_GROUP, __v: 0 })).toBe(false);
134
- });
135
-
136
- it('requires a name on the update payload, which both handlers checked by hand', () => {
137
- const validate = compile('UpdateUserGroupPayload');
138
- expect(validate({ name: 'Renamed' })).toBe(true);
139
- expect(validate({})).toBe(false);
140
- expect(validate({ name: 'Renamed', rogue_field: 1 })).toBe(false);
141
- });
142
-
143
- it('accepts a create payload with only a name', () => {
144
- const validate = compile('CreateUserGroupPayload');
145
- expect(validate({ name: 'Engineering' })).toBe(true);
146
- expect(validate({ name: 'Engineering', allowed_projects: [] })).toBe(true);
147
- // `properties` and `clearance` are updatable but not settable at creation, and never were.
148
- expect(validate({ name: 'Engineering', clearance: 3 })).toBe(false);
149
- });
150
-
151
- it('documents allowed_projects for the request rather than inheriting the response text', () => {
152
- // The one field where picking is not enough: the response explains what an empty list MEANS,
153
- // the request explains what sending one DOES. Overriding the picked field is how a payload
154
- // keeps request-specific documentation — and the same mechanism a field with genuinely
155
- // different request semantics would need.
156
- const create = (ApiSchemaComponents.CreateUserGroupPayload.properties as Record<string, JsonObject>)
157
- .allowed_projects;
158
- const group = (ApiSchemaComponents.UserGroup.properties as Record<string, JsonObject>).allowed_projects;
159
- expect(create.description).toBe('Restrict the new group to the given projects (empty/absent = org-wide).');
160
- expect(create.description).not.toBe(group.description);
161
- // Everything except the description still comes from the group.
162
- expect({ ...create, description: undefined }).toEqual({ ...group, description: undefined });
163
- });
164
- });
165
-
166
- describe('gate 4 — runtime enforcement uses the published components', () => {
167
- it('enforces the date-time format the timestamps claim', () => {
168
- // Through the registry rather than the local `compile` helper: the production validator
169
- // registers ajv-formats, and a bare Ajv2020 ignores `format` entirely.
170
- expect(validateApiResponse('UserGroup', { ...VALID_GROUP, created_at: 'yesterday' }).valid).toBe(false);
171
- expect(validateApiResponse('UserGroup', VALID_GROUP).valid).toBe(true);
172
- });
173
-
174
- it('rejects an undeclared update field without removing it', () => {
175
- const payload: Record<string, unknown> = { name: 'Acme', rogue_field: 42 };
176
- const result = validateApiRequest('UpdateUserGroupPayload', payload);
177
- expect(result.valid).toBe(false);
178
- expect(payload.rogue_field).toBe(42);
179
- });
180
-
181
- it('checks every member of the group listing against the same UserGroup component', () => {
182
- expect(validateApiResponse('UserGroupArray', [VALID_GROUP, VALID_GROUP]).valid).toBe(true);
183
- expect(validateApiResponse('UserGroupArray', []).valid).toBe(true);
184
- // One group still carrying its members is what the unmapped listing would have produced.
185
- expect(validateApiResponse('UserGroupArray', [VALID_GROUP, { ...VALID_GROUP, members: [] }]).valid).toBe(false);
186
- });
187
-
188
- it('checks every member of the members listing against UserRef', () => {
189
- expect(validateApiResponse('UserRefArray', [VALID_REF]).valid).toBe(true);
190
- // A user Mongo holds with no email — required on the wire, which is why the handler maps.
191
- const { email: _dropped, ...withoutEmail } = VALID_REF;
192
- expect(validateApiResponse('UserRefArray', [withoutEmail]).valid).toBe(false);
193
- expect(validateApiResponse('UserRefArray', [{ ...VALID_REF, email: '' }]).valid).toBe(true);
194
- // And the whole user document, which is what serializing the populated doc would send.
195
- expect(validateApiResponse('UserRefArray', [{ ...VALID_REF, clearance: 3 }]).valid).toBe(false);
196
- });
197
-
198
- it('hands back the component type on the valid branch', () => {
199
- const result = validateApiResponse('UserGroup', VALID_GROUP);
200
- expect(result.valid).toBe(true);
201
- if (result.valid) {
202
- assertType<Equals<typeof result.data, UserGroup>>(true);
203
- }
204
- });
205
- });
@@ -1,122 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import type { GenericCommandResponse } from '../common.js';
3
- import type { RecalculateEmbeddingsQuery } from '../embeddings.js';
4
- import type {
5
- DriftAnalysisStatusResponse,
6
- EmbeddingsStatusResponse,
7
- IndexingStatusResponse,
8
- ProjectConfigurationEmbeddingEnablePayload,
9
- ReindexAgentRunsPayload,
10
- ReindexAgentRunsResponse,
11
- StartProjectReindexPayload,
12
- } from '../project.js';
13
- import { WorkflowExecutionStatus } from '../store/workflow.js';
14
- import type { GenericCommandResponseSchema } from './commands.js';
15
- import type {
16
- EmbeddingsStatusResponseSchema,
17
- ProjectConfigurationEmbeddingEnablePayloadSchema,
18
- RecalculateEmbeddingsQuerySchema,
19
- } from './embeddings.js';
20
- import type {
21
- DriftAnalysisStatusResponseSchema,
22
- IndexingStatusResponseSchema,
23
- ReindexAgentRunsPayloadSchema,
24
- ReindexAgentRunsResponseSchema,
25
- StartProjectReindexPayloadSchema,
26
- } from './indexing.js';
27
- import { validateApiRequest, validateApiResponse } from './registry.js';
28
-
29
- type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
30
- function assertType<T extends true>(_value: T): void {}
31
-
32
- describe('indexing and embedding API contracts', () => {
33
- it('derives every public type from its domain schema', () => {
34
- assertType<Equals<GenericCommandResponse, typeof GenericCommandResponseSchema._output>>(true);
35
- assertType<Equals<EmbeddingsStatusResponse, typeof EmbeddingsStatusResponseSchema._output>>(true);
36
- assertType<Equals<RecalculateEmbeddingsQuery, typeof RecalculateEmbeddingsQuerySchema._output>>(true);
37
- assertType<Equals<IndexingStatusResponse, typeof IndexingStatusResponseSchema._output>>(true);
38
- assertType<Equals<DriftAnalysisStatusResponse, typeof DriftAnalysisStatusResponseSchema._output>>(true);
39
- assertType<
40
- Equals<
41
- ProjectConfigurationEmbeddingEnablePayload,
42
- typeof ProjectConfigurationEmbeddingEnablePayloadSchema._output
43
- >
44
- >(true);
45
- assertType<Equals<StartProjectReindexPayload, typeof StartProjectReindexPayloadSchema._output>>(true);
46
- assertType<Equals<ReindexAgentRunsPayload, typeof ReindexAgentRunsPayloadSchema._output>>(true);
47
- assertType<Equals<ReindexAgentRunsResponse, typeof ReindexAgentRunsResponseSchema._output>>(true);
48
- });
49
-
50
- it('rejects undeclared request fields while allowing both optional reindex bodies', () => {
51
- expect(validateApiRequest('StartProjectReindexPayload', undefined).valid).toBe(false);
52
- expect(validateApiRequest('StartProjectReindexPayload', {}).valid).toBe(true);
53
- expect(validateApiRequest('StartProjectReindexPayload', { unexpected: true }).valid).toBe(false);
54
- expect(validateApiRequest('ReindexAgentRunsPayload', {}).valid).toBe(true);
55
- expect(validateApiRequest('ReindexAgentRunsPayload', { recreate_index: true, unexpected: true }).valid).toBe(
56
- false,
57
- );
58
- });
59
-
60
- it('allows only the explicit synchronous embedding recalculation override', () => {
61
- expect(validateApiRequest('RecalculateEmbeddingsQuery', {}).valid).toBe(true);
62
- expect(validateApiRequest('RecalculateEmbeddingsQuery', { mode: 'sync' }).valid).toBe(true);
63
- expect(validateApiRequest('RecalculateEmbeddingsQuery', { force: true }).valid).toBe(true);
64
- expect(validateApiRequest('RecalculateEmbeddingsQuery', { mode: 'sync', force: true }).valid).toBe(true);
65
- expect(validateApiRequest('RecalculateEmbeddingsQuery', { force_renditions: true }).valid).toBe(false);
66
- expect(validateApiRequest('RecalculateEmbeddingsQuery', { mode: 'batch' }).valid).toBe(false);
67
- });
68
-
69
- it('validates the optional batch summary without exposing stored run fields', () => {
70
- const summary = {
71
- id: 'run-1',
72
- state: 'completed_with_errors',
73
- model: 'model-1',
74
- created_at: '2026-01-01T00:00:00Z',
75
- applied: 110,
76
- skipped: 17,
77
- failed: 0,
78
- stale: 0,
79
- };
80
- expect(
81
- validateApiResponse('EmbeddingsStatusResponse', {
82
- status: 'success',
83
- vectorIndex: { status: 'READY' },
84
- latestBatchRun: summary,
85
- }).valid,
86
- ).toBe(true);
87
- expect(validateApiResponse('EmbeddingBatchRunSummary', { ...summary, applied: -1 }).valid).toBe(false);
88
- expect(validateApiResponse('EmbeddingBatchRunSummary', { ...summary, prefix_uri: 'private' }).valid).toBe(
89
- false,
90
- );
91
- });
92
-
93
- it('keeps drift workflow status numeric and nullable identifiers explicit', () => {
94
- expect(
95
- validateApiResponse('DriftAnalysisStatusResponse', {
96
- workflow_id: null,
97
- workflow_run_id: null,
98
- status: WorkflowExecutionStatus.UNKNOWN,
99
- }).valid,
100
- ).toBe(true);
101
- expect(
102
- validateApiResponse('DriftAnalysisStatusResponse', {
103
- workflow_id: null,
104
- workflow_run_id: null,
105
- status: 'NOT_FOUND',
106
- }).valid,
107
- ).toBe(false);
108
- });
109
-
110
- it('validates command and embedding responses against the published components', () => {
111
- expect(validateApiResponse('GenericCommandResponse', { status: 'ok', message: 'done' }).valid).toBe(true);
112
- expect(
113
- validateApiResponse('GenericCommandResponse', { status: 'ok', message: 'done', extra: true }).valid,
114
- ).toBe(false);
115
- expect(
116
- validateApiResponse('EmbeddingsStatusResponse', {
117
- status: 'success',
118
- vectorIndex: { status: 'READY' },
119
- }).valid,
120
- ).toBe(true);
121
- });
122
- });
@@ -1,307 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import type { AsyncConversationExecutionPayload } from '../interaction.js';
3
- import {
4
- AsyncConversationExecutionPayloadSchema,
5
- ComputeRunFacetPayloadSchema,
6
- ComputeRunFacetsResponseSchema,
7
- ConversationStateSchema,
8
- ExecutionRunRefSchema,
9
- FindRunResultSchema,
10
- InCodeInteractionSchema,
11
- InteractionCreatePayloadSchema,
12
- InteractionPromptSegmentInputSchema,
13
- InteractionSchema,
14
- InteractionUpdatePayloadSchema,
15
- PromptSegmentDefSchema,
16
- ResolvedCatalogInteractionSchema,
17
- RunClonePayloadSchema,
18
- } from './interaction.js';
19
- import { validateApiRequest } from './registry.js';
20
-
21
- describe('conversation state contract', () => {
22
- it('publishes the tool catalog storage scope used to resolve tool references', () => {
23
- expect(ConversationStateSchema.shape.tool_catalog_storage_id.safeParse('process-run-1').success).toBe(true);
24
- });
25
- });
26
-
27
- describe('in-code interaction contract', () => {
28
- it('retains prompt schemas when resolving a catalog interaction', () => {
29
- const interaction = InCodeInteractionSchema.parse({
30
- type: 'sys',
31
- id: 'sys:GeneralAgent',
32
- name: 'GeneralAgent',
33
- title: 'General Agent',
34
- tags: ['agent'],
35
- agent_runner_options: { is_agent: true, request_template: '{{user_prompt}}' },
36
- prompts: [
37
- {
38
- role: 'user',
39
- content: '{{user_prompt}}',
40
- content_type: 'handlebars',
41
- schema: {
42
- type: 'object',
43
- properties: { user_prompt: { type: 'string', editor: 'textarea' } },
44
- },
45
- },
46
- ],
47
- });
48
-
49
- expect(interaction.prompts[0]?.schema).toMatchObject({
50
- properties: { user_prompt: { type: 'string' } },
51
- });
52
- });
53
-
54
- it('requires normalized title and tags only on the resolved response', () => {
55
- const authoringShape = {
56
- type: 'sys',
57
- id: 'sys:Untitled',
58
- name: 'Untitled',
59
- prompts: [],
60
- };
61
-
62
- expect(InCodeInteractionSchema.safeParse(authoringShape).success).toBe(true);
63
- expect(ResolvedCatalogInteractionSchema.safeParse(authoringShape).success).toBe(false);
64
- expect(
65
- ResolvedCatalogInteractionSchema.safeParse({ ...authoringShape, title: 'Untitled', tags: [] }).success,
66
- ).toBe(true);
67
- });
68
- });
69
-
70
- describe('AsyncConversationExecutionPayload contract', () => {
71
- it('accepts caller-provided metadata and enrichment controls', () => {
72
- const payload: AsyncConversationExecutionPayload = {
73
- type: 'conversation',
74
- interaction: 'sys:AppTester',
75
- title: 'Manual title',
76
- topic: 'Manual topic',
77
- generate_topic: false,
78
- generate_lessons: false,
79
- };
80
-
81
- expect(AsyncConversationExecutionPayloadSchema.parse(payload)).toMatchObject(payload);
82
- });
83
-
84
- it('retains an immutable app-version execution target', () => {
85
- const payload: AsyncConversationExecutionPayload = {
86
- type: 'conversation',
87
- interaction: 'sys:AppTester',
88
- app_version: '20260804T022611971Z',
89
- };
90
-
91
- expect(AsyncConversationExecutionPayloadSchema.parse(payload)).toMatchObject({
92
- app_version: '20260804T022611971Z',
93
- });
94
- });
95
-
96
- it('accepts Process-authored agent execution policy', () => {
97
- const payload: AsyncConversationExecutionPayload = {
98
- type: 'conversation',
99
- interaction: 'sys:AppDeveloper',
100
- agent_policy: {
101
- phases: [
102
- {
103
- id: 'saved',
104
- tools: ['app_workspace_save'],
105
- tool_input_contains: [{ field: 'mode', contains: 'commit' }],
106
- recovery_prompt: 'Save before finishing.',
107
- },
108
- ],
109
- phase_resets: [{ tools: ['app_workspace_edit'], to_phase: 'saved' }],
110
- action_phase_count: 1,
111
- action_phase_max_tokens: 4_096,
112
- completion_prompt: 'Return the structured result now.',
113
- },
114
- };
115
-
116
- expect(AsyncConversationExecutionPayloadSchema.parse(payload)).toMatchObject(payload);
117
- });
118
-
119
- it('rejects a non-string app-version target', () => {
120
- expect(() =>
121
- AsyncConversationExecutionPayloadSchema.parse({
122
- type: 'conversation',
123
- interaction: 'sys:AppTester',
124
- app_version: 42,
125
- }),
126
- ).toThrow();
127
- });
128
- });
129
-
130
- describe('run facet contracts', () => {
131
- const facets = [
132
- { name: 'environments', field: 'environment' },
133
- { name: 'interactions', field: 'interaction' },
134
- { name: 'models', field: 'modelId' },
135
- { name: 'statuses', field: 'status' },
136
- { name: 'finish_reason', field: 'finish_reason' },
137
- ];
138
-
139
- it('accepts exactly the supported run facet pairs', () => {
140
- expect(ComputeRunFacetPayloadSchema.parse({ facets })).toEqual({ facets });
141
- });
142
-
143
- it.each(['tags', 'created_by', 'start', 'end'])('rejects the removed %s facet', (field) => {
144
- expect(ComputeRunFacetPayloadSchema.safeParse({ facets: [{ name: field, field }] }).success).toBe(false);
145
- });
146
-
147
- it('rejects mismatched and additional facet names', () => {
148
- expect(ComputeRunFacetPayloadSchema.safeParse({ facets: [{ name: 'models', field: 'status' }] }).success).toBe(
149
- false,
150
- );
151
- expect(ComputeRunFacetPayloadSchema.safeParse({ facets: [{ name: 'custom', field: 'modelId' }] }).success).toBe(
152
- false,
153
- );
154
- });
155
-
156
- it('keeps removed facet fields available as query filters', () => {
157
- const query = {
158
- tags: ['visible'],
159
- created_by: 'user:123',
160
- start: '2026-08-01T00:00:00.000Z',
161
- end: '2026-08-02T00:00:00.000Z',
162
- };
163
-
164
- expect(ComputeRunFacetPayloadSchema.parse({ facets: [], query })).toEqual({ facets: [], query });
165
- });
166
-
167
- it('rejects removed and custom response facets', () => {
168
- expect(ComputeRunFacetsResponseSchema.safeParse({ tags: [] }).success).toBe(false);
169
- expect(ComputeRunFacetsResponseSchema.safeParse({ custom: [] }).success).toBe(false);
170
- });
171
- });
172
-
173
- describe('run response contracts', () => {
174
- it('retains an environment ID when a run references a deleted environment', () => {
175
- expect(ExecutionRunRefSchema.shape.environment.parse('env-deleted')).toBe('env-deleted');
176
- expect(ExecutionRunRefSchema.shape.environment.parse(null)).toBeNull();
177
- });
178
-
179
- it('models the arbitrary stored-field projection returned by /runs/find', () => {
180
- expect(
181
- FindRunResultSchema.parse({
182
- id: 'run-1',
183
- environment: 'env-1',
184
- account: 'account-1',
185
- project: 'project-1',
186
- interaction: 'interaction-1',
187
- result: [],
188
- parameters: { query: 'test' },
189
- }),
190
- ).toMatchObject({ environment: 'env-1', account: 'account-1', project: 'project-1' });
191
- });
192
-
193
- it('does not publish run persistence-only fields', () => {
194
- expect(() => FindRunResultSchema.parse({ interaction_code: 'sys:Example' })).toThrow();
195
- expect(() => FindRunResultSchema.parse({ tmp_prompt: [] })).toThrow();
196
- });
197
-
198
- it('models enriched supported run facet buckets', () => {
199
- expect(
200
- ComputeRunFacetsResponseSchema.parse({
201
- environments: [{ _id: 'env-1', count: 2, name: 'Default' }],
202
- interactions: [{ _id: 'interaction-1', count: 1, name: 'Example', status: 'published', version: 3 }],
203
- models: [{ _id: 'gpt', count: 2 }],
204
- total: 2,
205
- }),
206
- ).toMatchObject({ total: 2 });
207
- });
208
- });
209
-
210
- describe('interaction contracts', () => {
211
- const populatedPrompt = {
212
- role: 'user',
213
- content: 'Hello',
214
- content_type: 'text',
215
- id: 'prompt-1',
216
- name: 'Greeting',
217
- status: 'draft',
218
- version: 1,
219
- project: 'project-1',
220
- created_by: 'user-1',
221
- updated_by: 'user-1',
222
- created_at: '2026-08-20T00:00:00.000Z',
223
- updated_at: '2026-08-20T00:00:00.000Z',
224
- };
225
-
226
- it('accepts the media-result storage setting on interaction payloads and responses', () => {
227
- expect(InteractionSchema.shape.store_media_results.parse(true)).toBe(true);
228
- expect(InteractionCreatePayloadSchema.shape.store_media_results.parse(false)).toBe(false);
229
- expect(InteractionUpdatePayloadSchema.shape.store_media_results.parse(true)).toBe(true);
230
- });
231
-
232
- it('keeps legacy populated prompts valid in interaction write payloads', () => {
233
- const segment = { type: 'template', template: populatedPrompt };
234
-
235
- expect(InteractionPromptSegmentInputSchema.safeParse(segment).success).toBe(true);
236
- expect(
237
- InteractionPromptSegmentInputSchema.safeParse({
238
- ...segment,
239
- template: { ...populatedPrompt, edit_revision: 3 },
240
- }).success,
241
- ).toBe(true);
242
- });
243
-
244
- it('still requires edit revisions on populated prompts returned by the API', () => {
245
- const segment = { type: 'template', template: populatedPrompt };
246
-
247
- expect(PromptSegmentDefSchema.safeParse(segment).success).toBe(false);
248
- expect(
249
- PromptSegmentDefSchema.safeParse({
250
- ...segment,
251
- template: { ...populatedPrompt, edit_revision: 3 },
252
- }).success,
253
- ).toBe(true);
254
- });
255
- });
256
-
257
- describe('user message payload contract', () => {
258
- const base = {
259
- run: { id: 'run-1', account: 'acc-1', project: 'proj-1' },
260
- environment: 'env-1',
261
- options: { model: 'model-1' },
262
- tools: [],
263
- message: 'Search the other collection instead.',
264
- };
265
-
266
- it('accepts tool results owed to the model alongside the message', () => {
267
- // A stop or an approval denial can leave results undelivered. They have to travel with
268
- // the message that resumes the conversation: the payload is strict, so before `results`
269
- // existed here the server rejected them and the work was silently dropped.
270
- const result = validateApiRequest('UserMessagePayload', {
271
- ...base,
272
- results: [{ tool_use_id: 'search-1', content: 'found 3 docs', is_error: false }],
273
- });
274
-
275
- expect(result.valid).toBe(true);
276
- });
277
-
278
- it('still accepts a message with no owed results', () => {
279
- expect(validateApiRequest('UserMessagePayload', base).valid).toBe(true);
280
- });
281
-
282
- it('stays closed to undeclared fields', () => {
283
- expect(validateApiRequest('UserMessagePayload', { ...base, unsupported: true }).valid).toBe(false);
284
- });
285
- });
286
-
287
- describe('inference workflow attribution', () => {
288
- it('keeps required clone workflow identifiers free of execution deprecation metadata', () => {
289
- const workflow = RunClonePayloadSchema.shape.workflow.shape;
290
- expect(workflow.run_id.meta()?.deprecated).toBeUndefined();
291
- expect(workflow.workflow_id.meta()?.deprecated).toBeUndefined();
292
- });
293
- it('accepts root agent attribution on execution and clone requests', () => {
294
- const workflow = { run_id: 'child-run', workflow_id: 'workstream:parent:child', agent_run_id: 'root-agent' };
295
- expect(validateApiRequest('ExecutionRunWorkflow', workflow).valid).toBe(true);
296
- expect(validateApiRequest('RunClonePayload', { source_run_id: 'source', workflow }).valid).toBe(true);
297
- expect(
298
- validateApiRequest('ExecutionRunWorkflow', { run_id: 'legacy', workflow_id: 'AgentRun:legacy' }).valid,
299
- ).toBe(true);
300
- });
301
- });
302
-
303
- describe('background inference telemetry contract', () => {
304
- it('accepts the background call type in the generated runtime contract', () => {
305
- expect(validateApiRequest('LlmCallType', 'background').valid).toBe(true);
306
- });
307
- });