@kindgi/api 0.1.4-rc.5 → 0.1.5-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/dist/agent-binding.d.ts +13 -0
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts.map +1 -1
  4. package/dist/agent-pins.js +18 -2
  5. package/dist/agent-pins.js.map +1 -1
  6. package/dist/app.d.ts +110 -17
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +163 -35
  9. package/dist/app.js.map +1 -1
  10. package/dist/block-publish.d.ts +56 -0
  11. package/dist/block-publish.d.ts.map +1 -0
  12. package/dist/block-publish.js +132 -0
  13. package/dist/block-publish.js.map +1 -0
  14. package/dist/caller.d.ts +24 -0
  15. package/dist/caller.d.ts.map +1 -0
  16. package/dist/caller.js +47 -0
  17. package/dist/caller.js.map +1 -0
  18. package/dist/capability-binding.d.ts +11 -0
  19. package/dist/capability-binding.d.ts.map +1 -1
  20. package/dist/derive-agent-version.d.ts +7 -0
  21. package/dist/derive-agent-version.d.ts.map +1 -1
  22. package/dist/derive-agent-version.js +4 -0
  23. package/dist/derive-agent-version.js.map +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +73 -7
  26. package/dist/errors.js.map +1 -1
  27. package/dist/eval-case-binding.d.ts +16 -4
  28. package/dist/eval-case-binding.d.ts.map +1 -1
  29. package/dist/eval-run-binding.d.ts +31 -0
  30. package/dist/eval-run-binding.d.ts.map +1 -1
  31. package/dist/eval-run-dispatcher.d.ts +7 -0
  32. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  33. package/dist/eval-run-dispatcher.js.map +1 -1
  34. package/dist/eval-sample.d.ts +11 -0
  35. package/dist/eval-sample.d.ts.map +1 -0
  36. package/dist/eval-sample.js +34 -0
  37. package/dist/eval-sample.js.map +1 -0
  38. package/dist/eval-suite-binding.d.ts +13 -0
  39. package/dist/eval-suite-binding.d.ts.map +1 -1
  40. package/dist/eval-suite-binding.js.map +1 -1
  41. package/dist/flow-binding.d.ts +18 -0
  42. package/dist/flow-binding.d.ts.map +1 -1
  43. package/dist/flow-pins.d.ts.map +1 -1
  44. package/dist/flow-pins.js +18 -2
  45. package/dist/flow-pins.js.map +1 -1
  46. package/dist/gate.d.ts.map +1 -1
  47. package/dist/gate.js +25 -0
  48. package/dist/gate.js.map +1 -1
  49. package/dist/handler-binding.d.ts +32 -0
  50. package/dist/handler-binding.d.ts.map +1 -1
  51. package/dist/hitl-binding.d.ts +23 -0
  52. package/dist/hitl-binding.d.ts.map +1 -1
  53. package/dist/identity-directory-binding.d.ts +82 -4
  54. package/dist/identity-directory-binding.d.ts.map +1 -1
  55. package/dist/identity-provider-binding.d.ts +197 -17
  56. package/dist/identity-provider-binding.d.ts.map +1 -1
  57. package/dist/improvement-pass-binding.d.ts +196 -0
  58. package/dist/improvement-pass-binding.d.ts.map +1 -0
  59. package/dist/improvement-pass-binding.js +9 -0
  60. package/dist/improvement-pass-binding.js.map +1 -0
  61. package/dist/index.d.ts +35 -17
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +11 -3
  64. package/dist/index.js.map +1 -1
  65. package/dist/judged-dispatcher.d.ts +25 -4
  66. package/dist/judged-dispatcher.d.ts.map +1 -1
  67. package/dist/judged-dispatcher.js +43 -6
  68. package/dist/judged-dispatcher.js.map +1 -1
  69. package/dist/judgment-binding.d.ts +25 -1
  70. package/dist/judgment-binding.d.ts.map +1 -1
  71. package/dist/mcp-endpoint-binding.d.ts +7 -0
  72. package/dist/mcp-endpoint-binding.d.ts.map +1 -1
  73. package/dist/memory-binding.d.ts +124 -17
  74. package/dist/memory-binding.d.ts.map +1 -1
  75. package/dist/memory-erasure-binding.d.ts +145 -0
  76. package/dist/memory-erasure-binding.d.ts.map +1 -0
  77. package/dist/memory-erasure-binding.js +4 -0
  78. package/dist/memory-erasure-binding.js.map +1 -0
  79. package/dist/middleware/auth.d.ts +66 -13
  80. package/dist/middleware/auth.d.ts.map +1 -1
  81. package/dist/middleware/auth.js +150 -50
  82. package/dist/middleware/auth.js.map +1 -1
  83. package/dist/middleware/authorize.d.ts +6 -0
  84. package/dist/middleware/authorize.d.ts.map +1 -1
  85. package/dist/middleware/authorize.js +113 -4
  86. package/dist/middleware/authorize.js.map +1 -1
  87. package/dist/middleware/error-mapper.d.ts +5 -0
  88. package/dist/middleware/error-mapper.d.ts.map +1 -1
  89. package/dist/middleware/error-mapper.js +14 -1
  90. package/dist/middleware/error-mapper.js.map +1 -1
  91. package/dist/middleware/idempotency.d.ts +70 -5
  92. package/dist/middleware/idempotency.d.ts.map +1 -1
  93. package/dist/middleware/idempotency.js +174 -41
  94. package/dist/middleware/idempotency.js.map +1 -1
  95. package/dist/middleware/key-project.d.ts +17 -0
  96. package/dist/middleware/key-project.d.ts.map +1 -0
  97. package/dist/middleware/key-project.js +75 -0
  98. package/dist/middleware/key-project.js.map +1 -0
  99. package/dist/middleware/principal.d.ts.map +1 -1
  100. package/dist/middleware/principal.js +9 -5
  101. package/dist/middleware/principal.js.map +1 -1
  102. package/dist/middleware/project-ref.d.ts.map +1 -1
  103. package/dist/middleware/project-ref.js +3 -0
  104. package/dist/middleware/project-ref.js.map +1 -1
  105. package/dist/openapi/generate.d.ts.map +1 -1
  106. package/dist/openapi/generate.js +5 -2
  107. package/dist/openapi/generate.js.map +1 -1
  108. package/dist/openapi/operations.d.ts.map +1 -1
  109. package/dist/openapi/operations.js +918 -139
  110. package/dist/openapi/operations.js.map +1 -1
  111. package/dist/openapi/schemas.d.ts +92 -13
  112. package/dist/openapi/schemas.d.ts.map +1 -1
  113. package/dist/openapi/schemas.js +2122 -370
  114. package/dist/openapi/schemas.js.map +1 -1
  115. package/dist/person-grants-binding.d.ts +77 -0
  116. package/dist/person-grants-binding.d.ts.map +1 -0
  117. package/dist/person-grants-binding.js +4 -0
  118. package/dist/person-grants-binding.js.map +1 -0
  119. package/dist/proposal-service.d.ts +121 -0
  120. package/dist/proposal-service.d.ts.map +1 -0
  121. package/dist/proposal-service.js +447 -0
  122. package/dist/proposal-service.js.map +1 -0
  123. package/dist/proposal-status.d.ts +60 -0
  124. package/dist/proposal-status.d.ts.map +1 -0
  125. package/dist/proposal-status.js +109 -0
  126. package/dist/proposal-status.js.map +1 -0
  127. package/dist/provider-binding.d.ts +10 -0
  128. package/dist/provider-binding.d.ts.map +1 -1
  129. package/dist/publish-refused.d.ts +18 -3
  130. package/dist/publish-refused.d.ts.map +1 -1
  131. package/dist/publish-refused.js +18 -3
  132. package/dist/publish-refused.js.map +1 -1
  133. package/dist/routes/adapters.d.ts +2 -1
  134. package/dist/routes/adapters.d.ts.map +1 -1
  135. package/dist/routes/adapters.js +3 -1
  136. package/dist/routes/adapters.js.map +1 -1
  137. package/dist/routes/agent-releases.d.ts +55 -3
  138. package/dist/routes/agent-releases.d.ts.map +1 -1
  139. package/dist/routes/agent-releases.js +85 -55
  140. package/dist/routes/agent-releases.js.map +1 -1
  141. package/dist/routes/agents.d.ts +12 -1
  142. package/dist/routes/agents.d.ts.map +1 -1
  143. package/dist/routes/agents.js +100 -2
  144. package/dist/routes/agents.js.map +1 -1
  145. package/dist/routes/approvals.d.ts +15 -3
  146. package/dist/routes/approvals.d.ts.map +1 -1
  147. package/dist/routes/approvals.js +133 -122
  148. package/dist/routes/approvals.js.map +1 -1
  149. package/dist/routes/artifacts.d.ts +25 -3
  150. package/dist/routes/artifacts.d.ts.map +1 -1
  151. package/dist/routes/artifacts.js +116 -7
  152. package/dist/routes/artifacts.js.map +1 -1
  153. package/dist/routes/auth.d.ts +25 -1
  154. package/dist/routes/auth.d.ts.map +1 -1
  155. package/dist/routes/auth.js +655 -281
  156. package/dist/routes/auth.js.map +1 -1
  157. package/dist/routes/blocks.d.ts.map +1 -1
  158. package/dist/routes/blocks.js +2 -42
  159. package/dist/routes/blocks.js.map +1 -1
  160. package/dist/routes/capabilities.d.ts +2 -1
  161. package/dist/routes/capabilities.d.ts.map +1 -1
  162. package/dist/routes/capabilities.js +6 -1
  163. package/dist/routes/capabilities.js.map +1 -1
  164. package/dist/routes/compliance.d.ts +9 -10
  165. package/dist/routes/compliance.d.ts.map +1 -1
  166. package/dist/routes/compliance.js +42 -61
  167. package/dist/routes/compliance.js.map +1 -1
  168. package/dist/routes/conversations.d.ts +8 -1
  169. package/dist/routes/conversations.d.ts.map +1 -1
  170. package/dist/routes/conversations.js +87 -8
  171. package/dist/routes/conversations.js.map +1 -1
  172. package/dist/routes/cost.d.ts +7 -1
  173. package/dist/routes/cost.d.ts.map +1 -1
  174. package/dist/routes/cost.js +22 -3
  175. package/dist/routes/cost.js.map +1 -1
  176. package/dist/routes/denied.d.ts +11 -0
  177. package/dist/routes/denied.d.ts.map +1 -0
  178. package/dist/routes/denied.js +17 -0
  179. package/dist/routes/denied.js.map +1 -0
  180. package/dist/routes/deployments.d.ts +2 -1
  181. package/dist/routes/deployments.d.ts.map +1 -1
  182. package/dist/routes/deployments.js +44 -12
  183. package/dist/routes/deployments.js.map +1 -1
  184. package/dist/routes/eval-comparison.d.ts.map +1 -1
  185. package/dist/routes/eval-comparison.js +69 -1
  186. package/dist/routes/eval-comparison.js.map +1 -1
  187. package/dist/routes/eval-overrides.d.ts +18 -0
  188. package/dist/routes/eval-overrides.d.ts.map +1 -0
  189. package/dist/routes/eval-overrides.js +81 -0
  190. package/dist/routes/eval-overrides.js.map +1 -0
  191. package/dist/routes/eval-runs.d.ts +10 -1
  192. package/dist/routes/eval-runs.d.ts.map +1 -1
  193. package/dist/routes/eval-runs.js +63 -7
  194. package/dist/routes/eval-runs.js.map +1 -1
  195. package/dist/routes/eval-suites.d.ts.map +1 -1
  196. package/dist/routes/eval-suites.js +20 -1
  197. package/dist/routes/eval-suites.js.map +1 -1
  198. package/dist/routes/event-triggers.d.ts +5 -1
  199. package/dist/routes/event-triggers.d.ts.map +1 -1
  200. package/dist/routes/event-triggers.js +26 -3
  201. package/dist/routes/event-triggers.js.map +1 -1
  202. package/dist/routes/export-signing-keys.d.ts +12 -0
  203. package/dist/routes/export-signing-keys.d.ts.map +1 -0
  204. package/dist/routes/export-signing-keys.js +24 -0
  205. package/dist/routes/export-signing-keys.js.map +1 -0
  206. package/dist/routes/flows.d.ts.map +1 -1
  207. package/dist/routes/flows.js +9 -1
  208. package/dist/routes/flows.js.map +1 -1
  209. package/dist/routes/gate-policies.d.ts +4 -1
  210. package/dist/routes/gate-policies.d.ts.map +1 -1
  211. package/dist/routes/gate-policies.js +29 -5
  212. package/dist/routes/gate-policies.js.map +1 -1
  213. package/dist/routes/guardrails.d.ts +16 -14
  214. package/dist/routes/guardrails.d.ts.map +1 -1
  215. package/dist/routes/guardrails.js +39 -3
  216. package/dist/routes/guardrails.js.map +1 -1
  217. package/dist/routes/identity.d.ts +20 -4
  218. package/dist/routes/identity.d.ts.map +1 -1
  219. package/dist/routes/identity.js +246 -6
  220. package/dist/routes/identity.js.map +1 -1
  221. package/dist/routes/improvement-passes.d.ts +52 -0
  222. package/dist/routes/improvement-passes.d.ts.map +1 -0
  223. package/dist/routes/improvement-passes.js +449 -0
  224. package/dist/routes/improvement-passes.js.map +1 -0
  225. package/dist/routes/judged-suites.d.ts +50 -0
  226. package/dist/routes/judged-suites.d.ts.map +1 -1
  227. package/dist/routes/judged-suites.js +66 -27
  228. package/dist/routes/judged-suites.js.map +1 -1
  229. package/dist/routes/judgment-context.d.ts +18 -2
  230. package/dist/routes/judgment-context.d.ts.map +1 -1
  231. package/dist/routes/judgment-context.js +63 -5
  232. package/dist/routes/judgment-context.js.map +1 -1
  233. package/dist/routes/judgment-flow-context.d.ts.map +1 -1
  234. package/dist/routes/judgment-flow-context.js +14 -2
  235. package/dist/routes/judgment-flow-context.js.map +1 -1
  236. package/dist/routes/judgments.d.ts.map +1 -1
  237. package/dist/routes/judgments.js +8 -1
  238. package/dist/routes/judgments.js.map +1 -1
  239. package/dist/routes/mcp.d.ts.map +1 -1
  240. package/dist/routes/mcp.js +26 -1
  241. package/dist/routes/mcp.js.map +1 -1
  242. package/dist/routes/memory-access.d.ts +43 -0
  243. package/dist/routes/memory-access.d.ts.map +1 -0
  244. package/dist/routes/memory-access.js +129 -0
  245. package/dist/routes/memory-access.js.map +1 -0
  246. package/dist/routes/memory-erasures.d.ts +25 -0
  247. package/dist/routes/memory-erasures.d.ts.map +1 -0
  248. package/dist/routes/memory-erasures.js +214 -0
  249. package/dist/routes/memory-erasures.js.map +1 -0
  250. package/dist/routes/memory-parse.d.ts +38 -0
  251. package/dist/routes/memory-parse.d.ts.map +1 -0
  252. package/dist/routes/memory-parse.js +199 -0
  253. package/dist/routes/memory-parse.js.map +1 -0
  254. package/dist/routes/memory.d.ts +9 -4
  255. package/dist/routes/memory.d.ts.map +1 -1
  256. package/dist/routes/memory.js +226 -234
  257. package/dist/routes/memory.js.map +1 -1
  258. package/dist/routes/observations.d.ts +4 -1
  259. package/dist/routes/observations.d.ts.map +1 -1
  260. package/dist/routes/observations.js +8 -2
  261. package/dist/routes/observations.js.map +1 -1
  262. package/dist/routes/pagination.d.ts +7 -0
  263. package/dist/routes/pagination.d.ts.map +1 -1
  264. package/dist/routes/pagination.js +10 -0
  265. package/dist/routes/pagination.js.map +1 -1
  266. package/dist/routes/policies.d.ts +2 -1
  267. package/dist/routes/policies.d.ts.map +1 -1
  268. package/dist/routes/policies.js +3 -1
  269. package/dist/routes/policies.js.map +1 -1
  270. package/dist/routes/project-mismatch.d.ts +22 -0
  271. package/dist/routes/project-mismatch.d.ts.map +1 -0
  272. package/dist/routes/project-mismatch.js +34 -0
  273. package/dist/routes/project-mismatch.js.map +1 -0
  274. package/dist/routes/projects.d.ts +15 -4
  275. package/dist/routes/projects.d.ts.map +1 -1
  276. package/dist/routes/projects.js +100 -9
  277. package/dist/routes/projects.js.map +1 -1
  278. package/dist/routes/proposals.d.ts +25 -17
  279. package/dist/routes/proposals.d.ts.map +1 -1
  280. package/dist/routes/proposals.js +340 -507
  281. package/dist/routes/proposals.js.map +1 -1
  282. package/dist/routes/provenance.d.ts +17 -3
  283. package/dist/routes/provenance.d.ts.map +1 -1
  284. package/dist/routes/provenance.js +79 -103
  285. package/dist/routes/provenance.js.map +1 -1
  286. package/dist/routes/providers.d.ts +17 -1
  287. package/dist/routes/providers.d.ts.map +1 -1
  288. package/dist/routes/providers.js +188 -8
  289. package/dist/routes/providers.js.map +1 -1
  290. package/dist/routes/public-run-tokens.d.ts.map +1 -1
  291. package/dist/routes/public-run-tokens.js +3 -0
  292. package/dist/routes/public-run-tokens.js.map +1 -1
  293. package/dist/routes/runs.d.ts +10 -0
  294. package/dist/routes/runs.d.ts.map +1 -1
  295. package/dist/routes/runs.js +92 -42
  296. package/dist/routes/runs.js.map +1 -1
  297. package/dist/routes/schedules.d.ts +21 -13
  298. package/dist/routes/schedules.d.ts.map +1 -1
  299. package/dist/routes/schedules.js +416 -55
  300. package/dist/routes/schedules.js.map +1 -1
  301. package/dist/routes/segments.d.ts +2 -0
  302. package/dist/routes/segments.d.ts.map +1 -1
  303. package/dist/routes/segments.js +5 -0
  304. package/dist/routes/segments.js.map +1 -1
  305. package/dist/routes/service-accounts.d.ts +17 -0
  306. package/dist/routes/service-accounts.d.ts.map +1 -0
  307. package/dist/routes/service-accounts.js +212 -0
  308. package/dist/routes/service-accounts.js.map +1 -0
  309. package/dist/routes/sign-in-options.d.ts +50 -0
  310. package/dist/routes/sign-in-options.d.ts.map +1 -0
  311. package/dist/routes/sign-in-options.js +98 -0
  312. package/dist/routes/sign-in-options.js.map +1 -0
  313. package/dist/routes/signing-keys.d.ts +2 -1
  314. package/dist/routes/signing-keys.d.ts.map +1 -1
  315. package/dist/routes/signing-keys.js +3 -1
  316. package/dist/routes/signing-keys.js.map +1 -1
  317. package/dist/routes/tenant-access.d.ts +13 -0
  318. package/dist/routes/tenant-access.d.ts.map +1 -0
  319. package/dist/routes/tenant-access.js +26 -0
  320. package/dist/routes/tenant-access.js.map +1 -0
  321. package/dist/routes/tenant.d.ts.map +1 -1
  322. package/dist/routes/tenant.js +4 -0
  323. package/dist/routes/tenant.js.map +1 -1
  324. package/dist/routes/token-sign-in.d.ts +36 -0
  325. package/dist/routes/token-sign-in.d.ts.map +1 -0
  326. package/dist/routes/token-sign-in.js +101 -0
  327. package/dist/routes/token-sign-in.js.map +1 -0
  328. package/dist/routes/tokens.d.ts +15 -5
  329. package/dist/routes/tokens.d.ts.map +1 -1
  330. package/dist/routes/tokens.js +162 -43
  331. package/dist/routes/tokens.js.map +1 -1
  332. package/dist/routes/tools.d.ts.map +1 -1
  333. package/dist/routes/tools.js +9 -1
  334. package/dist/routes/tools.js.map +1 -1
  335. package/dist/routes/trigger-access.d.ts +29 -0
  336. package/dist/routes/trigger-access.d.ts.map +1 -0
  337. package/dist/routes/trigger-access.js +33 -0
  338. package/dist/routes/trigger-access.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +2 -1
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -1
  341. package/dist/routes/webhook-endpoints.js +11 -3
  342. package/dist/routes/webhook-endpoints.js.map +1 -1
  343. package/dist/routes/webhooks.d.ts +5 -1
  344. package/dist/routes/webhooks.d.ts.map +1 -1
  345. package/dist/routes/webhooks.js +25 -2
  346. package/dist/routes/webhooks.js.map +1 -1
  347. package/dist/run-failure.d.ts +21 -0
  348. package/dist/run-failure.d.ts.map +1 -0
  349. package/dist/run-failure.js +29 -0
  350. package/dist/run-failure.js.map +1 -0
  351. package/dist/service-account-binding.d.ts +108 -0
  352. package/dist/service-account-binding.d.ts.map +1 -0
  353. package/dist/service-account-binding.js +4 -0
  354. package/dist/service-account-binding.js.map +1 -0
  355. package/dist/session-store-binding.d.ts +61 -13
  356. package/dist/session-store-binding.d.ts.map +1 -1
  357. package/dist/signed-export.d.ts +89 -0
  358. package/dist/signed-export.d.ts.map +1 -0
  359. package/dist/signed-export.js +149 -0
  360. package/dist/signed-export.js.map +1 -0
  361. package/dist/supervisor-binding.d.ts +186 -413
  362. package/dist/supervisor-binding.d.ts.map +1 -1
  363. package/dist/testing/app-bindings.d.ts +33 -0
  364. package/dist/testing/app-bindings.d.ts.map +1 -0
  365. package/dist/testing/app-bindings.js +112 -0
  366. package/dist/testing/app-bindings.js.map +1 -0
  367. package/dist/testing/index.d.ts +11 -0
  368. package/dist/testing/index.d.ts.map +1 -0
  369. package/dist/testing/index.js +13 -0
  370. package/dist/testing/index.js.map +1 -0
  371. package/dist/testing/stub-binding.d.ts +34 -0
  372. package/dist/testing/stub-binding.d.ts.map +1 -0
  373. package/dist/testing/stub-binding.js +42 -0
  374. package/dist/testing/stub-binding.js.map +1 -0
  375. package/dist/testing/trigger-registry.d.ts +21 -0
  376. package/dist/testing/trigger-registry.d.ts.map +1 -0
  377. package/dist/testing/trigger-registry.js +206 -0
  378. package/dist/testing/trigger-registry.js.map +1 -0
  379. package/dist/token-admin.d.ts +46 -8
  380. package/dist/token-admin.d.ts.map +1 -1
  381. package/dist/token-admin.js.map +1 -1
  382. package/dist/tool-binding.d.ts +13 -0
  383. package/dist/tool-binding.d.ts.map +1 -1
  384. package/dist/trigger-binding.d.ts +2 -2
  385. package/dist/trigger-binding.d.ts.map +1 -1
  386. package/dist/trigger-binding.js +1 -1
  387. package/dist/trigger-binding.js.map +1 -1
  388. package/dist/types.d.ts +16 -0
  389. package/dist/types.d.ts.map +1 -1
  390. package/dist/webhook-endpoint-binding.d.ts +19 -3
  391. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  392. package/dist/webhook-endpoint-binding.js +1 -1
  393. package/dist/webhook-endpoint-binding.js.map +1 -1
  394. package/openapi.json +15286 -8653
  395. package/package.json +26 -22
  396. package/src/agent-binding.ts +14 -0
  397. package/src/agent-pins.ts +18 -2
  398. package/src/app.ts +366 -80
  399. package/src/block-publish.ts +181 -0
  400. package/src/caller.ts +62 -0
  401. package/src/capability-binding.ts +12 -0
  402. package/src/derive-agent-version.ts +9 -1
  403. package/src/errors.ts +73 -7
  404. package/src/eval-case-binding.ts +17 -1
  405. package/src/eval-run-binding.ts +31 -0
  406. package/src/eval-run-dispatcher.ts +7 -0
  407. package/src/eval-sample.ts +42 -0
  408. package/src/eval-suite-binding.ts +14 -0
  409. package/src/flow-binding.ts +19 -0
  410. package/src/flow-pins.ts +18 -2
  411. package/src/gate.ts +26 -0
  412. package/src/handler-binding.ts +36 -1
  413. package/src/hitl-binding.ts +24 -0
  414. package/src/identity-directory-binding.ts +85 -4
  415. package/src/identity-provider-binding.ts +216 -21
  416. package/src/improvement-pass-binding.ts +193 -0
  417. package/src/index.ts +153 -31
  418. package/src/judged-dispatcher.ts +78 -11
  419. package/src/judgment-binding.ts +25 -1
  420. package/src/mcp-endpoint-binding.ts +7 -0
  421. package/src/memory-binding.ts +121 -17
  422. package/src/memory-erasure-binding.ts +156 -0
  423. package/src/middleware/auth.ts +228 -62
  424. package/src/middleware/authorize.ts +139 -3
  425. package/src/middleware/error-mapper.ts +15 -1
  426. package/src/middleware/idempotency.ts +230 -43
  427. package/src/middleware/key-project.ts +86 -0
  428. package/src/middleware/principal.ts +9 -5
  429. package/src/middleware/project-ref.ts +3 -0
  430. package/src/openapi/generate.ts +11 -2
  431. package/src/openapi/operations.ts +1059 -142
  432. package/src/openapi/schemas.ts +2438 -485
  433. package/src/person-grants-binding.ts +76 -0
  434. package/src/proposal-service.ts +640 -0
  435. package/src/proposal-status.ts +176 -0
  436. package/src/provider-binding.ts +10 -0
  437. package/src/publish-refused.ts +38 -9
  438. package/src/routes/adapters.ts +4 -0
  439. package/src/routes/agent-releases.ts +121 -69
  440. package/src/routes/agents.ts +128 -1
  441. package/src/routes/approvals.ts +164 -154
  442. package/src/routes/artifacts.ts +181 -11
  443. package/src/routes/auth.ts +804 -336
  444. package/src/routes/blocks.ts +2 -53
  445. package/src/routes/capabilities.ts +10 -1
  446. package/src/routes/compliance.ts +60 -99
  447. package/src/routes/conversations.ts +101 -7
  448. package/src/routes/cost.ts +32 -3
  449. package/src/routes/denied.ts +28 -0
  450. package/src/routes/deployments.ts +62 -16
  451. package/src/routes/eval-comparison.ts +81 -2
  452. package/src/routes/eval-overrides.ts +108 -0
  453. package/src/routes/eval-runs.ts +86 -6
  454. package/src/routes/eval-suites.ts +25 -1
  455. package/src/routes/event-triggers.ts +27 -3
  456. package/src/routes/export-signing-keys.ts +31 -0
  457. package/src/routes/flows.ts +12 -1
  458. package/src/routes/gate-policies.ts +37 -6
  459. package/src/routes/guardrails.ts +61 -2
  460. package/src/routes/identity.ts +328 -10
  461. package/src/routes/improvement-passes.ts +541 -0
  462. package/src/routes/judged-suites.ts +113 -43
  463. package/src/routes/judgment-context.ts +76 -5
  464. package/src/routes/judgment-flow-context.ts +16 -2
  465. package/src/routes/judgments.ts +17 -3
  466. package/src/routes/mcp.ts +29 -1
  467. package/src/routes/memory-access.ts +179 -0
  468. package/src/routes/memory-erasures.ts +240 -0
  469. package/src/routes/memory-parse.ts +250 -0
  470. package/src/routes/memory.ts +244 -286
  471. package/src/routes/observations.ts +15 -2
  472. package/src/routes/pagination.ts +12 -0
  473. package/src/routes/policies.ts +7 -1
  474. package/src/routes/project-mismatch.ts +56 -0
  475. package/src/routes/projects.ts +107 -13
  476. package/src/routes/proposals.ts +370 -611
  477. package/src/routes/provenance.ts +99 -133
  478. package/src/routes/providers.ts +223 -8
  479. package/src/routes/public-run-tokens.ts +3 -0
  480. package/src/routes/runs.ts +119 -39
  481. package/src/routes/schedules.ts +472 -60
  482. package/src/routes/segments.ts +11 -0
  483. package/src/routes/service-accounts.ts +262 -0
  484. package/src/routes/sign-in-options.ts +168 -0
  485. package/src/routes/signing-keys.ts +7 -1
  486. package/src/routes/tenant-access.ts +37 -0
  487. package/src/routes/tenant.ts +6 -0
  488. package/src/routes/token-sign-in.ts +161 -0
  489. package/src/routes/tokens.ts +172 -46
  490. package/src/routes/tools.ts +12 -1
  491. package/src/routes/trigger-access.ts +72 -0
  492. package/src/routes/webhook-endpoints.ts +15 -3
  493. package/src/routes/webhooks.ts +26 -2
  494. package/src/run-failure.ts +42 -0
  495. package/src/service-account-binding.ts +113 -0
  496. package/src/session-store-binding.ts +65 -13
  497. package/src/signed-export.ts +250 -0
  498. package/src/supervisor-binding.ts +169 -409
  499. package/src/testing/app-bindings.ts +142 -0
  500. package/src/testing/index.ts +21 -0
  501. package/src/testing/stub-binding.ts +53 -0
  502. package/src/testing/trigger-registry.ts +259 -0
  503. package/src/token-admin.ts +40 -8
  504. package/src/tool-binding.ts +14 -0
  505. package/src/trigger-binding.ts +8 -1
  506. package/src/types.ts +16 -0
  507. package/src/webhook-endpoint-binding.ts +18 -3
@@ -2,15 +2,18 @@
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
4
  import { Hono } from 'hono';
5
+ import type { Context, Next } from 'hono';
5
6
 
6
7
  import type { ConversationBinding } from '@kindgi/agents';
7
- import { serializePublicKeyPem, signEd25519 } from '@kindgi/crypto';
8
- import type { SigningKeyBinding } from '@kindgi/crypto';
9
- import { canonicalize } from '@kindgi/schema';
10
- import type { ConversationId, RunId, SigningKeyId, TenantId, Timestamp } from '@kindgi/types';
8
+ import type { AuditEventBinding } from '@kindgi/audit-events';
9
+ import { ref } from '@kindgi/authz';
10
+ import type { ExportSigningBinding } from '@kindgi/crypto';
11
+ import type { RunBinding } from '@kindgi/runtime';
12
+ import type { ConversationId, RunId, TenantId } from '@kindgi/types';
11
13
 
12
14
  import { statusFor, toWireError } from '../errors.js';
13
15
 
16
+ import type { Authorizer } from '../middleware/authorize.js';
14
17
  import type {
15
18
  CallUsageByCallId,
16
19
  ProvenanceBinding,
@@ -18,9 +21,18 @@ import type {
18
21
  ProvenanceListCursor,
19
22
  ProvenanceRecordSummary,
20
23
  } from '../provenance-binding.js';
24
+ import {
25
+ exportActor,
26
+ parseSigningKeyId,
27
+ readExportBody,
28
+ signExport,
29
+ signExportFailure,
30
+ signingNotConfigured,
31
+ } from '../signed-export.js';
21
32
  import type { AppEnv } from '../types.js';
22
33
  import { clampLimit, decodeCursor, encodeCursor } from './pagination.js';
23
34
  import { parseListScope } from './scope-params.js';
35
+ import { UUID_RE } from './uuid-param.js';
24
36
 
25
37
  /**
26
38
  * Provenance resource routes.
@@ -41,25 +53,56 @@ import { parseListScope } from './scope-params.js';
41
53
  * server round trip.
42
54
  */
43
55
  export interface ProvenanceRouterOptions {
44
- readonly signingKey?: SigningKeyBinding;
56
+ /** Signs provenance exports. Absent: `POST /:runId/export` answers `404 signing-not-configured`. */
57
+ readonly exportSigning?: ExportSigningBinding;
58
+ /** Records each signed export (`export-signed`). */
59
+ readonly auditEvents?: AuditEventBinding;
45
60
  /**
46
61
  * Conversation binding used by the signed-export path to read
47
62
  * conversation transcripts (`readMessages`) alongside provenance
48
63
  * DAGs. Absent = the export omits messages (empty array).
49
64
  */
50
65
  readonly conversationBinding?: ConversationBinding;
66
+ /** Where a run's project is read, for the per-run checks (T243 A). */
67
+ readonly runBinding?: RunBinding;
51
68
  }
52
69
 
53
70
  /** Bundle schema version — bump when the wire shape of `bundle.body` changes. */
54
71
  /** 1.1.0 adds `callUsage`: the model calls' usage from the cost ledger, when the run has any. */
55
- const BUNDLE_SCHEMA_VERSION = '1.1.0';
72
+ /** 1.2.0: `exportedAt` is in the signed body (was the envelope's only). */
73
+ const BUNDLE_SCHEMA_VERSION = '1.2.0';
56
74
 
57
75
  export function provenanceRouter(
58
76
  binding: ProvenanceBinding,
59
77
  options: ProvenanceRouterOptions = {},
78
+ /**
79
+ * With one (T243 A): a run's provenance (and its export) needs `read`
80
+ * on the run's project; the list holds only records whose project the
81
+ * caller may read (the tenant, for one with no project).
82
+ */
83
+ authorizer?: Authorizer,
60
84
  ): Hono<AppEnv> {
61
85
  const r = new Hono<AppEnv>();
62
- const signingKey = options.signingKey;
86
+ if (authorizer !== undefined) {
87
+ // A run that isn't there is the handler's 404 (`read` on the tenant).
88
+ // An id that isn't a run id is never looked up (its uuid cast would
89
+ // fail the query as a 500).
90
+ const onRunProject = async (c: Context<AppEnv>, next: Next) => {
91
+ const tenantId = c.get('tenantId') as TenantId;
92
+ const runId = c.req.param('runId') ?? '';
93
+ const run = UUID_RE.test(runId)
94
+ ? await options.runBinding?.getRun(tenantId, runId as RunId)
95
+ : undefined;
96
+ const at =
97
+ run === undefined || run === null
98
+ ? ref('tenant', tenantId as unknown as string)
99
+ : ref('project', run.projectId as unknown as string);
100
+ return authorizer.authorize('read', () => at)(c, next);
101
+ };
102
+ r.use('/:runId', async (c, next) => (c.req.method === 'GET' ? onRunProject(c, next) : next()));
103
+ r.use('/:runId/export', onRunProject);
104
+ }
105
+ const exportSigning = options.exportSigning;
63
106
 
64
107
  // ---------- GET / (list metadata, cursor-paginated) ----------
65
108
  r.get('/', async (c) => {
@@ -125,8 +168,16 @@ export function provenanceRouter(
125
168
  }
126
169
  const { records, nextCursor } = result.value;
127
170
  const hasMore = nextCursor !== undefined;
171
+ const visible =
172
+ authorizer === undefined
173
+ ? records
174
+ : await authorizer.filterByCan(c, 'read', records, (rec) =>
175
+ rec.projectId !== undefined
176
+ ? ref('project', rec.projectId as unknown as string)
177
+ : ref('tenant', tenantId as unknown as string),
178
+ );
128
179
  return c.json({
129
- data: records.map(serializeRecordMetadata),
180
+ data: visible.map(serializeRecordMetadata),
130
181
  hasMore,
131
182
  ...(nextCursor !== undefined && {
132
183
  nextCursor: encodeCursor({ createdAt: nextCursor.createdAt, id: nextCursor.id }),
@@ -195,36 +246,10 @@ export function provenanceRouter(
195
246
  const tenantId = c.get('tenantId') as TenantId;
196
247
  const runId = c.req.param('runId') as RunId;
197
248
 
198
- if (signingKey === undefined) {
199
- c.status(statusFor('signing-not-configured') as never);
200
- return c.json(
201
- toWireError(
202
- {
203
- code: 'signing-not-configured',
204
- message:
205
- 'This deployment does not have a `signingKey` binding mounted; signed provenance exports are unavailable.',
206
- },
207
- requestId,
208
- ),
209
- );
210
- }
249
+ if (exportSigning === undefined) return signingNotConfigured(c, 'signed provenance exports');
211
250
 
212
- let body: unknown;
213
- try {
214
- body = await c.req.json();
215
- } catch {
216
- c.status(statusFor('bad-input') as never);
217
- return c.json(
218
- toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
219
- );
220
- }
221
- if (body === null || typeof body !== 'object' || Array.isArray(body)) {
222
- c.status(statusFor('bad-input') as never);
223
- return c.json(
224
- toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
225
- );
226
- }
227
- const parsed = parseExportBody(body as Record<string, unknown>);
251
+ const read = await readExportBody(c);
252
+ const parsed = read.kind === 'ok' ? parseExportBody(read.value) : read;
228
253
  if (parsed.kind === 'err') {
229
254
  c.status(statusFor('bad-input') as never);
230
255
  return c.json(toWireError({ code: 'bad-input', message: parsed.message }, requestId));
@@ -282,94 +307,43 @@ export function provenanceRouter(
282
307
  }
283
308
  }
284
309
 
285
- // 3. Look up the private key material.
286
- const privateKey = signingKey.getPrivateKey(signingKeyId);
287
- if (privateKey === null) {
288
- c.status(statusFor('signing-key-not-found') as never);
289
- return c.json(
290
- toWireError(
291
- {
292
- code: 'signing-key-not-found',
293
- message: `No signing key registered with id "${signingKeyId as unknown as string}"`,
294
- signingKeyId: signingKeyId as unknown as string,
295
- },
296
- requestId,
297
- ),
298
- );
299
- }
300
- const publicKeyRaw = signingKey.getPublicKey(signingKeyId);
301
- if (publicKeyRaw === null) {
302
- // Contract: `getPublicKey` never returns null for a key that
303
- // `getPrivateKey` resolved. Treat mismatch as a binding bug.
304
- c.status(statusFor('signing-key-not-found') as never);
305
- return c.json(
306
- toWireError(
307
- {
308
- code: 'signing-key-not-found',
309
- message: `Signing key "${signingKeyId as unknown as string}" resolved a private key but no public key`,
310
- signingKeyId: signingKeyId as unknown as string,
311
- },
312
- requestId,
313
- ),
314
- );
315
- }
316
-
317
- // 4. Build the canonical bundle body. Bundle shape is v1.0.0 —
318
- // ordering here is irrelevant for signing (canonicalize sorts
319
- // keys) but declared explicitly for reviewer scanability.
320
- const bundleBody = {
310
+ // 3. Sign the bundle body (and record the export).
311
+ const signed = await signExport({
312
+ signer: exportSigning,
313
+ kind: 'provenance',
321
314
  bundleSchemaVersion: BUNDLE_SCHEMA_VERSION,
322
- provenanceId: provenance.id as unknown as string,
323
- runId: provenance.runId as unknown as string,
324
- tenantId: provenance.tenantId as unknown as string,
325
- version: provenance.version,
326
- createdAt: provenance.createdAt as unknown as string,
327
- ...(provenance.flowRef !== undefined && {
328
- flowRef: {
329
- id: provenance.flowRef.id as unknown as string,
330
- version: provenance.flowRef.version,
315
+ ...(signingKeyId !== undefined && { signingKeyId }),
316
+ body: {
317
+ provenanceId: provenance.id as unknown as string,
318
+ runId: provenance.runId as unknown as string,
319
+ tenantId: provenance.tenantId as unknown as string,
320
+ version: provenance.version,
321
+ createdAt: provenance.createdAt as unknown as string,
322
+ ...(provenance.flowRef !== undefined && {
323
+ flowRef: {
324
+ id: provenance.flowRef.id as unknown as string,
325
+ version: provenance.flowRef.version,
326
+ },
327
+ }),
328
+ dag: {
329
+ nodes: provenance.nodes,
330
+ edges: provenance.edges,
331
331
  },
332
- }),
333
- dag: {
334
- nodes: provenance.nodes,
335
- edges: provenance.edges,
332
+ ...(messages !== undefined && { messages }),
333
+ ...(callUsage.value !== undefined && { callUsage: callUsage.value }),
336
334
  },
337
- ...(messages !== undefined && { messages }),
338
- ...(callUsage.value !== undefined && { callUsage: callUsage.value }),
339
- };
340
- const canonicalBundleBytes = new TextEncoder().encode(canonicalize(bundleBody));
341
-
342
- // 5. Sign the canonical bytes.
343
- const signResult = signEd25519(privateKey, canonicalBundleBytes);
344
- if (signResult.kind === 'err') {
345
- c.status(statusFor('export-key-error') as never);
346
- return c.json(
347
- toWireError(
348
- {
349
- code: 'export-key-error',
350
- message: `Failed to sign provenance bundle: ${signResult.error.message}`,
351
- },
352
- requestId,
353
- ),
354
- );
355
- }
356
-
357
- // 6. Emit the signed envelope. `bundle` is a base64 of the exact
358
- // bytes that were signed — verifiers decode + re-canonicalize
359
- // is unnecessary, they can verify against `atob(bundle)`
360
- // directly.
361
- const exportedAt = new Date().toISOString() as Timestamp;
362
- return c.json({
363
- runId: runId as unknown as string,
364
- bundle: Buffer.from(canonicalBundleBytes).toString('base64'),
365
- bundleSchemaVersion: BUNDLE_SCHEMA_VERSION,
366
- algorithm: 'ed25519' as const,
367
- signingKeyId: signingKeyId as unknown as string,
368
- signature: Buffer.from(signResult.value).toString('base64'),
369
- publicKey: serializePublicKeyPem(publicKeyRaw),
370
- canonicalization: 'sorted-key-json' as const,
371
- exportedAt: exportedAt as unknown as string,
335
+ ...(options.auditEvents !== undefined && {
336
+ record: {
337
+ auditEvents: options.auditEvents,
338
+ tenantId,
339
+ runId: runId as unknown as string,
340
+ actor: exportActor(c),
341
+ subject: { runId: runId as unknown as string },
342
+ },
343
+ }),
372
344
  });
345
+ if (signed.kind === 'err') return signExportFailure(c, signed.error, 'export-key-error');
346
+ return c.json({ runId: runId as unknown as string, ...signed.value });
373
347
  });
374
348
 
375
349
  return r;
@@ -407,7 +381,7 @@ function serializeRecordMetadata(row: ProvenanceRecordSummary): RecordMetadata {
407
381
  }
408
382
 
409
383
  interface ValidatedExportBody {
410
- readonly signingKeyId: SigningKeyId;
384
+ readonly signingKeyId: string | undefined;
411
385
  readonly includeMessages: boolean;
412
386
  }
413
387
 
@@ -416,10 +390,8 @@ type ParseResult<T> =
416
390
  | { readonly kind: 'err'; readonly message: string };
417
391
 
418
392
  function parseExportBody(body: Record<string, unknown>): ParseResult<ValidatedExportBody> {
419
- const raw = body.signingKeyId;
420
- if (typeof raw !== 'string' || raw.length === 0) {
421
- return { kind: 'err', message: 'Field `signingKeyId` must be a non-empty string' };
422
- }
393
+ const signingKeyId = parseSigningKeyId(body);
394
+ if (signingKeyId.kind === 'err') return signingKeyId;
423
395
  let includeMessages = false;
424
396
  if ('includeMessages' in body) {
425
397
  const im = body.includeMessages;
@@ -428,13 +400,7 @@ function parseExportBody(body: Record<string, unknown>): ParseResult<ValidatedEx
428
400
  }
429
401
  includeMessages = im;
430
402
  }
431
- return {
432
- kind: 'ok',
433
- value: {
434
- signingKeyId: raw as SigningKeyId,
435
- includeMessages,
436
- },
437
- };
403
+ return { kind: 'ok', value: { signingKeyId: signingKeyId.value, includeMessages } };
438
404
  }
439
405
 
440
406
  /** The run's call usage, when the binding has a cost ledger and the run made calls. */
@@ -5,19 +5,28 @@ import { Hono } from 'hono';
5
5
 
6
6
  import {
7
7
  type AdapterConfig,
8
+ type AdapterConfigProblem,
9
+ type AdapterFactoryRegistry,
8
10
  FEATURES,
9
11
  type Feature,
10
12
  type ModelInfo,
11
13
  type ProviderMetadata,
14
+ isModelThinking,
12
15
  validateProviderLabels,
13
16
  } from '@kindgi/capabilities';
14
17
  import type { Cursor, TenantId } from '@kindgi/types';
15
18
 
16
19
  import type { CapabilityDescriptor } from '../capability-binding.js';
17
20
  import { statusFor, toWireError } from '../errors.js';
18
- import type { ProviderRegistryBinding, ProviderSecretRef } from '../provider-binding.js';
21
+ import type { Authorizer } from '../middleware/authorize.js';
22
+ import type {
23
+ ProviderRegistryBinding,
24
+ ProviderRuntimeEntry,
25
+ ProviderSecretRef,
26
+ } from '../provider-binding.js';
19
27
  import type { AppEnv } from '../types.js';
20
28
  import { clampLimit } from './pagination.js';
29
+ import { tenantResourceAccess } from './tenant-access.js';
21
30
 
22
31
  /**
23
32
  * Providers resource routes — part of the admin control plane. Full
@@ -46,11 +55,20 @@ export type ProviderWriteHook = (params: {
46
55
  readonly kind: 'register' | 'unregister';
47
56
  }) => void | Promise<void>;
48
57
 
58
+ /**
59
+ * `factories`: the deployment's in-process adapter factories. With them, a
60
+ * registration is checked against its adapter's `checkConfig` before it's
61
+ * stored, and `GET /:providerId/check` answers for a registered one.
62
+ * Without them, registration takes any flat `adapter_config`.
63
+ */
49
64
  export function providersRouter(
50
65
  binding: ProviderRegistryBinding,
51
66
  onWrite?: ProviderWriteHook,
67
+ factories?: AdapterFactoryRegistry,
68
+ authorizer?: Authorizer,
52
69
  ): Hono<AppEnv> {
53
70
  const r = new Hono<AppEnv>();
71
+ r.use('*', tenantResourceAccess(authorizer));
54
72
 
55
73
  // ---------- GET / (list, cursor-paginated) ----------
56
74
  r.get('/', async (c) => {
@@ -151,12 +169,15 @@ export function providersRouter(
151
169
  // runtime bridge),
152
170
  // "adapter_config": { … } (optional — the adapter's flat,
153
171
  // non-secret connection settings)
172
+ // "send_traceparent": boolean (optional — send each call's
173
+ // traceparent to the provider)
154
174
  // }
155
175
  const bodyObj = body as {
156
176
  readonly metadata?: unknown;
157
177
  readonly adapter_id?: unknown;
158
178
  readonly secret_ref?: unknown;
159
179
  readonly adapter_config?: unknown;
180
+ readonly send_traceparent?: unknown;
160
181
  };
161
182
  if (bodyObj.metadata === undefined) {
162
183
  c.status(statusFor('bad-input') as never);
@@ -216,12 +237,38 @@ export function providersRouter(
216
237
  );
217
238
  }
218
239
 
240
+ // The registration's own fields first, then the adapter's check of what
241
+ // it'll be built from: refused now, naming the field, instead of skipped
242
+ // at the first model call. One answer lists them all.
243
+ const sendTraceparent = bodyObj.send_traceparent;
244
+ const adapterProblems = configProblems(factories, {
245
+ metadata: validation.value,
246
+ adapterId: bodyObj.adapter_id,
247
+ ...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
248
+ ...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
249
+ });
250
+ const problems = [...registrationProblems(bodyObj), ...(adapterProblems ?? [])];
251
+ if (problems.length > 0) {
252
+ c.status(statusFor('provider-config-invalid') as never);
253
+ return c.json(
254
+ toWireError(
255
+ {
256
+ code: 'provider-config-invalid',
257
+ message: refusalOf(validation.value.id, bodyObj.adapter_id, problems),
258
+ issues: problems,
259
+ },
260
+ requestId,
261
+ ),
262
+ );
263
+ }
264
+
219
265
  const outcome = await binding.register({
220
266
  tenantId,
221
267
  metadata: validation.value,
222
268
  adapterId: bodyObj.adapter_id,
223
269
  ...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
224
270
  ...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
271
+ ...(typeof sendTraceparent === 'boolean' && { sendTraceparent }),
225
272
  });
226
273
  if (outcome.kind === 'already-registered') {
227
274
  c.status(statusFor('provider-already-registered') as never);
@@ -264,6 +311,31 @@ export function providersRouter(
264
311
  return c.json({ providerId: outcome.providerId });
265
312
  });
266
313
 
314
+ // ---------- GET /:providerId/check ----------
315
+ r.get('/:providerId/check', async (c) => {
316
+ const requestId = c.get('requestId');
317
+ const tenantId = c.get('tenantId') as TenantId;
318
+ const providerId = c.req.param('providerId');
319
+ const entries = await binding.resolveForRuntime({ tenantId });
320
+ const entry = entries.find((e) => e.metadata.id === providerId);
321
+ if (entry === undefined) {
322
+ c.status(statusFor('provider-not-found') as never);
323
+ return c.json(
324
+ toWireError(
325
+ { code: 'provider-not-found', message: `Provider "${providerId}" not found`, providerId },
326
+ requestId,
327
+ ),
328
+ );
329
+ }
330
+ const problems = configProblems(factories, entry);
331
+ return c.json({
332
+ providerId,
333
+ adapterId: entry.adapterId,
334
+ checked: problems !== undefined,
335
+ issues: problems ?? [],
336
+ });
337
+ });
338
+
267
339
  // ---------- POST /:providerId/unregister ----------
268
340
  r.post('/:providerId/unregister', async (c) => {
269
341
  const requestId = c.get('requestId');
@@ -305,14 +377,15 @@ function serializeProvider(m: ProviderMetadata): Record<string, unknown> {
305
377
  name: model.name,
306
378
  contextWindow: model.contextWindow,
307
379
  features: model.features,
308
- cost: {
309
- promptUsdPer1kTokens: model.cost.promptUsdPer1kTokens,
310
- completionUsdPer1kTokens: model.cost.completionUsdPer1kTokens,
311
- },
380
+ // As stored: the base rates and any an adapter widens it with.
381
+ cost: { ...model.cost },
312
382
  ...(model.p95LatencyMs !== undefined && { p95LatencyMs: model.p95LatencyMs }),
313
383
  ...(model.maxOutputTokens !== undefined && { maxOutputTokens: model.maxOutputTokens }),
384
+ ...(model.sampling !== undefined && { sampling: model.sampling }),
385
+ ...(model.thinking !== undefined && { thinking: model.thinking }),
314
386
  ...(model.description !== undefined && { description: model.description }),
315
387
  })),
388
+ ...(m.defaultModel !== undefined && { defaultModel: m.defaultModel }),
316
389
  ...(m.attributes !== undefined && { attributes: m.attributes }),
317
390
  ...(m.description !== undefined && { description: m.description }),
318
391
  ...(m.capabilityKind !== undefined && { capabilityKind: m.capabilityKind }),
@@ -328,6 +401,9 @@ function serializeCapability(d: CapabilityDescriptor): Record<string, unknown> {
328
401
  description: d.description,
329
402
  ...(d.kind !== undefined && { kind: d.kind }),
330
403
  ...(d.paramsSchema !== undefined && { paramsSchema: d.paramsSchema }),
404
+ ...(d.providers !== undefined && {
405
+ providers: d.providers.map((p) => ({ providerId: p.providerId, models: [...p.models] })),
406
+ }),
331
407
  };
332
408
  }
333
409
 
@@ -436,10 +512,20 @@ function validateProviderMetadata(
436
512
  }
437
513
  const badLabels = validateProviderLabels(b.id, b.labels);
438
514
  if (badLabels !== undefined) return { kind: 'err', error: badLabels };
515
+ if (b.defaultModel !== undefined && !seenNames.has(b.defaultModel as string)) {
516
+ return {
517
+ kind: 'err',
518
+ error: {
519
+ message: `provider "${b.id}" defaultModel must be one of its models (${[...seenNames].join(', ')}), got ${JSON.stringify(b.defaultModel)}`,
520
+ reason: 'unknown-default-model',
521
+ },
522
+ };
523
+ }
439
524
  const value: ProviderMetadata = {
440
525
  id: b.id,
441
526
  region: b.region,
442
527
  models: validatedModels,
528
+ ...(b.defaultModel !== undefined && { defaultModel: b.defaultModel as string }),
443
529
  ...(b.attributes !== undefined && { attributes: b.attributes as readonly string[] }),
444
530
  ...(b.description !== undefined && { description: b.description }),
445
531
  ...(b.capabilityKind !== undefined && { capabilityKind: b.capabilityKind as string }),
@@ -527,6 +613,16 @@ function validateModelInfo(
527
613
  },
528
614
  };
529
615
  }
616
+ const extraRates = costExtraRates(cost as unknown as Record<string, unknown>);
617
+ if (extraRates === undefined) {
618
+ return {
619
+ kind: 'err',
620
+ error: {
621
+ message: `provider "${providerId}" model "${m.name}" cost table's other rates must be non-negative numbers, or objects of them (e.g. longContext: { thresholdTokens, promptUsdPer1kTokens, completionUsdPer1kTokens })`,
622
+ reason: 'invalid-cost',
623
+ },
624
+ };
625
+ }
530
626
  if (m.p95LatencyMs !== undefined) {
531
627
  if (typeof m.p95LatencyMs !== 'number' || m.p95LatencyMs < 0) {
532
628
  return {
@@ -553,6 +649,24 @@ function validateModelInfo(
553
649
  };
554
650
  }
555
651
  }
652
+ if (m.sampling !== undefined && typeof m.sampling !== 'boolean') {
653
+ return {
654
+ kind: 'err',
655
+ error: {
656
+ message: `provider "${providerId}" model "${m.name}" sampling must be true or false`,
657
+ reason: 'invalid-sampling',
658
+ },
659
+ };
660
+ }
661
+ if (m.thinking !== undefined && !isModelThinking(m.thinking)) {
662
+ return {
663
+ kind: 'err',
664
+ error: {
665
+ message: `provider "${providerId}" model "${m.name}" thinking must be { mode: 'adaptive' | 'always', lowest: <the vendor's setting> }`,
666
+ reason: 'invalid-thinking',
667
+ },
668
+ };
669
+ }
556
670
  if (m.description !== undefined && typeof m.description !== 'string') {
557
671
  return {
558
672
  kind: 'err',
@@ -567,21 +681,122 @@ function validateModelInfo(
567
681
  contextWindow: m.contextWindow,
568
682
  features: m.features as readonly Feature[],
569
683
  cost: {
684
+ ...extraRates,
570
685
  promptUsdPer1kTokens: cost.promptUsdPer1kTokens,
571
686
  completionUsdPer1kTokens: cost.completionUsdPer1kTokens,
572
- },
687
+ } as ModelInfo['cost'],
573
688
  ...(m.p95LatencyMs !== undefined && { p95LatencyMs: m.p95LatencyMs }),
574
689
  ...(m.maxOutputTokens !== undefined && { maxOutputTokens: m.maxOutputTokens }),
690
+ ...(m.sampling !== undefined && { sampling: m.sampling }),
691
+ ...(m.thinking !== undefined && {
692
+ thinking: { mode: m.thinking.mode, lowest: m.thinking.lowest },
693
+ }),
575
694
  ...(m.description !== undefined && { description: m.description }),
576
695
  };
577
696
  return { kind: 'ok', value };
578
697
  }
579
698
 
699
+ /**
700
+ * The rates a cost table carries beyond the two base ones: an adapter
701
+ * widens it with its own (Anthropic's prompt-cache multipliers, Gemini's
702
+ * cached-prompt share, a long-context tier), each a non-negative number
703
+ * or one level of an object of them. Returned as given, or `undefined`
704
+ * when one isn't, so a registration keeps what its adapter prices with.
705
+ */
706
+ function costExtraRates(
707
+ cost: Readonly<Record<string, unknown>>,
708
+ ): Record<string, number | Record<string, number>> | undefined {
709
+ const isRate = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0;
710
+ const out: Record<string, number | Record<string, number>> = {};
711
+ for (const [key, value] of Object.entries(cost)) {
712
+ if (key === 'promptUsdPer1kTokens' || key === 'completionUsdPer1kTokens') continue;
713
+ if (isRate(value)) {
714
+ out[key] = value;
715
+ } else if (
716
+ typeof value === 'object' &&
717
+ value !== null &&
718
+ !Array.isArray(value) &&
719
+ Object.keys(value).length > 0 &&
720
+ Object.values(value).every(isRate)
721
+ ) {
722
+ out[key] = { ...(value as Record<string, number>) };
723
+ } else {
724
+ return undefined;
725
+ }
726
+ }
727
+ return out;
728
+ }
729
+
730
+ /**
731
+ * What's wrong with a registration, by its adapter's own static check
732
+ * (`AdapterFactoryEntry.checkConfig`): no network, no secret read.
733
+ * `undefined` when there's nothing to check it with (no factories wired, or
734
+ * an adapter without a check). An adapter the deployment doesn't have is a
735
+ * problem: the runtime could never build the provider.
736
+ */
737
+ function configProblems(
738
+ factories: AdapterFactoryRegistry | undefined,
739
+ registration: ProviderRuntimeEntry,
740
+ ): readonly AdapterConfigProblem[] | undefined {
741
+ if (factories === undefined) return undefined;
742
+ const entry = factories.get(registration.adapterId);
743
+ if (entry === undefined) {
744
+ return [
745
+ {
746
+ path: '/adapter_id',
747
+ message: `This runtime has no adapter "${registration.adapterId}", so it can't build provider "${registration.metadata.id}".`,
748
+ },
749
+ ];
750
+ }
751
+ return entry.checkConfig?.({
752
+ metadata: registration.metadata,
753
+ ...(registration.adapterConfig !== undefined && { config: registration.adapterConfig }),
754
+ hasSecretRef: registration.secretRef !== undefined,
755
+ });
756
+ }
757
+
758
+ /**
759
+ * What's wrong with the registration's own fields, before its adapter's:
760
+ * `send_traceparent`, when present, is a boolean. The runtime, not the
761
+ * adapter, reads it.
762
+ */
763
+ export function registrationProblems(body: {
764
+ readonly send_traceparent?: unknown;
765
+ }): readonly AdapterConfigProblem[] {
766
+ const value = body.send_traceparent;
767
+ return value === undefined || typeof value === 'boolean'
768
+ ? []
769
+ : [{ path: '/send_traceparent', message: 'send_traceparent must be true or false.' }];
770
+ }
771
+
772
+ /**
773
+ * The 422's message: one sentence naming the provider, its adapter and the
774
+ * first problem, with a count of the rest (`details.issues` lists each).
775
+ * A problem with the registration's own fields names the provider alone.
776
+ */
777
+ function refusalOf(
778
+ providerId: string,
779
+ adapterId: string,
780
+ problems: readonly AdapterConfigProblem[],
781
+ ): string {
782
+ const [first, ...rest] = problems;
783
+ if (first === undefined) return `Provider "${providerId}" doesn't fit adapter ${adapterId}.`;
784
+ if (first.path === '/adapter_id') return first.message;
785
+ const more = rest.length > 0 ? ` (and ${rest.length} more)` : '';
786
+ const what = first.message.replace(/\.$/, '');
787
+ return REGISTRATION_PATHS.has(first.path)
788
+ ? `Provider "${providerId}": ${what}${more}.`
789
+ : `Provider "${providerId}" doesn't fit adapter ${adapterId}: ${what}${more}.`;
790
+ }
791
+
792
+ /** The paths `registrationProblems` reports: the registration's own fields, not its adapter's. */
793
+ const REGISTRATION_PATHS: ReadonlySet<string> = new Set(['/send_traceparent']);
794
+
580
795
  /**
581
796
  * Parse the optional `adapter_config` on the register request body: a
582
797
  * flat object of string, number or boolean values. Credentials don't
583
- * belong here (they ride on `secret_ref`); the adapter validates its
584
- * own keys when it is instantiated.
798
+ * belong here (they ride on `secret_ref`); the adapter checks its own keys
799
+ * (`configProblems`).
585
800
  */
586
801
  function parseAdapterConfig(
587
802
  raw: unknown,