@kindgi/api 0.0.0-bootstrap.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +397 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +268 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +20 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +34 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5050 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +705 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29649 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1286 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +295 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +40 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5444 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +892 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,624 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { Hono } from 'hono';
5
+
6
+ import {
7
+ type AdapterConfig,
8
+ FEATURES,
9
+ type Feature,
10
+ type ModelInfo,
11
+ type ProviderMetadata,
12
+ } from '@kindgi/capabilities';
13
+ import type { Cursor, TenantId } from '@kindgi/types';
14
+
15
+ import type { CapabilityDescriptor } from '../capability-binding.js';
16
+ import { statusFor, toWireError } from '../errors.js';
17
+ import type { ProviderRegistryBinding, ProviderSecretRef } from '../provider-binding.js';
18
+ import type { AppEnv } from '../types.js';
19
+ import { clampLimit } from './pagination.js';
20
+
21
+ /**
22
+ * Providers resource routes — part of the admin control plane. Full
23
+ * CRUD. Model providers are tenant-owned: each tenant registers the
24
+ * endpoints they want the runtime's capability router to consider
25
+ * (hosted model APIs, self-hosted inference servers, embedding backends,
26
+ * sandbox-exec fleets, ...).
27
+ *
28
+ * Secrets do NOT cross the wire — `ProviderMetadata` is the wire shape.
29
+ * Deployments store the actual credential set inside the caller-plugged
30
+ * `ProviderRegistryBinding`; the API surface only returns routing-
31
+ * relevant metadata: provider-level `id` / `region` / `attributes` +
32
+ * `models[]` (each with `name`, `contextWindow`, `features`, `cost`,
33
+ * optional `p95LatencyMs` / `maxOutputTokens` / `description`).
34
+ */
35
+ /**
36
+ * Optional side-effect callback fired after a successful write
37
+ * (register, unregister) to a provider. Lets an in-process runtime
38
+ * cache (e.g. a per-tenant provider cache) invalidate its
39
+ * per-tenant snapshot so the next agent run picks up the new
40
+ * provider without a process restart.
41
+ */
42
+ export type ProviderWriteHook = (params: {
43
+ readonly tenantId: TenantId;
44
+ readonly providerId: string;
45
+ readonly kind: 'register' | 'unregister';
46
+ }) => void | Promise<void>;
47
+
48
+ export function providersRouter(
49
+ binding: ProviderRegistryBinding,
50
+ onWrite?: ProviderWriteHook,
51
+ ): Hono<AppEnv> {
52
+ const r = new Hono<AppEnv>();
53
+
54
+ // ---------- GET / (list, cursor-paginated) ----------
55
+ r.get('/', async (c) => {
56
+ const tenantId = c.get('tenantId') as TenantId;
57
+ const limit = clampLimit(c.req.query('limit'));
58
+
59
+ const cursorRaw = c.req.query('cursor');
60
+ const featureRaw = c.req.query('feature');
61
+ const page = await binding.list({
62
+ tenantId,
63
+ limit,
64
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
65
+ ...(featureRaw !== undefined && featureRaw.length > 0 && { featureFilter: featureRaw }),
66
+ });
67
+ return c.json({
68
+ data: page.data.map(serializeProvider),
69
+ hasMore: page.nextCursor !== undefined,
70
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
71
+ });
72
+ });
73
+
74
+ // ---------- GET /:providerId ----------
75
+ r.get('/:providerId', async (c) => {
76
+ const requestId = c.get('requestId');
77
+ const tenantId = c.get('tenantId') as TenantId;
78
+ const providerId = c.req.param('providerId');
79
+
80
+ const provider = await binding.get({ tenantId, providerId });
81
+ if (provider === null) {
82
+ c.status(statusFor('provider-not-found') as never);
83
+ return c.json(
84
+ toWireError(
85
+ {
86
+ code: 'provider-not-found',
87
+ message: `No provider registered with id "${providerId}"`,
88
+ providerId,
89
+ },
90
+ requestId,
91
+ ),
92
+ );
93
+ }
94
+ return c.json(serializeProvider(provider));
95
+ });
96
+
97
+ // ---------- GET /:providerId/capabilities (sub-resource) ----------
98
+ r.get('/:providerId/capabilities', async (c) => {
99
+ const requestId = c.get('requestId');
100
+ const tenantId = c.get('tenantId') as TenantId;
101
+ const providerId = c.req.param('providerId');
102
+
103
+ const capabilities = await binding.capabilitiesFor({ tenantId, providerId });
104
+ if (capabilities === null) {
105
+ c.status(statusFor('provider-not-found') as never);
106
+ return c.json(
107
+ toWireError(
108
+ {
109
+ code: 'provider-not-found',
110
+ message: `No provider registered with id "${providerId}"`,
111
+ providerId,
112
+ },
113
+ requestId,
114
+ ),
115
+ );
116
+ }
117
+ return c.json({
118
+ data: capabilities.map(serializeCapability),
119
+ });
120
+ });
121
+
122
+ // ---------- POST / (register) ----------
123
+ r.post('/', async (c) => {
124
+ const requestId = c.get('requestId');
125
+ const tenantId = c.get('tenantId') as TenantId;
126
+
127
+ let body: unknown;
128
+ try {
129
+ body = await c.req.json();
130
+ } catch {
131
+ c.status(statusFor('bad-input') as never);
132
+ return c.json(
133
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
134
+ );
135
+ }
136
+ if (body === null || typeof body !== 'object') {
137
+ c.status(statusFor('bad-input') as never);
138
+ return c.json(
139
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
140
+ );
141
+ }
142
+
143
+ // Wire body shape:
144
+ // {
145
+ // "metadata": ProviderMetadata (required),
146
+ // "adapter_id": string (required — an adapter registered
147
+ // for the tenant),
148
+ // "secret_ref": { envName, name } (optional — tenant-scoped
149
+ // credential pointer for the
150
+ // runtime bridge),
151
+ // "adapter_config": { … } (optional — the adapter's flat,
152
+ // non-secret connection settings)
153
+ // }
154
+ const bodyObj = body as {
155
+ readonly metadata?: unknown;
156
+ readonly adapter_id?: unknown;
157
+ readonly secret_ref?: unknown;
158
+ readonly adapter_config?: unknown;
159
+ };
160
+ if (bodyObj.metadata === undefined) {
161
+ c.status(statusFor('bad-input') as never);
162
+ return c.json(
163
+ toWireError(
164
+ {
165
+ code: 'bad-input',
166
+ message:
167
+ 'Request body must include a `metadata` object with the ProviderMetadata shape.',
168
+ },
169
+ requestId,
170
+ ),
171
+ );
172
+ }
173
+ if (typeof bodyObj.adapter_id !== 'string' || bodyObj.adapter_id.length === 0) {
174
+ c.status(statusFor('bad-input') as never);
175
+ return c.json(
176
+ toWireError(
177
+ {
178
+ code: 'bad-input',
179
+ message:
180
+ 'Request body must include a non-empty string `adapter_id` naming a registered adapter.',
181
+ },
182
+ requestId,
183
+ ),
184
+ );
185
+ }
186
+ const secretRefResult = parseSecretRef(bodyObj.secret_ref);
187
+ if (secretRefResult.kind === 'err') {
188
+ c.status(statusFor('bad-input') as never);
189
+ return c.json(toWireError({ code: 'bad-input', message: secretRefResult.error }, requestId));
190
+ }
191
+ const adapterConfigResult = parseAdapterConfig(bodyObj.adapter_config);
192
+ if (adapterConfigResult.kind === 'err') {
193
+ c.status(statusFor('bad-input') as never);
194
+ return c.json(
195
+ toWireError({ code: 'bad-input', message: adapterConfigResult.error }, requestId),
196
+ );
197
+ }
198
+
199
+ // Shape validation matches `@kindgi/capabilities.createProviderRegistry`
200
+ // internal `validate()` — same rules as the runtime primitive, so a
201
+ // provider registered through the API is byte-identical to one
202
+ // registered in-process.
203
+ const validation = validateProviderMetadata(bodyObj.metadata);
204
+ if (validation.kind === 'err') {
205
+ c.status(statusFor('invalid-provider') as never);
206
+ return c.json(
207
+ toWireError(
208
+ {
209
+ code: 'invalid-provider',
210
+ message: validation.error.message,
211
+ reason: validation.error.reason,
212
+ },
213
+ requestId,
214
+ ),
215
+ );
216
+ }
217
+
218
+ const outcome = await binding.register({
219
+ tenantId,
220
+ metadata: validation.value,
221
+ adapterId: bodyObj.adapter_id,
222
+ ...(secretRefResult.value !== undefined && { secretRef: secretRefResult.value }),
223
+ ...(adapterConfigResult.value !== undefined && { adapterConfig: adapterConfigResult.value }),
224
+ });
225
+ if (outcome.kind === 'already-registered') {
226
+ c.status(statusFor('provider-already-registered') as never);
227
+ return c.json(
228
+ toWireError(
229
+ {
230
+ code: 'provider-already-registered',
231
+ message: `Provider "${outcome.providerId}" is already registered`,
232
+ providerId: outcome.providerId,
233
+ },
234
+ requestId,
235
+ ),
236
+ );
237
+ }
238
+ if (outcome.kind === 'invalid') {
239
+ c.status(statusFor('invalid-provider') as never);
240
+ return c.json(
241
+ toWireError(
242
+ {
243
+ code: 'invalid-provider',
244
+ message: outcome.message,
245
+ providerId: outcome.providerId,
246
+ ...(outcome.reason !== undefined && { reason: outcome.reason }),
247
+ },
248
+ requestId,
249
+ ),
250
+ );
251
+ }
252
+ if (onWrite !== undefined) {
253
+ try {
254
+ await onWrite({ tenantId, providerId: outcome.providerId, kind: 'register' });
255
+ } catch {
256
+ // Post-write hooks are advisory (cache invalidation etc.).
257
+ // A hook failure does NOT roll back the register — the row
258
+ // is durably stored; a stale in-memory cache will self-heal
259
+ // on the next boot.
260
+ }
261
+ }
262
+ c.status(201);
263
+ return c.json({ providerId: outcome.providerId });
264
+ });
265
+
266
+ // ---------- POST /:providerId/unregister ----------
267
+ r.post('/:providerId/unregister', async (c) => {
268
+ const requestId = c.get('requestId');
269
+ const tenantId = c.get('tenantId') as TenantId;
270
+ const providerId = c.req.param('providerId');
271
+
272
+ const outcome = await binding.unregister({ tenantId, providerId });
273
+ if (!outcome.unregistered) {
274
+ c.status(statusFor('provider-not-found') as never);
275
+ return c.json(
276
+ toWireError(
277
+ {
278
+ code: 'provider-not-found',
279
+ message: `No provider "${providerId}" to unregister`,
280
+ providerId,
281
+ },
282
+ requestId,
283
+ ),
284
+ );
285
+ }
286
+ if (onWrite !== undefined) {
287
+ try {
288
+ await onWrite({ tenantId, providerId, kind: 'unregister' });
289
+ } catch {
290
+ // See register path — hooks are advisory.
291
+ }
292
+ }
293
+ return c.json({ providerId, unregistered: true });
294
+ });
295
+
296
+ return r;
297
+ }
298
+
299
+ function serializeProvider(m: ProviderMetadata): Record<string, unknown> {
300
+ return {
301
+ id: m.id,
302
+ region: m.region,
303
+ models: m.models.map((model) => ({
304
+ name: model.name,
305
+ contextWindow: model.contextWindow,
306
+ features: model.features,
307
+ cost: {
308
+ promptUsdPer1kTokens: model.cost.promptUsdPer1kTokens,
309
+ completionUsdPer1kTokens: model.cost.completionUsdPer1kTokens,
310
+ },
311
+ ...(model.p95LatencyMs !== undefined && { p95LatencyMs: model.p95LatencyMs }),
312
+ ...(model.maxOutputTokens !== undefined && { maxOutputTokens: model.maxOutputTokens }),
313
+ ...(model.description !== undefined && { description: model.description }),
314
+ })),
315
+ ...(m.attributes !== undefined && { attributes: m.attributes }),
316
+ ...(m.description !== undefined && { description: m.description }),
317
+ ...(m.capabilityKind !== undefined && { capabilityKind: m.capabilityKind }),
318
+ ...(m.fallback !== undefined && { fallback: m.fallback }),
319
+ };
320
+ }
321
+
322
+ function serializeCapability(d: CapabilityDescriptor): Record<string, unknown> {
323
+ return {
324
+ id: d.id,
325
+ feature: d.feature,
326
+ description: d.description,
327
+ ...(d.kind !== undefined && { kind: d.kind }),
328
+ ...(d.paramsSchema !== undefined && { paramsSchema: d.paramsSchema }),
329
+ };
330
+ }
331
+
332
+ /**
333
+ * Wire-shape validator for `ProviderMetadata`. Mirrors the private
334
+ * `validate()` inside `@kindgi/capabilities.createProviderRegistry` —
335
+ * kept in sync with the runtime so a provider registered through the
336
+ * API is byte-identical to one registered in-process. The wire path
337
+ * additionally enforces `features ⊆ FEATURES` (closed enum) since it
338
+ * receives untyped JSON; the runtime primitive receives already-typed
339
+ * `Feature[]` from its callers. Returns a `Result`-ish shape rather
340
+ * than throwing.
341
+ */
342
+ /** `metadata.region`: one DNS label (`us-central1`, `eu-west-1`, `global`, `unspecified`). */
343
+ const REGION = /^[a-z][a-z0-9-]{0,62}$/;
344
+
345
+ function validateProviderMetadata(
346
+ body: unknown,
347
+ ):
348
+ | { kind: 'ok'; value: ProviderMetadata }
349
+ | { kind: 'err'; error: { message: string; reason: string } } {
350
+ const b = body as Partial<ProviderMetadata> & Record<string, unknown>;
351
+ if (typeof b.id !== 'string' || b.id.length === 0) {
352
+ return { kind: 'err', error: { message: 'metadata.id required', reason: 'empty-id' } };
353
+ }
354
+ if (typeof b.region !== 'string' || b.region.length === 0) {
355
+ return {
356
+ kind: 'err',
357
+ error: { message: `provider "${b.id}" missing metadata.region`, reason: 'empty-region' },
358
+ };
359
+ }
360
+ // An adapter may build a hostname from the region (Vertex AI:
361
+ // `<region>-aiplatform.googleapis.com`), so it must stay one DNS label.
362
+ if (!REGION.test(b.region)) {
363
+ return {
364
+ kind: 'err',
365
+ error: {
366
+ message: `provider "${b.id}" metadata.region must be one DNS label: lowercase letters, digits and hyphens (e.g. us-central1)`,
367
+ reason: 'invalid-region',
368
+ },
369
+ };
370
+ }
371
+ if (!Array.isArray(b.models) || b.models.length === 0) {
372
+ return {
373
+ kind: 'err',
374
+ error: {
375
+ message: `provider "${b.id}" must expose at least one model in metadata.models[]`,
376
+ reason: 'empty-models',
377
+ },
378
+ };
379
+ }
380
+ const seenNames = new Set<string>();
381
+ const validatedModels: ModelInfo[] = [];
382
+ for (const rawModel of b.models) {
383
+ const modelResult = validateModelInfo(b.id, rawModel);
384
+ if (modelResult.kind === 'err') return modelResult;
385
+ if (seenNames.has(modelResult.value.name)) {
386
+ return {
387
+ kind: 'err',
388
+ error: {
389
+ message: `provider "${b.id}" declares model "${modelResult.value.name}" more than once in metadata.models[]`,
390
+ reason: 'duplicate-model-name',
391
+ },
392
+ };
393
+ }
394
+ seenNames.add(modelResult.value.name);
395
+ validatedModels.push(modelResult.value);
396
+ }
397
+ if (b.attributes !== undefined) {
398
+ if (!Array.isArray(b.attributes) || b.attributes.some((a) => typeof a !== 'string')) {
399
+ return {
400
+ kind: 'err',
401
+ error: {
402
+ message: `provider "${b.id}" attributes must be an array of strings`,
403
+ reason: 'invalid-attributes',
404
+ },
405
+ };
406
+ }
407
+ }
408
+ if (b.description !== undefined && typeof b.description !== 'string') {
409
+ return {
410
+ kind: 'err',
411
+ error: {
412
+ message: `provider "${b.id}" description must be a string`,
413
+ reason: 'invalid-description',
414
+ },
415
+ };
416
+ }
417
+ if (b.capabilityKind !== undefined && typeof b.capabilityKind !== 'string') {
418
+ return {
419
+ kind: 'err',
420
+ error: {
421
+ message: `provider "${b.id}" capabilityKind must be a string`,
422
+ reason: 'invalid-capability-kind',
423
+ },
424
+ };
425
+ }
426
+ if (b.fallback !== undefined && typeof b.fallback !== 'boolean') {
427
+ return {
428
+ kind: 'err',
429
+ error: {
430
+ message: `provider "${b.id}" fallback must be a boolean`,
431
+ reason: 'invalid-fallback',
432
+ },
433
+ };
434
+ }
435
+ const value: ProviderMetadata = {
436
+ id: b.id,
437
+ region: b.region,
438
+ models: validatedModels,
439
+ ...(b.attributes !== undefined && { attributes: b.attributes as readonly string[] }),
440
+ ...(b.description !== undefined && { description: b.description }),
441
+ ...(b.capabilityKind !== undefined && { capabilityKind: b.capabilityKind as string }),
442
+ ...(b.fallback !== undefined && { fallback: b.fallback as boolean }),
443
+ };
444
+ return { kind: 'ok', value };
445
+ }
446
+
447
+ /**
448
+ * Wire-shape validator for a single `ModelInfo` inside `metadata.models[]`.
449
+ * Enforces the same guardrails as `createProviderRegistry.validate()`
450
+ * plus the closed-enum `features` check (wire-only — the runtime
451
+ * primitive receives already-typed `Feature[]`).
452
+ */
453
+ function validateModelInfo(
454
+ providerId: string,
455
+ raw: unknown,
456
+ ): { kind: 'ok'; value: ModelInfo } | { kind: 'err'; error: { message: string; reason: string } } {
457
+ if (raw === null || typeof raw !== 'object') {
458
+ return {
459
+ kind: 'err',
460
+ error: {
461
+ message: `provider "${providerId}" metadata.models[] entries must be objects`,
462
+ reason: 'invalid-model-shape',
463
+ },
464
+ };
465
+ }
466
+ const m = raw as Partial<ModelInfo> & Record<string, unknown>;
467
+ if (typeof m.name !== 'string' || m.name.length === 0) {
468
+ return {
469
+ kind: 'err',
470
+ error: {
471
+ message: `provider "${providerId}" has a model with empty name`,
472
+ reason: 'empty-model-name',
473
+ },
474
+ };
475
+ }
476
+ if (
477
+ typeof m.contextWindow !== 'number' ||
478
+ m.contextWindow <= 0 ||
479
+ !Number.isInteger(m.contextWindow)
480
+ ) {
481
+ return {
482
+ kind: 'err',
483
+ error: {
484
+ message: `provider "${providerId}" model "${m.name}" contextWindow must be a positive integer`,
485
+ reason: 'invalid-context-window',
486
+ },
487
+ };
488
+ }
489
+ if (!Array.isArray(m.features)) {
490
+ return {
491
+ kind: 'err',
492
+ error: {
493
+ message: `provider "${providerId}" model "${m.name}" features must be an array`,
494
+ reason: 'invalid-features',
495
+ },
496
+ };
497
+ }
498
+ for (const f of m.features) {
499
+ if (typeof f !== 'string' || !(FEATURES as readonly string[]).includes(f)) {
500
+ return {
501
+ kind: 'err',
502
+ error: {
503
+ message: `provider "${providerId}" model "${m.name}" features contains unknown value "${String(f)}"`,
504
+ reason: 'unknown-feature',
505
+ },
506
+ };
507
+ }
508
+ }
509
+ const cost = m.cost as ModelInfo['cost'] | undefined;
510
+ if (
511
+ cost === undefined ||
512
+ typeof cost.promptUsdPer1kTokens !== 'number' ||
513
+ cost.promptUsdPer1kTokens < 0 ||
514
+ typeof cost.completionUsdPer1kTokens !== 'number' ||
515
+ cost.completionUsdPer1kTokens < 0
516
+ ) {
517
+ return {
518
+ kind: 'err',
519
+ error: {
520
+ message: `provider "${providerId}" model "${m.name}" cost table must have non-negative promptUsdPer1kTokens + completionUsdPer1kTokens`,
521
+ reason: 'invalid-cost',
522
+ },
523
+ };
524
+ }
525
+ if (m.p95LatencyMs !== undefined) {
526
+ if (typeof m.p95LatencyMs !== 'number' || m.p95LatencyMs < 0) {
527
+ return {
528
+ kind: 'err',
529
+ error: {
530
+ message: `provider "${providerId}" model "${m.name}" p95LatencyMs must be a non-negative number`,
531
+ reason: 'invalid-p95-latency',
532
+ },
533
+ };
534
+ }
535
+ }
536
+ if (m.maxOutputTokens !== undefined) {
537
+ if (
538
+ typeof m.maxOutputTokens !== 'number' ||
539
+ m.maxOutputTokens <= 0 ||
540
+ !Number.isInteger(m.maxOutputTokens)
541
+ ) {
542
+ return {
543
+ kind: 'err',
544
+ error: {
545
+ message: `provider "${providerId}" model "${m.name}" maxOutputTokens must be a positive integer`,
546
+ reason: 'invalid-max-output-tokens',
547
+ },
548
+ };
549
+ }
550
+ }
551
+ if (m.description !== undefined && typeof m.description !== 'string') {
552
+ return {
553
+ kind: 'err',
554
+ error: {
555
+ message: `provider "${providerId}" model "${m.name}" description must be a string`,
556
+ reason: 'invalid-description',
557
+ },
558
+ };
559
+ }
560
+ const value: ModelInfo = {
561
+ name: m.name,
562
+ contextWindow: m.contextWindow,
563
+ features: m.features as readonly Feature[],
564
+ cost: {
565
+ promptUsdPer1kTokens: cost.promptUsdPer1kTokens,
566
+ completionUsdPer1kTokens: cost.completionUsdPer1kTokens,
567
+ },
568
+ ...(m.p95LatencyMs !== undefined && { p95LatencyMs: m.p95LatencyMs }),
569
+ ...(m.maxOutputTokens !== undefined && { maxOutputTokens: m.maxOutputTokens }),
570
+ ...(m.description !== undefined && { description: m.description }),
571
+ };
572
+ return { kind: 'ok', value };
573
+ }
574
+
575
+ /**
576
+ * Parse the optional `adapter_config` on the register request body: a
577
+ * flat object of string, number or boolean values. Credentials don't
578
+ * belong here (they ride on `secret_ref`); the adapter validates its
579
+ * own keys when it is instantiated.
580
+ */
581
+ function parseAdapterConfig(
582
+ raw: unknown,
583
+ ):
584
+ | { readonly kind: 'ok'; readonly value: AdapterConfig | undefined }
585
+ | { readonly kind: 'err'; readonly error: string } {
586
+ if (raw === undefined || raw === null) return { kind: 'ok', value: undefined };
587
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
588
+ return { kind: 'err', error: '`adapter_config` must be an object.' };
589
+ }
590
+ const bad = Object.entries(raw).filter(
591
+ ([, v]) => typeof v !== 'string' && typeof v !== 'number' && typeof v !== 'boolean',
592
+ );
593
+ if (bad.length > 0) {
594
+ return {
595
+ kind: 'err',
596
+ error: `\`adapter_config\` values must be strings, numbers or booleans (${bad.map(([k]) => k).join(', ')}).`,
597
+ };
598
+ }
599
+ return { kind: 'ok', value: raw as AdapterConfig };
600
+ }
601
+
602
+ /**
603
+ * Parse the optional `secret_ref` on the register request body.
604
+ * Accepts `undefined` (no credential — dev-echo, local models),
605
+ * `{envName: string, name: string}`, or rejects any other shape.
606
+ */
607
+ function parseSecretRef(
608
+ raw: unknown,
609
+ ):
610
+ | { readonly kind: 'ok'; readonly value: ProviderSecretRef | undefined }
611
+ | { readonly kind: 'err'; readonly error: string } {
612
+ if (raw === undefined || raw === null) return { kind: 'ok', value: undefined };
613
+ if (typeof raw !== 'object') {
614
+ return { kind: 'err', error: '`secret_ref` must be an object with `envName` and `name`.' };
615
+ }
616
+ const r = raw as { readonly envName?: unknown; readonly name?: unknown };
617
+ if (typeof r.envName !== 'string' || r.envName.length === 0) {
618
+ return { kind: 'err', error: '`secret_ref.envName` must be a non-empty string.' };
619
+ }
620
+ if (typeof r.name !== 'string' || r.name.length === 0) {
621
+ return { kind: 'err', error: '`secret_ref.name` must be a non-empty string.' };
622
+ }
623
+ return { kind: 'ok', value: { envName: r.envName, name: r.name } };
624
+ }