@kindgi/api 0.1.4 → 0.1.5

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 (516) 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/cost-binding.d.ts +19 -0
  21. package/dist/cost-binding.d.ts.map +1 -1
  22. package/dist/cost-binding.js.map +1 -1
  23. package/dist/derive-agent-version.d.ts +7 -0
  24. package/dist/derive-agent-version.d.ts.map +1 -1
  25. package/dist/derive-agent-version.js +4 -0
  26. package/dist/derive-agent-version.js.map +1 -1
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +75 -7
  29. package/dist/errors.js.map +1 -1
  30. package/dist/eval-case-binding.d.ts +16 -4
  31. package/dist/eval-case-binding.d.ts.map +1 -1
  32. package/dist/eval-run-binding.d.ts +31 -0
  33. package/dist/eval-run-binding.d.ts.map +1 -1
  34. package/dist/eval-run-dispatcher.d.ts +7 -0
  35. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  36. package/dist/eval-run-dispatcher.js.map +1 -1
  37. package/dist/eval-sample.d.ts +11 -0
  38. package/dist/eval-sample.d.ts.map +1 -0
  39. package/dist/eval-sample.js +34 -0
  40. package/dist/eval-sample.js.map +1 -0
  41. package/dist/eval-suite-binding.d.ts +13 -0
  42. package/dist/eval-suite-binding.d.ts.map +1 -1
  43. package/dist/eval-suite-binding.js.map +1 -1
  44. package/dist/flow-binding.d.ts +18 -0
  45. package/dist/flow-binding.d.ts.map +1 -1
  46. package/dist/flow-pins.d.ts.map +1 -1
  47. package/dist/flow-pins.js +18 -2
  48. package/dist/flow-pins.js.map +1 -1
  49. package/dist/gate.d.ts.map +1 -1
  50. package/dist/gate.js +25 -0
  51. package/dist/gate.js.map +1 -1
  52. package/dist/handler-binding.d.ts +32 -0
  53. package/dist/handler-binding.d.ts.map +1 -1
  54. package/dist/hitl-binding.d.ts +23 -0
  55. package/dist/hitl-binding.d.ts.map +1 -1
  56. package/dist/identity-directory-binding.d.ts +82 -4
  57. package/dist/identity-directory-binding.d.ts.map +1 -1
  58. package/dist/identity-provider-binding.d.ts +197 -17
  59. package/dist/identity-provider-binding.d.ts.map +1 -1
  60. package/dist/improvement-pass-binding.d.ts +196 -0
  61. package/dist/improvement-pass-binding.d.ts.map +1 -0
  62. package/dist/improvement-pass-binding.js +9 -0
  63. package/dist/improvement-pass-binding.js.map +1 -0
  64. package/dist/index.d.ts +35 -17
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +11 -3
  67. package/dist/index.js.map +1 -1
  68. package/dist/judged-dispatcher.d.ts +25 -4
  69. package/dist/judged-dispatcher.d.ts.map +1 -1
  70. package/dist/judged-dispatcher.js +43 -6
  71. package/dist/judged-dispatcher.js.map +1 -1
  72. package/dist/judgment-binding.d.ts +25 -1
  73. package/dist/judgment-binding.d.ts.map +1 -1
  74. package/dist/mcp-endpoint-binding.d.ts +7 -0
  75. package/dist/mcp-endpoint-binding.d.ts.map +1 -1
  76. package/dist/memory-binding.d.ts +124 -17
  77. package/dist/memory-binding.d.ts.map +1 -1
  78. package/dist/memory-erasure-binding.d.ts +145 -0
  79. package/dist/memory-erasure-binding.d.ts.map +1 -0
  80. package/dist/memory-erasure-binding.js +4 -0
  81. package/dist/memory-erasure-binding.js.map +1 -0
  82. package/dist/middleware/auth.d.ts +66 -13
  83. package/dist/middleware/auth.d.ts.map +1 -1
  84. package/dist/middleware/auth.js +150 -50
  85. package/dist/middleware/auth.js.map +1 -1
  86. package/dist/middleware/authorize.d.ts +9 -0
  87. package/dist/middleware/authorize.d.ts.map +1 -1
  88. package/dist/middleware/authorize.js +122 -4
  89. package/dist/middleware/authorize.js.map +1 -1
  90. package/dist/middleware/error-mapper.d.ts +5 -0
  91. package/dist/middleware/error-mapper.d.ts.map +1 -1
  92. package/dist/middleware/error-mapper.js +14 -1
  93. package/dist/middleware/error-mapper.js.map +1 -1
  94. package/dist/middleware/idempotency.d.ts +70 -5
  95. package/dist/middleware/idempotency.d.ts.map +1 -1
  96. package/dist/middleware/idempotency.js +174 -41
  97. package/dist/middleware/idempotency.js.map +1 -1
  98. package/dist/middleware/key-project.d.ts +17 -0
  99. package/dist/middleware/key-project.d.ts.map +1 -0
  100. package/dist/middleware/key-project.js +75 -0
  101. package/dist/middleware/key-project.js.map +1 -0
  102. package/dist/middleware/principal.d.ts.map +1 -1
  103. package/dist/middleware/principal.js +9 -5
  104. package/dist/middleware/principal.js.map +1 -1
  105. package/dist/middleware/project-ref.d.ts.map +1 -1
  106. package/dist/middleware/project-ref.js +3 -0
  107. package/dist/middleware/project-ref.js.map +1 -1
  108. package/dist/openapi/generate.d.ts.map +1 -1
  109. package/dist/openapi/generate.js +5 -2
  110. package/dist/openapi/generate.js.map +1 -1
  111. package/dist/openapi/operations.d.ts.map +1 -1
  112. package/dist/openapi/operations.js +919 -140
  113. package/dist/openapi/operations.js.map +1 -1
  114. package/dist/openapi/schemas.d.ts +90 -13
  115. package/dist/openapi/schemas.d.ts.map +1 -1
  116. package/dist/openapi/schemas.js +2081 -359
  117. package/dist/openapi/schemas.js.map +1 -1
  118. package/dist/person-grants-binding.d.ts +77 -0
  119. package/dist/person-grants-binding.d.ts.map +1 -0
  120. package/dist/person-grants-binding.js +4 -0
  121. package/dist/person-grants-binding.js.map +1 -0
  122. package/dist/proposal-service.d.ts +121 -0
  123. package/dist/proposal-service.d.ts.map +1 -0
  124. package/dist/proposal-service.js +447 -0
  125. package/dist/proposal-service.js.map +1 -0
  126. package/dist/proposal-status.d.ts +60 -0
  127. package/dist/proposal-status.d.ts.map +1 -0
  128. package/dist/proposal-status.js +109 -0
  129. package/dist/proposal-status.js.map +1 -0
  130. package/dist/provider-binding.d.ts +10 -0
  131. package/dist/provider-binding.d.ts.map +1 -1
  132. package/dist/publish-refused.d.ts +28 -3
  133. package/dist/publish-refused.d.ts.map +1 -1
  134. package/dist/publish-refused.js +24 -3
  135. package/dist/publish-refused.js.map +1 -1
  136. package/dist/routes/adapters.d.ts +2 -1
  137. package/dist/routes/adapters.d.ts.map +1 -1
  138. package/dist/routes/adapters.js +3 -1
  139. package/dist/routes/adapters.js.map +1 -1
  140. package/dist/routes/agent-releases.d.ts +55 -3
  141. package/dist/routes/agent-releases.d.ts.map +1 -1
  142. package/dist/routes/agent-releases.js +85 -55
  143. package/dist/routes/agent-releases.js.map +1 -1
  144. package/dist/routes/agents.d.ts +12 -1
  145. package/dist/routes/agents.d.ts.map +1 -1
  146. package/dist/routes/agents.js +100 -2
  147. package/dist/routes/agents.js.map +1 -1
  148. package/dist/routes/approvals.d.ts +15 -3
  149. package/dist/routes/approvals.d.ts.map +1 -1
  150. package/dist/routes/approvals.js +133 -122
  151. package/dist/routes/approvals.js.map +1 -1
  152. package/dist/routes/artifacts.d.ts +25 -3
  153. package/dist/routes/artifacts.d.ts.map +1 -1
  154. package/dist/routes/artifacts.js +116 -7
  155. package/dist/routes/artifacts.js.map +1 -1
  156. package/dist/routes/auth.d.ts +25 -1
  157. package/dist/routes/auth.d.ts.map +1 -1
  158. package/dist/routes/auth.js +655 -281
  159. package/dist/routes/auth.js.map +1 -1
  160. package/dist/routes/blocks.d.ts.map +1 -1
  161. package/dist/routes/blocks.js +2 -42
  162. package/dist/routes/blocks.js.map +1 -1
  163. package/dist/routes/capabilities.d.ts +2 -1
  164. package/dist/routes/capabilities.d.ts.map +1 -1
  165. package/dist/routes/capabilities.js +6 -1
  166. package/dist/routes/capabilities.js.map +1 -1
  167. package/dist/routes/compliance.d.ts +9 -10
  168. package/dist/routes/compliance.d.ts.map +1 -1
  169. package/dist/routes/compliance.js +42 -61
  170. package/dist/routes/compliance.js.map +1 -1
  171. package/dist/routes/conversations.d.ts +8 -1
  172. package/dist/routes/conversations.d.ts.map +1 -1
  173. package/dist/routes/conversations.js +87 -8
  174. package/dist/routes/conversations.js.map +1 -1
  175. package/dist/routes/cost.d.ts +12 -1
  176. package/dist/routes/cost.d.ts.map +1 -1
  177. package/dist/routes/cost.js +74 -3
  178. package/dist/routes/cost.js.map +1 -1
  179. package/dist/routes/denied.d.ts +11 -0
  180. package/dist/routes/denied.d.ts.map +1 -0
  181. package/dist/routes/denied.js +17 -0
  182. package/dist/routes/denied.js.map +1 -0
  183. package/dist/routes/deployments.d.ts +10 -1
  184. package/dist/routes/deployments.d.ts.map +1 -1
  185. package/dist/routes/deployments.js +171 -13
  186. package/dist/routes/deployments.js.map +1 -1
  187. package/dist/routes/eval-comparison.d.ts.map +1 -1
  188. package/dist/routes/eval-comparison.js +69 -1
  189. package/dist/routes/eval-comparison.js.map +1 -1
  190. package/dist/routes/eval-overrides.d.ts +18 -0
  191. package/dist/routes/eval-overrides.d.ts.map +1 -0
  192. package/dist/routes/eval-overrides.js +81 -0
  193. package/dist/routes/eval-overrides.js.map +1 -0
  194. package/dist/routes/eval-runs.d.ts +10 -1
  195. package/dist/routes/eval-runs.d.ts.map +1 -1
  196. package/dist/routes/eval-runs.js +66 -7
  197. package/dist/routes/eval-runs.js.map +1 -1
  198. package/dist/routes/eval-suites.d.ts.map +1 -1
  199. package/dist/routes/eval-suites.js +28 -2
  200. package/dist/routes/eval-suites.js.map +1 -1
  201. package/dist/routes/event-triggers.d.ts +5 -1
  202. package/dist/routes/event-triggers.d.ts.map +1 -1
  203. package/dist/routes/event-triggers.js +26 -3
  204. package/dist/routes/event-triggers.js.map +1 -1
  205. package/dist/routes/export-signing-keys.d.ts +12 -0
  206. package/dist/routes/export-signing-keys.d.ts.map +1 -0
  207. package/dist/routes/export-signing-keys.js +24 -0
  208. package/dist/routes/export-signing-keys.js.map +1 -0
  209. package/dist/routes/flows.d.ts.map +1 -1
  210. package/dist/routes/flows.js +9 -1
  211. package/dist/routes/flows.js.map +1 -1
  212. package/dist/routes/gate-policies.d.ts +4 -1
  213. package/dist/routes/gate-policies.d.ts.map +1 -1
  214. package/dist/routes/gate-policies.js +29 -5
  215. package/dist/routes/gate-policies.js.map +1 -1
  216. package/dist/routes/guardrails.d.ts +16 -14
  217. package/dist/routes/guardrails.d.ts.map +1 -1
  218. package/dist/routes/guardrails.js +39 -3
  219. package/dist/routes/guardrails.js.map +1 -1
  220. package/dist/routes/identity.d.ts +20 -4
  221. package/dist/routes/identity.d.ts.map +1 -1
  222. package/dist/routes/identity.js +246 -6
  223. package/dist/routes/identity.js.map +1 -1
  224. package/dist/routes/improvement-passes.d.ts +52 -0
  225. package/dist/routes/improvement-passes.d.ts.map +1 -0
  226. package/dist/routes/improvement-passes.js +449 -0
  227. package/dist/routes/improvement-passes.js.map +1 -0
  228. package/dist/routes/judged-suites.d.ts +50 -0
  229. package/dist/routes/judged-suites.d.ts.map +1 -1
  230. package/dist/routes/judged-suites.js +66 -27
  231. package/dist/routes/judged-suites.js.map +1 -1
  232. package/dist/routes/judgment-context.d.ts +18 -2
  233. package/dist/routes/judgment-context.d.ts.map +1 -1
  234. package/dist/routes/judgment-context.js +63 -5
  235. package/dist/routes/judgment-context.js.map +1 -1
  236. package/dist/routes/judgment-flow-context.d.ts.map +1 -1
  237. package/dist/routes/judgment-flow-context.js +14 -2
  238. package/dist/routes/judgment-flow-context.js.map +1 -1
  239. package/dist/routes/judgments.d.ts.map +1 -1
  240. package/dist/routes/judgments.js +8 -1
  241. package/dist/routes/judgments.js.map +1 -1
  242. package/dist/routes/mcp.d.ts.map +1 -1
  243. package/dist/routes/mcp.js +26 -1
  244. package/dist/routes/mcp.js.map +1 -1
  245. package/dist/routes/memory-access.d.ts +43 -0
  246. package/dist/routes/memory-access.d.ts.map +1 -0
  247. package/dist/routes/memory-access.js +114 -0
  248. package/dist/routes/memory-access.js.map +1 -0
  249. package/dist/routes/memory-erasures.d.ts +25 -0
  250. package/dist/routes/memory-erasures.d.ts.map +1 -0
  251. package/dist/routes/memory-erasures.js +214 -0
  252. package/dist/routes/memory-erasures.js.map +1 -0
  253. package/dist/routes/memory-parse.d.ts +38 -0
  254. package/dist/routes/memory-parse.d.ts.map +1 -0
  255. package/dist/routes/memory-parse.js +199 -0
  256. package/dist/routes/memory-parse.js.map +1 -0
  257. package/dist/routes/memory.d.ts +9 -4
  258. package/dist/routes/memory.d.ts.map +1 -1
  259. package/dist/routes/memory.js +226 -234
  260. package/dist/routes/memory.js.map +1 -1
  261. package/dist/routes/observations.d.ts +4 -1
  262. package/dist/routes/observations.d.ts.map +1 -1
  263. package/dist/routes/observations.js +8 -2
  264. package/dist/routes/observations.js.map +1 -1
  265. package/dist/routes/pagination.d.ts +7 -0
  266. package/dist/routes/pagination.d.ts.map +1 -1
  267. package/dist/routes/pagination.js +10 -0
  268. package/dist/routes/pagination.js.map +1 -1
  269. package/dist/routes/policies.d.ts +2 -1
  270. package/dist/routes/policies.d.ts.map +1 -1
  271. package/dist/routes/policies.js +3 -1
  272. package/dist/routes/policies.js.map +1 -1
  273. package/dist/routes/project-mismatch.d.ts +22 -0
  274. package/dist/routes/project-mismatch.d.ts.map +1 -0
  275. package/dist/routes/project-mismatch.js +34 -0
  276. package/dist/routes/project-mismatch.js.map +1 -0
  277. package/dist/routes/projects.d.ts +15 -4
  278. package/dist/routes/projects.d.ts.map +1 -1
  279. package/dist/routes/projects.js +100 -9
  280. package/dist/routes/projects.js.map +1 -1
  281. package/dist/routes/proposals.d.ts +25 -17
  282. package/dist/routes/proposals.d.ts.map +1 -1
  283. package/dist/routes/proposals.js +340 -507
  284. package/dist/routes/proposals.js.map +1 -1
  285. package/dist/routes/provenance.d.ts +17 -3
  286. package/dist/routes/provenance.d.ts.map +1 -1
  287. package/dist/routes/provenance.js +79 -103
  288. package/dist/routes/provenance.js.map +1 -1
  289. package/dist/routes/providers.d.ts +17 -1
  290. package/dist/routes/providers.d.ts.map +1 -1
  291. package/dist/routes/providers.js +110 -3
  292. package/dist/routes/providers.js.map +1 -1
  293. package/dist/routes/public-run-tokens.d.ts.map +1 -1
  294. package/dist/routes/public-run-tokens.js +3 -0
  295. package/dist/routes/public-run-tokens.js.map +1 -1
  296. package/dist/routes/readable-projects.d.ts +26 -0
  297. package/dist/routes/readable-projects.d.ts.map +1 -0
  298. package/dist/routes/readable-projects.js +39 -0
  299. package/dist/routes/readable-projects.js.map +1 -0
  300. package/dist/routes/runs.d.ts +10 -0
  301. package/dist/routes/runs.d.ts.map +1 -1
  302. package/dist/routes/runs.js +92 -42
  303. package/dist/routes/runs.js.map +1 -1
  304. package/dist/routes/schedules.d.ts +21 -13
  305. package/dist/routes/schedules.d.ts.map +1 -1
  306. package/dist/routes/schedules.js +416 -55
  307. package/dist/routes/schedules.js.map +1 -1
  308. package/dist/routes/segments.d.ts +2 -0
  309. package/dist/routes/segments.d.ts.map +1 -1
  310. package/dist/routes/segments.js +5 -0
  311. package/dist/routes/segments.js.map +1 -1
  312. package/dist/routes/service-accounts.d.ts +17 -0
  313. package/dist/routes/service-accounts.d.ts.map +1 -0
  314. package/dist/routes/service-accounts.js +212 -0
  315. package/dist/routes/service-accounts.js.map +1 -0
  316. package/dist/routes/sign-in-options.d.ts +50 -0
  317. package/dist/routes/sign-in-options.d.ts.map +1 -0
  318. package/dist/routes/sign-in-options.js +98 -0
  319. package/dist/routes/sign-in-options.js.map +1 -0
  320. package/dist/routes/signing-keys.d.ts +2 -1
  321. package/dist/routes/signing-keys.d.ts.map +1 -1
  322. package/dist/routes/signing-keys.js +3 -1
  323. package/dist/routes/signing-keys.js.map +1 -1
  324. package/dist/routes/tenant-access.d.ts +13 -0
  325. package/dist/routes/tenant-access.d.ts.map +1 -0
  326. package/dist/routes/tenant-access.js +26 -0
  327. package/dist/routes/tenant-access.js.map +1 -0
  328. package/dist/routes/tenant.d.ts.map +1 -1
  329. package/dist/routes/tenant.js +4 -0
  330. package/dist/routes/tenant.js.map +1 -1
  331. package/dist/routes/token-sign-in.d.ts +36 -0
  332. package/dist/routes/token-sign-in.d.ts.map +1 -0
  333. package/dist/routes/token-sign-in.js +101 -0
  334. package/dist/routes/token-sign-in.js.map +1 -0
  335. package/dist/routes/tokens.d.ts +15 -5
  336. package/dist/routes/tokens.d.ts.map +1 -1
  337. package/dist/routes/tokens.js +162 -43
  338. package/dist/routes/tokens.js.map +1 -1
  339. package/dist/routes/tools.d.ts.map +1 -1
  340. package/dist/routes/tools.js +9 -1
  341. package/dist/routes/tools.js.map +1 -1
  342. package/dist/routes/trigger-access.d.ts +29 -0
  343. package/dist/routes/trigger-access.d.ts.map +1 -0
  344. package/dist/routes/trigger-access.js +33 -0
  345. package/dist/routes/trigger-access.js.map +1 -0
  346. package/dist/routes/webhook-endpoints.d.ts +2 -1
  347. package/dist/routes/webhook-endpoints.d.ts.map +1 -1
  348. package/dist/routes/webhook-endpoints.js +11 -3
  349. package/dist/routes/webhook-endpoints.js.map +1 -1
  350. package/dist/routes/webhooks.d.ts +5 -1
  351. package/dist/routes/webhooks.d.ts.map +1 -1
  352. package/dist/routes/webhooks.js +25 -2
  353. package/dist/routes/webhooks.js.map +1 -1
  354. package/dist/run-failure.d.ts +21 -0
  355. package/dist/run-failure.d.ts.map +1 -0
  356. package/dist/run-failure.js +29 -0
  357. package/dist/run-failure.js.map +1 -0
  358. package/dist/service-account-binding.d.ts +108 -0
  359. package/dist/service-account-binding.d.ts.map +1 -0
  360. package/dist/service-account-binding.js +4 -0
  361. package/dist/service-account-binding.js.map +1 -0
  362. package/dist/session-store-binding.d.ts +61 -13
  363. package/dist/session-store-binding.d.ts.map +1 -1
  364. package/dist/signed-export.d.ts +89 -0
  365. package/dist/signed-export.d.ts.map +1 -0
  366. package/dist/signed-export.js +149 -0
  367. package/dist/signed-export.js.map +1 -0
  368. package/dist/supervisor-binding.d.ts +186 -413
  369. package/dist/supervisor-binding.d.ts.map +1 -1
  370. package/dist/testing/app-bindings.d.ts +33 -0
  371. package/dist/testing/app-bindings.d.ts.map +1 -0
  372. package/dist/testing/app-bindings.js +112 -0
  373. package/dist/testing/app-bindings.js.map +1 -0
  374. package/dist/testing/index.d.ts +11 -0
  375. package/dist/testing/index.d.ts.map +1 -0
  376. package/dist/testing/index.js +13 -0
  377. package/dist/testing/index.js.map +1 -0
  378. package/dist/testing/stub-binding.d.ts +34 -0
  379. package/dist/testing/stub-binding.d.ts.map +1 -0
  380. package/dist/testing/stub-binding.js +42 -0
  381. package/dist/testing/stub-binding.js.map +1 -0
  382. package/dist/testing/trigger-registry.d.ts +21 -0
  383. package/dist/testing/trigger-registry.d.ts.map +1 -0
  384. package/dist/testing/trigger-registry.js +206 -0
  385. package/dist/testing/trigger-registry.js.map +1 -0
  386. package/dist/token-admin.d.ts +46 -8
  387. package/dist/token-admin.d.ts.map +1 -1
  388. package/dist/token-admin.js.map +1 -1
  389. package/dist/tool-binding.d.ts +13 -0
  390. package/dist/tool-binding.d.ts.map +1 -1
  391. package/dist/trigger-binding.d.ts +2 -2
  392. package/dist/trigger-binding.d.ts.map +1 -1
  393. package/dist/trigger-binding.js +1 -1
  394. package/dist/trigger-binding.js.map +1 -1
  395. package/dist/types.d.ts +16 -0
  396. package/dist/types.d.ts.map +1 -1
  397. package/dist/webhook-endpoint-binding.d.ts +19 -3
  398. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  399. package/dist/webhook-endpoint-binding.js +1 -1
  400. package/dist/webhook-endpoint-binding.js.map +1 -1
  401. package/openapi.json +15387 -8789
  402. package/package.json +26 -22
  403. package/src/agent-binding.ts +14 -0
  404. package/src/agent-pins.ts +18 -2
  405. package/src/app.ts +366 -80
  406. package/src/block-publish.ts +181 -0
  407. package/src/caller.ts +62 -0
  408. package/src/capability-binding.ts +12 -0
  409. package/src/cost-binding.ts +19 -0
  410. package/src/derive-agent-version.ts +9 -1
  411. package/src/errors.ts +75 -7
  412. package/src/eval-case-binding.ts +17 -1
  413. package/src/eval-run-binding.ts +31 -0
  414. package/src/eval-run-dispatcher.ts +7 -0
  415. package/src/eval-sample.ts +42 -0
  416. package/src/eval-suite-binding.ts +14 -0
  417. package/src/flow-binding.ts +19 -0
  418. package/src/flow-pins.ts +18 -2
  419. package/src/gate.ts +26 -0
  420. package/src/handler-binding.ts +36 -1
  421. package/src/hitl-binding.ts +24 -0
  422. package/src/identity-directory-binding.ts +85 -4
  423. package/src/identity-provider-binding.ts +216 -21
  424. package/src/improvement-pass-binding.ts +193 -0
  425. package/src/index.ts +153 -31
  426. package/src/judged-dispatcher.ts +78 -11
  427. package/src/judgment-binding.ts +25 -1
  428. package/src/mcp-endpoint-binding.ts +7 -0
  429. package/src/memory-binding.ts +121 -17
  430. package/src/memory-erasure-binding.ts +156 -0
  431. package/src/middleware/auth.ts +228 -62
  432. package/src/middleware/authorize.ts +155 -3
  433. package/src/middleware/error-mapper.ts +15 -1
  434. package/src/middleware/idempotency.ts +230 -43
  435. package/src/middleware/key-project.ts +86 -0
  436. package/src/middleware/principal.ts +9 -5
  437. package/src/middleware/project-ref.ts +3 -0
  438. package/src/openapi/generate.ts +11 -2
  439. package/src/openapi/operations.ts +1060 -143
  440. package/src/openapi/schemas.ts +2387 -469
  441. package/src/person-grants-binding.ts +76 -0
  442. package/src/proposal-service.ts +640 -0
  443. package/src/proposal-status.ts +176 -0
  444. package/src/provider-binding.ts +10 -0
  445. package/src/publish-refused.ts +56 -9
  446. package/src/routes/adapters.ts +4 -0
  447. package/src/routes/agent-releases.ts +121 -69
  448. package/src/routes/agents.ts +128 -1
  449. package/src/routes/approvals.ts +164 -154
  450. package/src/routes/artifacts.ts +181 -11
  451. package/src/routes/auth.ts +804 -336
  452. package/src/routes/blocks.ts +2 -53
  453. package/src/routes/capabilities.ts +10 -1
  454. package/src/routes/compliance.ts +60 -99
  455. package/src/routes/conversations.ts +101 -7
  456. package/src/routes/cost.ts +110 -4
  457. package/src/routes/denied.ts +28 -0
  458. package/src/routes/deployments.ts +210 -17
  459. package/src/routes/eval-comparison.ts +81 -2
  460. package/src/routes/eval-overrides.ts +108 -0
  461. package/src/routes/eval-runs.ts +89 -6
  462. package/src/routes/eval-suites.ts +32 -2
  463. package/src/routes/event-triggers.ts +27 -3
  464. package/src/routes/export-signing-keys.ts +31 -0
  465. package/src/routes/flows.ts +12 -1
  466. package/src/routes/gate-policies.ts +37 -6
  467. package/src/routes/guardrails.ts +61 -2
  468. package/src/routes/identity.ts +328 -10
  469. package/src/routes/improvement-passes.ts +541 -0
  470. package/src/routes/judged-suites.ts +113 -43
  471. package/src/routes/judgment-context.ts +76 -5
  472. package/src/routes/judgment-flow-context.ts +16 -2
  473. package/src/routes/judgments.ts +17 -3
  474. package/src/routes/mcp.ts +29 -1
  475. package/src/routes/memory-access.ts +160 -0
  476. package/src/routes/memory-erasures.ts +240 -0
  477. package/src/routes/memory-parse.ts +250 -0
  478. package/src/routes/memory.ts +244 -286
  479. package/src/routes/observations.ts +15 -2
  480. package/src/routes/pagination.ts +12 -0
  481. package/src/routes/policies.ts +7 -1
  482. package/src/routes/project-mismatch.ts +56 -0
  483. package/src/routes/projects.ts +107 -13
  484. package/src/routes/proposals.ts +370 -611
  485. package/src/routes/provenance.ts +99 -133
  486. package/src/routes/providers.ts +142 -3
  487. package/src/routes/public-run-tokens.ts +3 -0
  488. package/src/routes/readable-projects.ts +66 -0
  489. package/src/routes/runs.ts +119 -39
  490. package/src/routes/schedules.ts +472 -60
  491. package/src/routes/segments.ts +11 -0
  492. package/src/routes/service-accounts.ts +262 -0
  493. package/src/routes/sign-in-options.ts +168 -0
  494. package/src/routes/signing-keys.ts +7 -1
  495. package/src/routes/tenant-access.ts +37 -0
  496. package/src/routes/tenant.ts +6 -0
  497. package/src/routes/token-sign-in.ts +161 -0
  498. package/src/routes/tokens.ts +172 -46
  499. package/src/routes/tools.ts +12 -1
  500. package/src/routes/trigger-access.ts +72 -0
  501. package/src/routes/webhook-endpoints.ts +15 -3
  502. package/src/routes/webhooks.ts +26 -2
  503. package/src/run-failure.ts +42 -0
  504. package/src/service-account-binding.ts +113 -0
  505. package/src/session-store-binding.ts +65 -13
  506. package/src/signed-export.ts +250 -0
  507. package/src/supervisor-binding.ts +169 -409
  508. package/src/testing/app-bindings.ts +142 -0
  509. package/src/testing/index.ts +21 -0
  510. package/src/testing/stub-binding.ts +53 -0
  511. package/src/testing/trigger-registry.ts +259 -0
  512. package/src/token-admin.ts +40 -8
  513. package/src/tool-binding.ts +14 -0
  514. package/src/trigger-binding.ts +8 -1
  515. package/src/types.ts +16 -0
  516. package/src/webhook-endpoint-binding.ts +18 -3
@@ -1,581 +1,414 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  import { Hono } from 'hono';
4
+ import { ref } from '@kindgi/authz';
4
5
  import { statusFor, toWireError } from '../errors.js';
6
+ import { createProposalService, proposalNotFound, } from '../proposal-service.js';
7
+ import { FIX_PROPOSAL_STATUSES, } from '../proposal-status.js';
8
+ import { actorOf, promotionResponse, scopeFromQuery } from './agent-releases.js';
9
+ import { parseComparison } from './eval-comparison.js';
10
+ import { liveScopeToWire, parseLiveScopeBody } from './live-scope-wire.js';
5
11
  import { clampLimit } from './pagination.js';
6
- import { parseScopeParams } from './scope-params.js';
7
- const FIX_PROPOSAL_STATUSES = new Set([
8
- 'draft',
9
- 'dry-running',
10
- 'dry-run-passed',
11
- 'dry-run-failed',
12
- 'proposed-for-review',
13
- 'approved',
14
- 'rejected',
15
- 'applied',
16
- 'rolled-back',
17
- 'withdrawn',
18
- ]);
19
- const PROPOSAL_TIERS = new Set([
20
- 'prompt',
21
- 'retrieval',
22
- 'tool-config',
23
- ]);
24
- const REVIEWER_ROLES = new Set([
25
- 'standard',
26
- 'senior',
27
- 'admin',
28
- ]);
12
+ const TIERS = ['settings-block', 'prompt-block'];
13
+ const OBJECTIVES = ['weightedYesShare', 'weightedPrecisionAtK'];
14
+ const MAX_TEXT = 2000;
29
15
  /**
30
- * Supervisor proposals resource. Ships the full self-fix lifecycle
31
- * over HTTP: draft → dry-run → submit-review → apply / rollback /
32
- * withdraw — the complete supervisor loop.
16
+ * Improvement proposals (`/v1/proposals`): a change to one data block an
17
+ * agent version pins (new settings values, or a new prompt template),
18
+ * for one live scope, taken through the same comparison, gate and
19
+ * promotion as any other version (`createProposalService`).
33
20
  *
34
- * Persistence + runtime wiring is caller-plugged via
35
- * `SupervisorBinding` — the API package doesn't own supervisor
36
- * runtime, agent registry, HITL wiring, or eval invocation.
21
+ * GET / list (statuses derived): by agent, tier, status and live scope
22
+ * GET /:id one
23
+ * POST / a hand-written proposal (a draft)
24
+ * POST /:id/evaluate publish the block version and derive the agent
25
+ * version (inert until promoted), then compare it
26
+ * on a test set (202)
27
+ * POST /:id/request a gated promotion of the candidate for the scope
28
+ * (201 promoted, 202 in review, 422 gate-failed)
29
+ * POST /:id/rollback the scope goes back to what served it before
30
+ * POST /:id/withdraw closed by a person
37
31
  *
38
- * `supervisorId` scoping: every route requires an `X-Supervisor-Id`
39
- * request header. Missing / empty → `400 supervisor-header-missing`.
40
- *
41
- * State transitions: attempts to advance a proposal from a status
42
- * the runtime won't accept (e.g., apply on a proposal still in
43
- * `dry-running`) surface as `409 proposal-invalid-state-transition`.
44
- * This is a caller/state conflict per `docs/API-ROUTE-CONVENTIONS.md`
45
- * §4.3 — the request was well-formed but the resource is not in
46
- * the required state.
32
+ * Authorized on the proposal's agent: reading is `read`, drafting,
33
+ * evaluating and withdrawing are `publish` (they make versions), and
34
+ * requesting and rolling back are `promote`. A proposal the caller can't
35
+ * read answers 404, as one that doesn't exist.
47
36
  */
48
- export function proposalsRouter(binding) {
37
+ export function proposalsRouter(store, deps, authorizer, mount) {
49
38
  const r = new Hono();
50
- // ---------- supervisor-id gate for the whole resource ----------
51
- r.use('*', async (c, next) => {
52
- const requestId = c.get('requestId');
53
- const supervisorId = c.req.header('x-supervisor-id');
54
- if (supervisorId === undefined || supervisorId.length === 0) {
55
- c.status(statusFor('supervisor-header-missing'));
56
- return c.json(toWireError({
57
- code: 'supervisor-header-missing',
58
- message: 'X-Supervisor-Id header is required on all /v1/proposals routes; supply the SupervisorId scoping the request.',
59
- }, requestId));
60
- }
61
- await next();
62
- return;
63
- });
64
- // ---------- GET / (list, cursor-paginated) ----------
39
+ const service = createProposalService({ ...deps, store });
40
+ // Routes mounted before `/:proposalId` (an improvement pass's `improve`).
41
+ mount?.(r, service);
42
+ /** `undefined` when allowed; else the 403. */
43
+ async function deny(c, action, agentId) {
44
+ if (authorizer === undefined)
45
+ return undefined;
46
+ const decision = await authorizer.check(c, action, ref('agent', agentId));
47
+ if (decision.allowed)
48
+ return undefined;
49
+ return fail(c, 'permission-denied', {
50
+ code: 'permission-denied',
51
+ message: `Permission denied: this needs ${action} on agent "${agentId}" (${decision.reason})`,
52
+ });
53
+ }
54
+ /** The proposal, if it exists and the caller may read it (else the 404). */
55
+ async function load(c) {
56
+ const proposalId = c.req.param('proposalId') ?? '';
57
+ const stored = await store.getProposal({
58
+ tenantId: c.get('tenantId'),
59
+ proposalId: proposalId,
60
+ });
61
+ const hidden = stored !== null &&
62
+ authorizer !== undefined &&
63
+ !(await authorizer.can(c, 'read', ref('agent', stored.agentId)));
64
+ if (stored === null || hidden)
65
+ return failWith(c, proposalNotFound(proposalId));
66
+ return stored;
67
+ }
68
+ async function answer(c, stored, status = 200) {
69
+ const f = await service.facts(c.get('tenantId'))(stored);
70
+ c.status(status);
71
+ return c.json(serialize(stored, f));
72
+ }
73
+ /** Read the body and the proposal, and check the caller may `action` it. */
74
+ async function prepare(c, action) {
75
+ const body = await readBody(c);
76
+ if (body === undefined)
77
+ return badInput(c, 'Request body must be a JSON object');
78
+ const proposal = await load(c);
79
+ if (proposal instanceof Response)
80
+ return proposal;
81
+ const denied = await deny(c, action, proposal.agentId);
82
+ return denied ?? { body, proposal };
83
+ }
84
+ // ---------- GET / ----------
65
85
  r.get('/', async (c) => {
66
- const requestId = c.get('requestId');
67
86
  const tenantId = c.get('tenantId');
68
- const supervisorId = c.req.header('x-supervisor-id');
69
- const limit = clampLimit(c.req.query('limit'));
70
- const cursorRaw = c.req.query('cursor');
71
- const statusRaw = c.req.query('status');
72
- const agentIdRaw = c.req.query('agentId');
73
- const tierRaw = c.req.query('tier');
74
- let status;
75
- if (statusRaw !== undefined && statusRaw.length > 0) {
76
- if (!FIX_PROPOSAL_STATUSES.has(statusRaw)) {
77
- c.status(statusFor('bad-input'));
78
- return c.json(toWireError({ code: 'bad-input', message: `Unknown \`status\` value: ${statusRaw}` }, requestId));
79
- }
80
- status = statusRaw;
81
- }
82
- let tier;
83
- if (tierRaw !== undefined && tierRaw.length > 0) {
84
- if (!PROPOSAL_TIERS.has(tierRaw)) {
85
- c.status(statusFor('bad-input'));
86
- return c.json(toWireError({ code: 'bad-input', message: `Unknown \`tier\` value: ${tierRaw}` }, requestId));
87
- }
88
- tier = tierRaw;
89
- }
90
- const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
91
- if (scopeParsed.kind === 'err') {
92
- c.status(statusFor('scope-invalid'));
93
- return c.json(toWireError({ code: 'scope-invalid', message: scopeParsed.message }, requestId));
94
- }
95
- const page = await binding.listProposals({
87
+ const status = c.req.query('status');
88
+ if (status !== undefined && !FIX_PROPOSAL_STATUSES.includes(status)) {
89
+ return badInput(c, `Unknown \`status\`: ${status}`);
90
+ }
91
+ const tier = c.req.query('tier');
92
+ if (tier !== undefined && !TIERS.includes(tier)) {
93
+ return badInput(c, `Unknown \`tier\`: ${tier} (one of ${TIERS.join(', ')})`);
94
+ }
95
+ const scope = scopeFromQuery((n) => c.req.query(n), c.req.queries('segment') ?? []);
96
+ if (scope.kind === 'err')
97
+ return badInput(c, scope.message);
98
+ const agentId = c.req.query('agentId');
99
+ const cursor = c.req.query('cursor');
100
+ const page = await store.listProposals({
96
101
  tenantId,
97
- supervisorId,
98
- limit,
99
- ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw }),
100
- ...(status !== undefined && { status }),
101
- ...(agentIdRaw !== undefined && agentIdRaw.length > 0 && { agentId: agentIdRaw }),
102
- ...(tier !== undefined && { tier }),
103
- ...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
104
- ...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
102
+ limit: clampLimit(c.req.query('limit')),
103
+ ...(cursor !== undefined && cursor !== '' && { cursor: cursor }),
104
+ ...(agentId !== undefined && agentId !== '' && { agentId: agentId }),
105
+ ...(tier !== undefined && { tier: tier }),
106
+ ...(scope.scope !== undefined && { liveScope: scope.scope }),
105
107
  });
108
+ const readable = authorizer === undefined
109
+ ? page.data
110
+ : await authorizer.filterByCan(c, 'read', page.data, (p) => ref('agent', p.agentId));
111
+ const read = service.facts(tenantId);
112
+ const rows = await Promise.all(readable.map(async (p) => serialize(p, await read(p))));
106
113
  return c.json({
107
- data: page.data.map(serializeProposal),
114
+ // A status filter applies after deriving, so a page can hold fewer rows than `limit`.
115
+ data: status === undefined ? rows : rows.filter((row) => row.status === status),
108
116
  hasMore: page.nextCursor !== undefined,
109
117
  ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor }),
110
118
  });
111
119
  });
112
120
  // ---------- GET /:proposalId ----------
113
121
  r.get('/:proposalId', async (c) => {
114
- const requestId = c.get('requestId');
115
- const tenantId = c.get('tenantId');
116
- const supervisorId = c.req.header('x-supervisor-id');
117
- const proposalId = c.req.param('proposalId');
118
- const proposal = await binding.getProposal({ tenantId, supervisorId, proposalId });
119
- if (proposal === null) {
120
- return proposalNotFound(c, requestId, proposalId);
121
- }
122
- return c.json(serializeProposal(proposal));
122
+ const stored = await load(c);
123
+ if (stored instanceof Response)
124
+ return stored;
125
+ return answer(c, stored);
123
126
  });
124
- // ---------- POST / (draft) ----------
127
+ // ---------- POST / (a hand-written proposal) ----------
125
128
  r.post('/', async (c) => {
126
- const requestId = c.get('requestId');
127
- const tenantId = c.get('tenantId');
128
- const supervisorId = c.req.header('x-supervisor-id');
129
- let body;
130
- try {
131
- body = await c.req.json();
132
- }
133
- catch {
134
- return badInput(c, requestId, 'Request body must be valid JSON');
135
- }
136
- const parsed = parseDraftBody(body);
137
- if (parsed.kind === 'err') {
138
- return badInput(c, requestId, parsed.message);
139
- }
140
- const outcome = await binding.draftProposal({
141
- tenantId,
142
- supervisorId,
143
- agentId: parsed.value.agentId,
144
- agentVersion: parsed.value.agentVersion,
145
- tier: parsed.value.tier,
146
- change: parsed.value.change,
147
- patternRefs: parsed.value.patternRefs,
148
- hypothesis: parsed.value.hypothesis,
149
- proposerRuleId: parsed.value.proposerRuleId,
129
+ const body = await readBody(c);
130
+ if (body === undefined)
131
+ return badInput(c, 'Request body must be a JSON object');
132
+ const parsed = parseCreateBody(body);
133
+ if (typeof parsed === 'string')
134
+ return badInput(c, parsed);
135
+ const denied = await deny(c, 'publish', parsed.agentId);
136
+ if (denied !== undefined)
137
+ return denied;
138
+ const actor = actorOf(c);
139
+ const outcome = await service.draft({
140
+ tenantId: c.get('tenantId'),
141
+ agentId: parsed.agentId,
142
+ fromVersion: parsed.fromVersion,
143
+ scope: parsed.scope,
144
+ tier: parsed.tier,
145
+ blockId: parsed.blockId,
146
+ content: parsed.content,
147
+ hypothesis: parsed.hypothesis,
148
+ ...(parsed.judgmentIds !== undefined && { evidence: { judgmentIds: parsed.judgmentIds } }),
149
+ drafter: { kind: 'person', by: `${actor.kind}:${actor.id}` },
150
150
  });
151
- // Both `ok` and `dedup` return 201 — the caller ends up with a
152
- // proposal id it can advance. Signal dedup via a header so
153
- // consumers that care can distinguish (mirrors the
154
- // X-Idempotent-Replay pattern from the idempotency middleware).
155
- if (outcome.kind === 'dedup') {
151
+ if (outcome.kind === 'err')
152
+ return failWith(c, outcome.error);
153
+ if (outcome.value.deduped) {
156
154
  c.header('X-Proposal-Deduped', 'true');
155
+ return answer(c, outcome.value.proposal);
157
156
  }
158
- c.status(201);
159
- return c.json(serializeProposal(outcome.proposal));
157
+ return answer(c, outcome.value.proposal, 201);
160
158
  });
161
- // ---------- POST /:proposalId/dry-run ----------
162
- r.post('/:proposalId/dry-run', async (c) => {
163
- const requestId = c.get('requestId');
164
- const tenantId = c.get('tenantId');
165
- const supervisorId = c.req.header('x-supervisor-id');
166
- const proposalId = c.req.param('proposalId');
167
- let body;
168
- try {
169
- body = await c.req.json();
170
- }
171
- catch {
172
- return badInput(c, requestId, 'Request body must be valid JSON');
173
- }
174
- const parsed = parseDryRunBody(body);
175
- if (parsed.kind === 'err') {
176
- return badInput(c, requestId, parsed.message);
177
- }
178
- const outcome = await binding.dryRunProposal({
179
- tenantId,
180
- supervisorId,
181
- proposalId,
182
- datasetId: parsed.value.datasetId,
183
- datasetVersion: parsed.value.datasetVersion,
184
- criterion: parsed.value.criterion,
185
- });
186
- if (outcome.kind === 'not-found') {
187
- return proposalNotFound(c, requestId, proposalId);
188
- }
189
- if (outcome.kind === 'invalid-transition') {
190
- return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
191
- }
192
- if (outcome.kind === 'runtime-error') {
193
- return runtimeError(c, requestId, outcome.code, outcome.message);
194
- }
195
- return c.json({
196
- proposal: serializeProposal(outcome.proposal),
197
- passed: outcome.passed,
198
- });
199
- });
200
- // ---------- POST /:proposalId/submit-review ----------
201
- r.post('/:proposalId/submit-review', async (c) => {
202
- const requestId = c.get('requestId');
203
- const tenantId = c.get('tenantId');
204
- const supervisorId = c.req.header('x-supervisor-id');
205
- const proposalId = c.req.param('proposalId');
206
- // Body is optional — every field on submit-review is an override.
207
- let body = {};
208
- try {
209
- const raw = await c.req.text();
210
- if (raw.length > 0)
211
- body = JSON.parse(raw);
212
- }
213
- catch {
214
- return badInput(c, requestId, 'Request body must be valid JSON');
215
- }
216
- const parsed = parseSubmitReviewBody(body);
217
- if (parsed.kind === 'err') {
218
- return badInput(c, requestId, parsed.message);
219
- }
220
- const outcome = await binding.submitReview({
221
- tenantId,
222
- supervisorId,
223
- proposalId,
224
- ...(parsed.value.requiredRole !== undefined && { requiredRole: parsed.value.requiredRole }),
225
- ...(parsed.value.expiresAt !== undefined && { expiresAt: parsed.value.expiresAt }),
226
- });
227
- if (outcome.kind === 'not-found') {
228
- return proposalNotFound(c, requestId, proposalId);
229
- }
230
- if (outcome.kind === 'invalid-transition') {
231
- return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
232
- }
233
- if (outcome.kind === 'ground-layer-violation') {
234
- c.status(statusFor('ground-layer-violation'));
235
- return c.json(toWireError({
236
- code: 'ground-layer-violation',
237
- message: `Proposal ${outcome.proposalId} violated ground guardrail ${outcome.guardrailId}: ${outcome.reason}`,
238
- proposalId: outcome.proposalId,
239
- guardrailId: outcome.guardrailId,
240
- reason: outcome.reason,
241
- }, requestId));
242
- }
243
- if (outcome.kind === 'runtime-error') {
244
- return runtimeError(c, requestId, outcome.code, outcome.message);
245
- }
246
- return c.json({
247
- proposal: serializeProposal(outcome.proposal),
248
- approvalId: outcome.approvalId,
249
- metaFix: outcome.metaFix,
159
+ // ---------- POST /:proposalId/evaluate ----------
160
+ r.post('/:proposalId/evaluate', async (c) => {
161
+ const body = await readBody(c);
162
+ if (body === undefined)
163
+ return badInput(c, 'Request body must be a JSON object');
164
+ const parsed = parseEvaluateBody(body);
165
+ if (typeof parsed === 'string')
166
+ return badInput(c, parsed);
167
+ const ready = await prepare(c, 'publish');
168
+ if (ready instanceof Response)
169
+ return ready;
170
+ const outcome = await service.evaluate({
171
+ tenantId: c.get('tenantId'),
172
+ proposal: ready.proposal,
173
+ suiteId: parsed.suiteId,
174
+ objective: parsed.objective,
175
+ ...(parsed.comparison !== undefined && { comparison: parsed.comparison }),
176
+ actor: actorOf(c),
250
177
  });
178
+ if (outcome.kind === 'err')
179
+ return failWith(c, outcome.error);
180
+ return answer(c, outcome.value, 202);
251
181
  });
252
- // ---------- POST /:proposalId/apply ----------
253
- r.post('/:proposalId/apply', async (c) => {
254
- const requestId = c.get('requestId');
255
- const tenantId = c.get('tenantId');
256
- const supervisorId = c.req.header('x-supervisor-id');
257
- const proposalId = c.req.param('proposalId');
258
- let body = {};
259
- try {
260
- const raw = await c.req.text();
261
- if (raw.length > 0)
262
- body = JSON.parse(raw);
263
- }
264
- catch {
265
- return badInput(c, requestId, 'Request body must be valid JSON');
266
- }
267
- const parsed = parseApplyBody(body);
268
- if (parsed.kind === 'err') {
269
- return badInput(c, requestId, parsed.message);
270
- }
271
- const outcome = await binding.applyProposal({
272
- tenantId,
273
- supervisorId,
274
- proposalId,
275
- ...(parsed.value.newVersion !== undefined && { newVersion: parsed.value.newVersion }),
276
- });
277
- if (outcome.kind === 'not-found') {
278
- return proposalNotFound(c, requestId, proposalId);
279
- }
280
- if (outcome.kind === 'invalid-transition') {
281
- return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
282
- }
283
- if (outcome.kind === 'runtime-error') {
284
- return runtimeError(c, requestId, outcome.code, outcome.message);
285
- }
286
- return c.json({
287
- proposalId: outcome.proposalId,
288
- appliedVersion: outcome.appliedVersion,
289
- appliedAt: outcome.appliedAt,
182
+ // ---------- POST /:proposalId/request ----------
183
+ r.post('/:proposalId/request', async (c) => {
184
+ const ready = await prepare(c, 'promote');
185
+ if (ready instanceof Response)
186
+ return ready;
187
+ const reason = optionalText(ready.body, 'reason');
188
+ if (reason.kind === 'err')
189
+ return badInput(c, reason.message);
190
+ const outcome = await service.request({
191
+ tenantId: c.get('tenantId'),
192
+ proposal: ready.proposal,
193
+ actor: actorOf(c),
194
+ ...(reason.value !== undefined && { reason: reason.value }),
290
195
  });
196
+ if (outcome.kind === 'err')
197
+ return failWith(c, outcome.error);
198
+ const { proposal, promotion } = outcome.value;
199
+ if (promotion.kind !== 'ok')
200
+ return promotionResponse(c, promotion);
201
+ if (promotion.promotion.status === 'refused') {
202
+ return promotionResponse(c, promotion, { proposalId: proposal.id });
203
+ }
204
+ return answer(c, proposal, promotion.promotion.status === 'pending-approval' ? 202 : 201);
291
205
  });
292
206
  // ---------- POST /:proposalId/rollback ----------
293
207
  r.post('/:proposalId/rollback', async (c) => {
294
- const requestId = c.get('requestId');
295
- const tenantId = c.get('tenantId');
296
- const supervisorId = c.req.header('x-supervisor-id');
297
- const proposalId = c.req.param('proposalId');
298
- let body;
299
- try {
300
- body = await c.req.json();
301
- }
302
- catch {
303
- return badInput(c, requestId, 'Request body must be valid JSON');
304
- }
305
- const parsed = parseReasonBody(body);
306
- if (parsed.kind === 'err') {
307
- return badInput(c, requestId, parsed.message);
308
- }
309
- const outcome = await binding.rollbackProposal({
310
- tenantId,
311
- supervisorId,
312
- proposalId,
313
- reason: parsed.value.reason,
314
- });
315
- if (outcome.kind === 'not-found') {
316
- return proposalNotFound(c, requestId, proposalId);
317
- }
318
- if (outcome.kind === 'invalid-transition') {
319
- return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
320
- }
321
- if (outcome.kind === 'runtime-error') {
322
- return runtimeError(c, requestId, outcome.code, outcome.message);
323
- }
324
- return c.json({
325
- proposalId: outcome.proposalId,
326
- rolledBackAt: outcome.rolledBackAt,
208
+ const ready = await prepare(c, 'promote');
209
+ if (ready instanceof Response)
210
+ return ready;
211
+ const reason = optionalText(ready.body, 'reason');
212
+ if (reason.kind === 'err')
213
+ return badInput(c, reason.message);
214
+ const outcome = await service.rollback({
215
+ tenantId: c.get('tenantId'),
216
+ proposal: ready.proposal,
217
+ actor: actorOf(c),
218
+ ...(reason.value !== undefined && { reason: reason.value }),
327
219
  });
220
+ if (outcome.kind === 'err')
221
+ return failWith(c, outcome.error);
222
+ return answer(c, outcome.value);
328
223
  });
329
224
  // ---------- POST /:proposalId/withdraw ----------
330
225
  r.post('/:proposalId/withdraw', async (c) => {
331
- const requestId = c.get('requestId');
332
- const tenantId = c.get('tenantId');
333
- const supervisorId = c.req.header('x-supervisor-id');
334
- const proposalId = c.req.param('proposalId');
335
- let body;
336
- try {
337
- body = await c.req.json();
338
- }
339
- catch {
340
- return badInput(c, requestId, 'Request body must be valid JSON');
341
- }
342
- const parsed = parseReasonBody(body);
343
- if (parsed.kind === 'err') {
344
- return badInput(c, requestId, parsed.message);
345
- }
346
- const outcome = await binding.withdrawProposal({
347
- tenantId,
348
- supervisorId,
349
- proposalId,
350
- reason: parsed.value.reason,
226
+ const ready = await prepare(c, 'publish');
227
+ if (ready instanceof Response)
228
+ return ready;
229
+ const reason = optionalText(ready.body, 'reason');
230
+ if (reason.kind === 'err')
231
+ return badInput(c, reason.message);
232
+ if (reason.value === undefined) {
233
+ return badInput(c, '`reason` is required: why it was withdrawn');
234
+ }
235
+ const outcome = await service.withdraw({
236
+ tenantId: c.get('tenantId'),
237
+ proposal: ready.proposal,
238
+ actor: actorOf(c),
239
+ reason: reason.value,
351
240
  });
352
- if (outcome.kind === 'not-found') {
353
- return proposalNotFound(c, requestId, proposalId);
354
- }
355
- if (outcome.kind === 'invalid-transition') {
356
- return invalidTransition(c, requestId, outcome.proposalId, outcome.from, outcome.to);
357
- }
358
- if (outcome.kind === 'runtime-error') {
359
- return runtimeError(c, requestId, outcome.code, outcome.message);
360
- }
361
- return c.json(serializeProposal(outcome.proposal));
241
+ if (outcome.kind === 'err')
242
+ return failWith(c, outcome.error);
243
+ return answer(c, outcome.value);
362
244
  });
363
245
  return r;
364
246
  }
365
- // -------------------- serialization --------------------
366
- function serializeProposal(p) {
247
+ // ---------- wire ----------
248
+ function evaluationWire(stored, seen) {
249
+ if (seen === undefined || seen === null)
250
+ return { ...stored };
251
+ return {
252
+ ...stored,
253
+ runStatus: seen.runStatus,
254
+ ...(seen.baseline !== undefined && { baseline: seen.baseline }),
255
+ ...(seen.candidate !== undefined && { candidate: seen.candidate }),
256
+ ...(seen.delta !== undefined && { delta: seen.delta }),
257
+ ...(seen.spread !== undefined && { spread: seen.spread }),
258
+ ...(seen.cases !== undefined && { cases: seen.cases }),
259
+ ...(seen.better !== undefined && { better: seen.better }),
260
+ };
261
+ }
262
+ export function serialize(p, f) {
263
+ const promotion = f.promotion ?? undefined;
367
264
  return {
368
265
  id: p.id,
369
- tenantId: p.tenantId,
370
- supervisorId: p.supervisorId,
371
266
  agentId: p.agentId,
372
- agentVersion: p.agentVersion,
267
+ fromVersion: p.fromVersion,
268
+ scope: liveScopeToWire(p.scope),
373
269
  tier: p.tier,
374
270
  change: p.change,
375
- patternRefs: p.patternRefs,
376
271
  hypothesis: p.hypothesis,
377
- proposerRuleId: p.proposerRuleId,
378
- status: p.status,
379
- fingerprint: p.fingerprint,
380
- ...(p.resolutionReason !== undefined && { resolutionReason: p.resolutionReason }),
381
- ...(p.reviewApprovalId !== undefined && {
382
- reviewApprovalId: p.reviewApprovalId,
272
+ ...(p.evidence !== undefined && { evidence: p.evidence }),
273
+ drafter: p.drafter,
274
+ status: f.status,
275
+ ...(p.candidate !== undefined && { candidate: p.candidate }),
276
+ ...(p.evaluation !== undefined && { evaluation: evaluationWire(p.evaluation, f.evaluation) }),
277
+ ...(promotion !== undefined && {
278
+ promotion: {
279
+ id: promotion.id,
280
+ status: promotion.status ?? 'promoted',
281
+ ...(promotion.approvalId !== undefined && { approvalId: promotion.approvalId }),
282
+ ...(f.liveNow !== undefined && { liveNow: f.liveNow }),
283
+ },
383
284
  }),
384
- ...(p.appliedVersion !== undefined && { appliedVersion: p.appliedVersion }),
385
- ...(p.appliedAt !== undefined && { appliedAt: p.appliedAt }),
386
- ...(p.rolledBackAt !== undefined && { rolledBackAt: p.rolledBackAt }),
285
+ ...(p.rolledBack !== undefined && { rolledBack: p.rolledBack }),
286
+ ...(p.withdrawn !== undefined && { withdrawn: p.withdrawn }),
387
287
  createdAt: p.createdAt,
388
288
  updatedAt: p.updatedAt,
389
- ...(p.resolvedAt !== undefined && { resolvedAt: p.resolvedAt }),
390
289
  };
391
290
  }
392
- function badInput(c, requestId, message) {
393
- c.status(statusFor('bad-input'));
394
- return c.json(toWireError({ code: 'bad-input', message }, requestId));
291
+ function obj(value) {
292
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
293
+ ? value
294
+ : undefined;
395
295
  }
396
- function proposalNotFound(c, requestId, proposalId) {
397
- c.status(statusFor('proposal-not-found'));
398
- return c.json(toWireError({
399
- code: 'proposal-not-found',
400
- message: `No proposal with id "${proposalId}"`,
401
- proposalId: proposalId,
402
- }, requestId));
296
+ function nonEmpty(value) {
297
+ return typeof value === 'string' && value.trim() !== '' && value.length <= MAX_TEXT;
403
298
  }
404
- function invalidTransition(c, requestId, proposalId, from, to) {
405
- c.status(statusFor('proposal-invalid-state-transition'));
406
- return c.json(toWireError({
407
- code: 'proposal-invalid-state-transition',
408
- message: `Cannot transition proposal ${proposalId} from ${from} to ${to}`,
409
- proposalId: proposalId,
410
- from,
411
- to,
412
- }, requestId));
299
+ function parseContent(tier, raw) {
300
+ const content = obj(raw);
301
+ const keys = content === undefined ? [] : Object.keys(content);
302
+ if (tier === 'settings-block') {
303
+ return content !== undefined && obj(content.values) !== undefined && keys.length === 1
304
+ ? undefined
305
+ : '`change.content` for a settings block is { values: { … } } (the schema carries over)';
306
+ }
307
+ return content !== undefined && typeof content.template === 'string' && keys.length === 1
308
+ ? undefined
309
+ : '`change.content` for a prompt block is { template } (the parameters carry over)';
413
310
  }
414
- function runtimeError(c, requestId, code, message) {
415
- c.status(statusFor(code));
416
- return c.json(toWireError({ code, message }, requestId));
311
+ function parseEvidence(raw) {
312
+ if (raw === undefined)
313
+ return {};
314
+ const evidence = obj(raw);
315
+ const ids = evidence?.judgmentIds;
316
+ const valid = evidence !== undefined &&
317
+ Object.keys(evidence).every((k) => k === 'judgmentIds') &&
318
+ (ids === undefined || (Array.isArray(ids) && ids.every((id) => nonEmpty(id))));
319
+ if (!valid)
320
+ return '`evidence` is { judgmentIds?: string[] }';
321
+ return ids === undefined ? {} : { judgmentIds: ids };
417
322
  }
418
- function parseDraftBody(body) {
419
- if (body === null || typeof body !== 'object') {
420
- return { kind: 'err', message: 'Request body must be an object' };
421
- }
422
- const b = body;
423
- const agentId = b.agentId;
424
- if (typeof agentId !== 'string' || agentId.length === 0) {
425
- return { kind: 'err', message: 'Field `agentId` must be a non-empty string' };
426
- }
427
- const agentVersion = b.agentVersion;
428
- if (typeof agentVersion !== 'string' || agentVersion.length === 0) {
429
- return { kind: 'err', message: 'Field `agentVersion` must be a non-empty string' };
323
+ function parseCreateBody(b) {
324
+ if (!nonEmpty(b.agentId))
325
+ return '`agentId` is required';
326
+ if (!nonEmpty(b.fromVersion)) {
327
+ return '`fromVersion` is required: the agent version the change applies to';
430
328
  }
329
+ const scope = parseLiveScopeBody(b.scope);
330
+ if (scope.kind === 'err')
331
+ return scope.message;
332
+ if (!TIERS.includes(b.tier))
333
+ return `\`tier\` must be one of ${TIERS.join(', ')}`;
431
334
  const tier = b.tier;
432
- if (typeof tier !== 'string' || !PROPOSAL_TIERS.has(tier)) {
433
- return {
434
- kind: 'err',
435
- message: 'Field `tier` must be one of "prompt", "retrieval", "tool-config"',
436
- };
437
- }
438
- const change = b.change;
439
- if (change === null || typeof change !== 'object') {
440
- return { kind: 'err', message: 'Field `change` must be an object' };
441
- }
442
- const patternRefs = b.patternRefs;
443
- if (!Array.isArray(patternRefs)) {
444
- return { kind: 'err', message: 'Field `patternRefs` must be an array' };
445
- }
446
- const hypothesis = b.hypothesis;
447
- if (typeof hypothesis !== 'string' || hypothesis.length === 0) {
448
- return { kind: 'err', message: 'Field `hypothesis` must be a non-empty string' };
449
- }
450
- const proposerRuleId = b.proposerRuleId;
451
- if (typeof proposerRuleId !== 'string' || proposerRuleId.length === 0) {
452
- return { kind: 'err', message: 'Field `proposerRuleId` must be a non-empty string' };
335
+ const change = obj(b.change);
336
+ if (change === undefined)
337
+ return '`change` must be an object: { blockId, content }';
338
+ if (!nonEmpty(change.blockId))
339
+ return '`change.blockId` is required';
340
+ const contentProblem = parseContent(tier, change.content);
341
+ if (contentProblem !== undefined)
342
+ return contentProblem;
343
+ if (!nonEmpty(b.hypothesis)) {
344
+ return '`hypothesis` is required: what the change should improve, and why';
453
345
  }
346
+ const evidence = parseEvidence(b.evidence);
347
+ if (typeof evidence === 'string')
348
+ return evidence;
454
349
  return {
455
- kind: 'ok',
456
- value: {
457
- agentId: agentId,
458
- agentVersion,
459
- tier: tier,
460
- change: change,
461
- patternRefs: patternRefs,
462
- hypothesis,
463
- proposerRuleId,
464
- },
350
+ agentId: b.agentId,
351
+ fromVersion: b.fromVersion,
352
+ scope: scope.scope,
353
+ tier,
354
+ blockId: change.blockId,
355
+ content: change.content,
356
+ hypothesis: b.hypothesis,
357
+ ...evidence,
465
358
  };
466
359
  }
467
- function parseDryRunBody(body) {
468
- if (body === null || typeof body !== 'object') {
469
- return { kind: 'err', message: 'Request body must be an object' };
360
+ function parseEvaluateBody(b) {
361
+ if (!nonEmpty(b.suiteId)) {
362
+ return '`suiteId` is required: the test set (a judged eval suite) to compare on';
470
363
  }
471
- const b = body;
472
- const datasetId = b.datasetId;
473
- if (typeof datasetId !== 'string' || datasetId.length === 0) {
474
- return { kind: 'err', message: 'Field `datasetId` must be a non-empty string' };
364
+ if (b.objective !== undefined && !OBJECTIVES.includes(b.objective)) {
365
+ return `\`objective\` must be one of ${OBJECTIVES.join(', ')}`;
475
366
  }
476
- const datasetVersion = b.datasetVersion;
477
- if (typeof datasetVersion !== 'string' || datasetVersion.length === 0) {
478
- return { kind: 'err', message: 'Field `datasetVersion` must be a non-empty string' };
479
- }
480
- const rawCriterion = b.criterion;
481
- if (rawCriterion === null || typeof rawCriterion !== 'object') {
482
- return { kind: 'err', message: 'Field `criterion` must be an object' };
483
- }
484
- const cr = rawCriterion;
485
- if (cr.kind === 'min-pass-rate') {
486
- const minPassRate = cr.minPassRate;
487
- if (typeof minPassRate !== 'number' || !Number.isFinite(minPassRate)) {
488
- return {
489
- kind: 'err',
490
- message: 'Field `criterion.minPassRate` must be a finite number for kind "min-pass-rate"',
491
- };
492
- }
493
- return {
494
- kind: 'ok',
495
- value: { datasetId, datasetVersion, criterion: { kind: 'min-pass-rate', minPassRate } },
496
- };
497
- }
498
- if (cr.kind === 'strict-improvement') {
499
- const baseline = cr.baselinePassRate;
500
- const minDelta = cr.minDelta;
501
- if (typeof baseline !== 'number' || !Number.isFinite(baseline)) {
502
- return {
503
- kind: 'err',
504
- message: 'Field `criterion.baselinePassRate` must be a finite number for kind "strict-improvement"',
505
- };
506
- }
507
- if (typeof minDelta !== 'number' || !Number.isFinite(minDelta)) {
508
- return {
509
- kind: 'err',
510
- message: 'Field `criterion.minDelta` must be a finite number for kind "strict-improvement"',
511
- };
512
- }
513
- return {
514
- kind: 'ok',
515
- value: {
516
- datasetId,
517
- datasetVersion,
518
- criterion: { kind: 'strict-improvement', baselinePassRate: baseline, minDelta },
519
- },
520
- };
367
+ const extra = Object.keys(b).filter((k) => !['suiteId', 'objective', 'reads', 'repetitions', 'k', 'classWeights', 'sample'].includes(k));
368
+ if (extra.length > 0) {
369
+ return `\`${extra[0]}\` isn't a field of an evaluation: { suiteId, objective?, reads?, repetitions?, k?, classWeights?, sample? }`;
521
370
  }
371
+ const comparison = parseComparison(b);
372
+ if (comparison.kind === 'err')
373
+ return comparison.message;
522
374
  return {
523
- kind: 'err',
524
- message: 'Field `criterion.kind` must be "min-pass-rate" or "strict-improvement"',
375
+ suiteId: b.suiteId,
376
+ objective: b.objective ?? 'weightedYesShare',
377
+ ...(comparison.value !== undefined && { comparison: comparison.value }),
525
378
  };
526
379
  }
527
- function parseSubmitReviewBody(body) {
528
- if (body === null || typeof body !== 'object') {
529
- return { kind: 'err', message: 'Request body must be an object' };
530
- }
531
- const b = body;
532
- const out = {};
533
- const requiredRole = b.requiredRole;
534
- if (requiredRole !== undefined) {
535
- if (typeof requiredRole !== 'string' ||
536
- !REVIEWER_ROLES.has(requiredRole)) {
537
- return {
538
- kind: 'err',
539
- message: 'Field `requiredRole` must be one of "standard", "senior", "admin"',
540
- };
541
- }
542
- out.requiredRole = requiredRole;
543
- }
544
- const expiresAt = b.expiresAt;
545
- if (expiresAt !== undefined) {
546
- if (typeof expiresAt !== 'string' || Number.isNaN(new Date(expiresAt).getTime())) {
547
- return { kind: 'err', message: 'Field `expiresAt` must be an ISO date string' };
548
- }
549
- out.expiresAt = expiresAt;
550
- }
551
- return { kind: 'ok', value: out };
380
+ function optionalText(body, field) {
381
+ const v = body[field];
382
+ if (v === undefined)
383
+ return { kind: 'ok' };
384
+ return nonEmpty(v)
385
+ ? { kind: 'ok', value: v }
386
+ : {
387
+ kind: 'err',
388
+ message: `\`${field}\` must be a non-empty string (at most ${MAX_TEXT} characters)`,
389
+ };
552
390
  }
553
- function parseApplyBody(body) {
554
- if (body === null || typeof body !== 'object') {
555
- return { kind: 'err', message: 'Request body must be an object' };
391
+ /** The body as an object; `{}` when empty, `undefined` when it isn't a JSON object. */
392
+ async function readBody(c) {
393
+ const text = await c.req.text();
394
+ if (text.trim() === '')
395
+ return {};
396
+ try {
397
+ return obj(JSON.parse(text));
556
398
  }
557
- const b = body;
558
- const newVersion = b.newVersion;
559
- if (newVersion !== undefined) {
560
- if (typeof newVersion !== 'string' || newVersion.length === 0) {
561
- return {
562
- kind: 'err',
563
- message: 'Field `newVersion` must be a non-empty string when present',
564
- };
565
- }
566
- return { kind: 'ok', value: { newVersion } };
399
+ catch {
400
+ return undefined;
567
401
  }
568
- return { kind: 'ok', value: {} };
569
402
  }
570
- function parseReasonBody(body) {
571
- if (body === null || typeof body !== 'object') {
572
- return { kind: 'err', message: 'Request body must be an object' };
573
- }
574
- const b = body;
575
- const reason = b.reason;
576
- if (typeof reason !== 'string' || reason.length === 0) {
577
- return { kind: 'err', message: 'Field `reason` must be a non-empty string' };
578
- }
579
- return { kind: 'ok', value: { reason } };
403
+ // ---------- helpers ----------
404
+ function fail(c, code, error) {
405
+ c.status(statusFor(code));
406
+ return c.json(toWireError(error, c.get('requestId')));
407
+ }
408
+ function badInput(c, message) {
409
+ return fail(c, 'bad-input', { code: 'bad-input', message });
410
+ }
411
+ function failWith(c, error) {
412
+ return fail(c, error.code, error);
580
413
  }
581
414
  //# sourceMappingURL=proposals.js.map