@capybara-hq/kernel 0.1.0-rc.5 → 0.1.0-rc.7

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 (362) hide show
  1. package/bootstrap.json +27 -3
  2. package/dist/admin/admin.controller.d.ts +21 -74
  3. package/dist/admin/admin.controller.js +50 -50
  4. package/dist/admin/admin.schemas.d.ts +57 -0
  5. package/dist/admin/admin.schemas.js +50 -0
  6. package/dist/admin/extensions.controller.d.ts +10 -0
  7. package/dist/admin/extensions.controller.js +18 -0
  8. package/dist/admin/extensions.schemas.d.ts +7 -0
  9. package/dist/admin/extensions.schemas.js +10 -0
  10. package/dist/admin/limit-defaults.d.ts +20 -0
  11. package/dist/admin/limit-defaults.js +10 -0
  12. package/dist/agents/agent-profile.service.d.ts +7 -5
  13. package/dist/agents/agent-profile.service.js +14 -9
  14. package/dist/agents/agents.controller.d.ts +7 -287
  15. package/dist/agents/agents.controller.js +7 -67
  16. package/dist/agents/agents.schemas.d.ts +389 -0
  17. package/dist/agents/agents.schemas.js +126 -0
  18. package/dist/agents/agents.service.d.ts +16 -6
  19. package/dist/agents/agents.service.js +75 -19
  20. package/dist/agents/definition.d.ts +47 -19
  21. package/dist/agents/definition.js +119 -38
  22. package/dist/agents/from-template.d.ts +2 -2
  23. package/dist/agents/from-template.js +76 -45
  24. package/dist/agents/from-template.service.d.ts +12 -0
  25. package/dist/agents/from-template.service.js +23 -6
  26. package/dist/agents/models.controller.d.ts +33 -5
  27. package/dist/agents/models.controller.js +50 -6
  28. package/dist/agents/org-templates.d.ts +13 -3
  29. package/dist/agents/org-templates.js +69 -28
  30. package/dist/agents/pending-connector-requests.d.ts +2 -0
  31. package/dist/agents/pending-connector-requests.js +1 -1
  32. package/dist/agents/pending-connectors.controller.d.ts +1 -1
  33. package/dist/agents/pending-connectors.controller.js +2 -2
  34. package/dist/agents/pending-connectors.service.d.ts +2 -2
  35. package/dist/agents/pending-connectors.service.js +19 -19
  36. package/dist/agents/profile.d.ts +18 -0
  37. package/dist/agents/profile.js +5 -1
  38. package/dist/agents/readiness.controller.d.ts +5 -5
  39. package/dist/agents/readiness.controller.js +6 -6
  40. package/dist/agents/templates.controller.d.ts +8 -17
  41. package/dist/agents/templates.controller.js +13 -31
  42. package/dist/agents/templates.schemas.d.ts +20 -0
  43. package/dist/agents/templates.schemas.js +45 -0
  44. package/dist/background/background.controller.js +3 -2
  45. package/dist/background/background.schemas.d.ts +10 -0
  46. package/dist/background/background.schemas.js +16 -0
  47. package/dist/background/tasks.service.d.ts +1 -1
  48. package/dist/background/tasks.service.js +7 -2
  49. package/dist/catalog/admin-catalog.controller.d.ts +4 -57
  50. package/dist/catalog/admin-catalog.controller.js +8 -45
  51. package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
  52. package/dist/catalog/admin-catalog.schemas.js +92 -0
  53. package/dist/catalog/catalog-content.d.ts +12 -2
  54. package/dist/catalog/catalog-scope.service.js +8 -2
  55. package/dist/catalog/catalog.service.d.ts +2 -0
  56. package/dist/catalog/catalog.service.js +3 -0
  57. package/dist/catalog/component-scope.controller.d.ts +3 -65
  58. package/dist/catalog/component-scope.controller.js +3 -56
  59. package/dist/catalog/component-scope.schemas.d.ts +114 -0
  60. package/dist/catalog/component-scope.schemas.js +97 -0
  61. package/dist/catalog/component-scope.service.d.ts +28 -4
  62. package/dist/catalog/component-scope.service.js +55 -3
  63. package/dist/catalog/component-state.d.ts +9 -2
  64. package/dist/catalog/component-state.js +22 -13
  65. package/dist/catalog/marketplaces.controller.d.ts +5 -35
  66. package/dist/catalog/marketplaces.controller.js +6 -34
  67. package/dist/catalog/marketplaces.schemas.d.ts +48 -0
  68. package/dist/catalog/marketplaces.schemas.js +53 -0
  69. package/dist/catalog/marketplaces.service.d.ts +15 -1
  70. package/dist/catalog/marketplaces.service.js +22 -1
  71. package/dist/catalog/org-catalog.controller.d.ts +6 -62
  72. package/dist/catalog/org-catalog.controller.js +12 -66
  73. package/dist/catalog/org-catalog.schemas.d.ts +79 -0
  74. package/dist/catalog/org-catalog.schemas.js +82 -0
  75. package/dist/catalog/org-catalog.service.d.ts +9 -2
  76. package/dist/catalog/org-catalog.service.js +38 -5
  77. package/dist/catalog/org-extension.controller.d.ts +1 -12
  78. package/dist/catalog/org-extension.controller.js +1 -10
  79. package/dist/catalog/org-extension.schemas.d.ts +15 -0
  80. package/dist/catalog/org-extension.schemas.js +22 -0
  81. package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
  82. package/dist/catalog/org-plugin-uploads.controller.js +15 -28
  83. package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
  84. package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
  85. package/dist/catalog/owned-items.d.ts +6 -2
  86. package/dist/catalog/owned-items.js +16 -4
  87. package/dist/catalog/platform-components.d.ts +2 -0
  88. package/dist/catalog/platform-components.js +2 -0
  89. package/dist/catalog/plugin-import.js +1 -0
  90. package/dist/catalog/plugin-install.js +1 -1
  91. package/dist/catalog/requests.service.d.ts +2 -1
  92. package/dist/catalog/requests.service.js +6 -2
  93. package/dist/channels/channels.schemas.d.ts +33 -0
  94. package/dist/channels/channels.schemas.js +34 -0
  95. package/dist/channels/connections.controller.d.ts +2 -29
  96. package/dist/channels/connections.controller.js +1 -23
  97. package/dist/channels/connections.service.d.ts +8 -2
  98. package/dist/channels/connections.service.js +23 -5
  99. package/dist/channels/inbound.js +4 -0
  100. package/dist/config/schema.d.ts +4 -0
  101. package/dist/config/schema.js +24 -0
  102. package/dist/conversations/conversations.controller.d.ts +16 -37
  103. package/dist/conversations/conversations.controller.js +16 -56
  104. package/dist/conversations/conversations.schemas.d.ts +52 -0
  105. package/dist/conversations/conversations.schemas.js +79 -0
  106. package/dist/conversations/conversations.service.d.ts +13 -4
  107. package/dist/conversations/conversations.service.js +32 -26
  108. package/dist/conversations/events.d.ts +80 -6
  109. package/dist/conversations/events.js +60 -5
  110. package/dist/conversations/message-context.d.ts +28 -0
  111. package/dist/conversations/message-context.js +56 -0
  112. package/dist/conversations/queue.d.ts +2 -1
  113. package/dist/conversations/queue.js +11 -2
  114. package/dist/ctx/create-ctx.d.ts +15 -1
  115. package/dist/ctx/create-ctx.js +23 -2
  116. package/dist/db/kernel-schema.d.ts +44 -0
  117. package/dist/environments/environments.schemas.d.ts +3 -0
  118. package/dist/environments/environments.schemas.js +14 -0
  119. package/dist/environments/environments.service.d.ts +16 -4
  120. package/dist/environments/environments.service.js +58 -13
  121. package/dist/errors.d.ts +6 -0
  122. package/dist/errors.js +6 -0
  123. package/dist/evals/evals.schemas.d.ts +110 -0
  124. package/dist/evals/evals.schemas.js +107 -0
  125. package/dist/evals/reconstruct.js +18 -11
  126. package/dist/evals/recorded-tools.d.ts +2 -1
  127. package/dist/evals/recorded-tools.js +11 -3
  128. package/dist/evals/run-replay.d.ts +8 -1
  129. package/dist/evals/run-replay.js +17 -2
  130. package/dist/evals/runs.controller.d.ts +2 -57
  131. package/dist/evals/runs.controller.js +1 -42
  132. package/dist/evals/runs.service.d.ts +8 -7
  133. package/dist/evals/runs.service.js +45 -30
  134. package/dist/evals/sets.controller.d.ts +2 -28
  135. package/dist/evals/sets.controller.js +1 -31
  136. package/dist/evals/sets.service.d.ts +7 -7
  137. package/dist/evals/sets.service.js +23 -17
  138. package/dist/evals/snapshot.d.ts +3 -2
  139. package/dist/evals/snapshot.js +17 -4
  140. package/dist/evals/step-replay.d.ts +2 -1
  141. package/dist/evals/step-replay.js +3 -2
  142. package/dist/extensions/admin-ops.d.ts +5 -3
  143. package/dist/extensions/admin-ops.js +17 -12
  144. package/dist/extensions/config-hash.d.ts +10 -0
  145. package/dist/extensions/config-hash.js +38 -0
  146. package/dist/extensions/deployment-config.d.ts +16 -1
  147. package/dist/extensions/deployment-config.js +83 -0
  148. package/dist/extensions/extensions.module.js +9 -12
  149. package/dist/extensions/host.d.ts +39 -12
  150. package/dist/extensions/host.js +129 -51
  151. package/dist/extensions/installs.d.ts +5 -0
  152. package/dist/extensions/installs.js +12 -0
  153. package/dist/extensions/org-config.d.ts +17 -2
  154. package/dist/extensions/org-config.js +23 -4
  155. package/dist/extensions/point-defaults.controller.d.ts +2 -8
  156. package/dist/extensions/point-defaults.controller.js +1 -3
  157. package/dist/extensions/point-defaults.d.ts +3 -1
  158. package/dist/extensions/point-defaults.js +4 -2
  159. package/dist/extensions/point-defaults.schemas.d.ts +9 -0
  160. package/dist/extensions/point-defaults.schemas.js +14 -0
  161. package/dist/extensions/state.module.d.ts +9 -0
  162. package/dist/extensions/state.module.js +38 -0
  163. package/dist/extensions/unavailable.d.ts +49 -0
  164. package/dist/extensions/unavailable.js +113 -0
  165. package/dist/files/previewers.controller.js +2 -3
  166. package/dist/files/previewers.d.ts +1 -1
  167. package/dist/files/previewers.js +4 -4
  168. package/dist/files/previewers.schemas.d.ts +10 -0
  169. package/dist/files/previewers.schemas.js +9 -0
  170. package/dist/http/api.module.js +4 -0
  171. package/dist/http/plugin-dispatch.d.ts +4 -1
  172. package/dist/http/plugin-dispatch.js +14 -2
  173. package/dist/identity/accounts.d.ts +43 -4
  174. package/dist/identity/accounts.js +74 -6
  175. package/dist/identity/auth.guard.js +10 -1
  176. package/dist/identity/cookies.d.ts +6 -0
  177. package/dist/identity/cookies.js +14 -0
  178. package/dist/identity/identity.module.js +3 -0
  179. package/dist/identity/initial-passwords.controller.d.ts +22 -0
  180. package/dist/identity/initial-passwords.controller.js +49 -0
  181. package/dist/identity/initial-passwords.d.ts +61 -0
  182. package/dist/identity/initial-passwords.job.d.ts +16 -0
  183. package/dist/identity/initial-passwords.job.js +46 -0
  184. package/dist/identity/initial-passwords.js +159 -0
  185. package/dist/identity/me.controller.d.ts +14 -0
  186. package/dist/identity/me.controller.js +39 -1
  187. package/dist/identity/principal.d.ts +8 -0
  188. package/dist/identity/principal.js +8 -0
  189. package/dist/identity/settings.d.ts +3 -1
  190. package/dist/identity/settings.js +6 -4
  191. package/dist/inbox/inbox.schemas.d.ts +8 -0
  192. package/dist/inbox/inbox.schemas.js +11 -0
  193. package/dist/inbox/platform-inbox.controller.d.ts +1 -1
  194. package/dist/inbox/platform-inbox.controller.js +2 -2
  195. package/dist/index.d.ts +4 -0
  196. package/dist/index.js +6 -0
  197. package/dist/infra/config/kernel-config.service.js +3 -0
  198. package/dist/infra/events/kernel-events.d.ts +8 -0
  199. package/dist/lifecycle/kernel-lifecycle.js +4 -0
  200. package/dist/models/embeddings.d.ts +82 -0
  201. package/dist/models/embeddings.js +326 -0
  202. package/dist/models/enablement.controller.d.ts +40 -0
  203. package/dist/models/enablement.controller.js +74 -0
  204. package/dist/models/enablement.d.ts +101 -0
  205. package/dist/models/enablement.js +264 -0
  206. package/dist/models/models.module.d.ts +5 -1
  207. package/dist/models/models.module.js +16 -4
  208. package/dist/models/org-models.schemas.d.ts +8 -0
  209. package/dist/models/org-models.schemas.js +22 -0
  210. package/dist/models/prices.d.ts +3 -1
  211. package/dist/models/prices.js +7 -5
  212. package/dist/models/purposes.d.ts +30 -6
  213. package/dist/models/purposes.js +68 -17
  214. package/dist/orgs/orgs.controller.d.ts +2 -5
  215. package/dist/orgs/orgs.controller.js +3 -6
  216. package/dist/orgs/orgs.schemas.d.ts +8 -0
  217. package/dist/orgs/orgs.schemas.js +16 -0
  218. package/dist/orgs/orgs.service.d.ts +3 -1
  219. package/dist/orgs/orgs.service.js +6 -4
  220. package/dist/orgs/settings.service.d.ts +9 -1
  221. package/dist/orgs/settings.service.js +20 -5
  222. package/dist/overrides.d.ts +4 -0
  223. package/dist/overrides.js +2 -0
  224. package/dist/platform/errors.d.ts +21 -4
  225. package/dist/platform/errors.js +45 -6
  226. package/dist/platform/exclusions.d.ts +2 -3
  227. package/dist/platform/exclusions.js +68 -831
  228. package/dist/platform/method.js +1 -1
  229. package/dist/platform/operation.d.ts +82 -5
  230. package/dist/platform/operation.js +62 -7
  231. package/dist/platform/ops/accounts.ops.d.ts +32 -0
  232. package/dist/platform/ops/accounts.ops.js +291 -0
  233. package/dist/platform/ops/admin.ops.d.ts +36 -0
  234. package/dist/platform/ops/admin.ops.js +389 -0
  235. package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
  236. package/dist/platform/ops/agent-skills.ops.js +226 -0
  237. package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
  238. package/dist/platform/ops/agent-templates.ops.js +194 -14
  239. package/dist/platform/ops/agents.ops.d.ts +19 -1
  240. package/dist/platform/ops/agents.ops.js +481 -58
  241. package/dist/platform/ops/approvals.ops.d.ts +30 -0
  242. package/dist/platform/ops/approvals.ops.js +116 -0
  243. package/dist/platform/ops/background.ops.d.ts +14 -0
  244. package/dist/platform/ops/background.ops.js +134 -0
  245. package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
  246. package/dist/platform/ops/catalog-admin.ops.js +587 -0
  247. package/dist/platform/ops/channels.ops.d.ts +16 -0
  248. package/dist/platform/ops/channels.ops.js +195 -0
  249. package/dist/platform/ops/components.ops.d.ts +46 -0
  250. package/dist/platform/ops/components.ops.js +853 -0
  251. package/dist/platform/ops/connectors.ops.d.ts +4 -2
  252. package/dist/platform/ops/connectors.ops.js +68 -6
  253. package/dist/platform/ops/conversations.ops.d.ts +30 -0
  254. package/dist/platform/ops/conversations.ops.js +470 -0
  255. package/dist/platform/ops/environments.ops.d.ts +26 -0
  256. package/dist/platform/ops/environments.ops.js +289 -0
  257. package/dist/platform/ops/errors.d.ts +10 -5
  258. package/dist/platform/ops/errors.js +19 -11
  259. package/dist/platform/ops/evals.ops.d.ts +28 -0
  260. package/dist/platform/ops/evals.ops.js +783 -0
  261. package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
  262. package/dist/platform/ops/extensions-admin.ops.js +344 -0
  263. package/dist/platform/ops/extensions.ops.d.ts +7 -1
  264. package/dist/platform/ops/extensions.ops.js +248 -17
  265. package/dist/platform/ops/inbox.ops.d.ts +25 -0
  266. package/dist/platform/ops/inbox.ops.js +378 -0
  267. package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
  268. package/dist/platform/ops/marketplaces.ops.js +326 -17
  269. package/dist/platform/ops/models.ops.d.ts +25 -0
  270. package/dist/platform/ops/models.ops.js +232 -0
  271. package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
  272. package/dist/platform/ops/org-plugins.ops.js +329 -0
  273. package/dist/platform/ops/org-settings.ops.d.ts +16 -0
  274. package/dist/platform/ops/org-settings.ops.js +102 -0
  275. package/dist/platform/ops/orgs.ops.d.ts +28 -0
  276. package/dist/platform/ops/orgs.ops.js +295 -0
  277. package/dist/platform/ops/other-orgs.d.ts +20 -0
  278. package/dist/platform/ops/other-orgs.js +72 -0
  279. package/dist/platform/ops/platform.ops.d.ts +4 -4
  280. package/dist/platform/ops/platform.ops.js +23 -24
  281. package/dist/platform/ops/plugins.ops.d.ts +10 -8
  282. package/dist/platform/ops/plugins.ops.js +176 -77
  283. package/dist/platform/ops/previewers.ops.d.ts +14 -0
  284. package/dist/platform/ops/previewers.ops.js +109 -0
  285. package/dist/platform/ops/requests.ops.js +57 -19
  286. package/dist/platform/ops/skills.ops.d.ts +5 -1
  287. package/dist/platform/ops/skills.ops.js +129 -11
  288. package/dist/platform/ops/unavailable.d.ts +23 -0
  289. package/dist/platform/ops/unavailable.js +111 -0
  290. package/dist/platform/parity.d.ts +33 -0
  291. package/dist/platform/parity.js +272 -0
  292. package/dist/platform/platform-ops.module.d.ts +32 -0
  293. package/dist/platform/platform-ops.module.js +78 -11
  294. package/dist/platform/route-schemas.d.ts +18 -0
  295. package/dist/platform/route-schemas.js +60 -0
  296. package/dist/roles/worker.module.js +2 -0
  297. package/dist/runtime/context/build.d.ts +2 -0
  298. package/dist/runtime/context/build.js +28 -2
  299. package/dist/runtime/context/compaction.js +10 -1
  300. package/dist/runtime/context/run-context.d.ts +65 -0
  301. package/dist/runtime/context/run-context.js +215 -0
  302. package/dist/runtime/hook-calls.d.ts +8 -1
  303. package/dist/runtime/hook-calls.js +40 -9
  304. package/dist/runtime/model-call.d.ts +8 -3
  305. package/dist/runtime/model-call.js +30 -6
  306. package/dist/runtime/providers.d.ts +146 -32
  307. package/dist/runtime/providers.js +328 -67
  308. package/dist/runtime/run-context.service.d.ts +65 -0
  309. package/dist/runtime/run-context.service.js +220 -0
  310. package/dist/runtime/run-worker.d.ts +6 -1
  311. package/dist/runtime/run-worker.js +35 -10
  312. package/dist/runtime/runtime.module.js +2 -0
  313. package/dist/runtime/subagents/definition.d.ts +15 -15
  314. package/dist/runtime/subagents/definition.js +49 -118
  315. package/dist/runtime/usage-report-jobs.d.ts +88 -0
  316. package/dist/runtime/usage-report-jobs.js +158 -0
  317. package/dist/runtime/usage-report.d.ts +33 -38
  318. package/dist/runtime/usage-report.js +152 -84
  319. package/dist/skills/changes.controller.js +2 -1
  320. package/dist/skills/changes.service.d.ts +1 -1
  321. package/dist/skills/changes.service.js +4 -4
  322. package/dist/skills/invocable.controller.d.ts +1 -1
  323. package/dist/skills/invocable.controller.js +2 -2
  324. package/dist/skills/invoke.d.ts +2 -2
  325. package/dist/skills/invoke.js +8 -1
  326. package/dist/skills/skills.controller.d.ts +4 -13
  327. package/dist/skills/skills.controller.js +8 -24
  328. package/dist/skills/skills.schemas.d.ts +48 -0
  329. package/dist/skills/skills.schemas.js +61 -0
  330. package/dist/skills/skills.service.d.ts +11 -1
  331. package/dist/skills/skills.service.js +37 -14
  332. package/dist/time-zone.d.ts +5 -0
  333. package/dist/time-zone.js +19 -0
  334. package/dist/tools/approvals.controller.js +2 -3
  335. package/dist/tools/approvals.schemas.d.ts +21 -0
  336. package/dist/tools/approvals.schemas.js +15 -0
  337. package/dist/tools/builtin-names.d.ts +10 -8
  338. package/dist/tools/builtin-names.js +16 -11
  339. package/dist/tools/builtins/builtin-tools.d.ts +3 -1
  340. package/dist/tools/builtins/builtin-tools.js +15 -3
  341. package/dist/tools/builtins/current-time.d.ts +26 -0
  342. package/dist/tools/builtins/current-time.js +99 -0
  343. package/dist/tools/builtins/platform.d.ts +19 -2
  344. package/dist/tools/builtins/platform.js +105 -16
  345. package/dist/tools/connectors.controller.d.ts +1 -2
  346. package/dist/tools/connectors.controller.js +1 -4
  347. package/dist/tools/connectors.schemas.d.ts +12 -0
  348. package/dist/tools/connectors.schemas.js +19 -0
  349. package/dist/tools/connectors.service.d.ts +5 -2
  350. package/dist/tools/connectors.service.js +7 -5
  351. package/dist/tools/org-tool-switches.d.ts +16 -2
  352. package/dist/tools/org-tool-switches.js +26 -9
  353. package/dist/tools/pipeline.js +9 -1
  354. package/dist/tools/registry.d.ts +48 -51
  355. package/dist/tools/registry.js +222 -233
  356. package/package.json +3 -3
  357. package/src/migrations/0089_model_kinds_usage.sql +38 -0
  358. package/src/migrations/0090_initial_passwords.sql +27 -0
  359. package/src/migrations/0091_account_time_zone.sql +4 -0
  360. package/src/migrations/0092_tools_default_on.sql +27 -0
  361. package/dist/platform/redact-orgs.d.ts +0 -7
  362. package/dist/platform/redact-orgs.js +0 -52
@@ -0,0 +1,783 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { Inject, Injectable } from "@nestjs/common";
11
+ import { z } from "zod";
12
+ import { ModelRef } from "../../agents/definition.js";
13
+ import { ApiError } from "../../errors.js";
14
+ import { EvalAddCaseBody, EvalCandidateSchema, EvalCaseParams, EvalLabelBody, EvalResultParams, EvalRunEstimateBody, EvalRunParams, EvalRunResultsQuery, EvalSampleBody, EvalSetCreateBody, EvalSetParams, EvalSetPatchBody, } from "../../evals/evals.schemas.js";
15
+ import { EvalRunsService } from "../../evals/runs.service.js";
16
+ import { EvalSetsService } from "../../evals/sets.service.js";
17
+ import { KernelConfigService } from "../../infra/config/kernel-config.service.js";
18
+ import { KernelDb } from "../../infra/database/kernel-db.js";
19
+ import { defineOperation } from "../operation.js";
20
+ import { PlatformOperations } from "../registry.js";
21
+ import { precheckBy, viaAgent } from "./errors.js";
22
+ import { Cursor, pageOf, startOf } from "./paging.js";
23
+ import { named, orElse } from "./summary.js";
24
+ const PAGE = 50;
25
+ const SetId = EvalSetParams.shape.setId;
26
+ const CaseId = EvalCaseParams.shape.caseId;
27
+ const RunId = EvalRunParams.shape.runId;
28
+ const ResultId = EvalResultParams.shape.resultId;
29
+ /** The candidate with every string bounded (the route's model and params strings are not). */
30
+ const Candidate = EvalCandidateSchema.extend({
31
+ model: ModelRef.strict()
32
+ .extend({ provider: z.string().min(1).max(200), model: z.string().min(1).max(200) })
33
+ .optional(),
34
+ modelParams: z
35
+ .record(z.string().min(1).max(100), z.union([z.string().max(1000), z.number(), z.boolean()]))
36
+ .optional(),
37
+ }).strict();
38
+ /** The body of `evals.estimate-run` and `evals.start-run`: the route's, with the bounded candidate. */
39
+ const RunBody = EvalRunEstimateBody.extend({
40
+ setId: SetId,
41
+ candidate: Candidate,
42
+ tokenCap: z.number().int().min(1).max(1_000_000_000).optional(),
43
+ }).strict();
44
+ const setRow = (s) => ({
45
+ id: s.id,
46
+ name: s.name,
47
+ state: s.caseCount === 0 ? "empty" : "ready",
48
+ ...(s.caseCount === 0 && { next: "Add cases with evals.add-case or evals.sample-cases." }),
49
+ agentId: s.agentId,
50
+ caseCount: s.caseCount,
51
+ createdAt: s.createdAt,
52
+ });
53
+ /**
54
+ * A case as a result shows it: a neutral label ("case 3"), never its title, which is an excerpt of
55
+ * the person's message and so conversation content.
56
+ */
57
+ const caseRow = (c, n) => ({
58
+ id: c.id,
59
+ name: `case ${n}`,
60
+ sourceConversationId: c.sourceConversationId,
61
+ sourceRunId: c.sourceRunId,
62
+ agentVersion: c.agentVersion,
63
+ replayableSteps: c.replayableSteps,
64
+ });
65
+ const runRow = (r) => ({
66
+ id: r.id,
67
+ name: `${r.mode} run`,
68
+ state: r.status,
69
+ ...(r.error !== null && { reason: r.error.code }),
70
+ mode: r.mode,
71
+ progress: `${r.casesDone}/${r.casesTotal}`,
72
+ createdAt: r.createdAt,
73
+ });
74
+ /** What a run summary line says about the candidate. */
75
+ const candidateText = (c) => {
76
+ const bits = [];
77
+ if (c.model !== undefined)
78
+ bits.push(`${c.model.provider}/${c.model.model}`);
79
+ if (c.agentVersion !== undefined)
80
+ bits.push(`agent version ${c.agentVersion}`);
81
+ if (c.instructions !== undefined)
82
+ bits.push("new instructions");
83
+ if (c.modelParams !== undefined)
84
+ bits.push("model params");
85
+ return bits.length === 0 ? "the unchanged agent" : bits.join(", ");
86
+ };
87
+ /** The candidate without the keys zod left undefined (exactOptionalPropertyTypes). */
88
+ const candidateOf = (c) => ({
89
+ ...(c.agentVersion !== undefined && { agentVersion: c.agentVersion }),
90
+ ...(c.model !== undefined && { model: c.model }),
91
+ ...(c.modelParams !== undefined && { modelParams: c.modelParams }),
92
+ ...(c.instructions !== undefined && { instructions: c.instructions }),
93
+ });
94
+ /**
95
+ * Eval operations of the `Platform` tool (spec §14): eval sets, their cases, runs and results,
96
+ * all for org admins (`evals.manage`), like the routes. Cases and full results are copies of
97
+ * conversation content: reading one is audited (`trajectory.viewed`, `eval.results_viewed`) with
98
+ * the operation that did it.
99
+ */
100
+ let EvalsOperations = class EvalsOperations {
101
+ registry;
102
+ sets;
103
+ runs;
104
+ kdb;
105
+ config;
106
+ constructor(registry, sets, runs, kdb, config) {
107
+ this.registry = registry;
108
+ this.sets = sets;
109
+ this.runs = runs;
110
+ this.kdb = kdb;
111
+ this.config = config;
112
+ }
113
+ /** The position of a case in its set, from 1 (0 when it is not there): the case's label. */
114
+ async caseNo(ctx, setId, caseId) {
115
+ const set = await orElse(() => this.sets.get(ctx.orgId, setId), null);
116
+ return (set?.cases.findIndex((c) => c.id === caseId) ?? -1) + 1;
117
+ }
118
+ /** The set's eval-set row of the org, or the refusal the routes give. */
119
+ setCheck(ctx, setId) {
120
+ return precheckBy(() => this.sets.get(ctx.orgId, setId));
121
+ }
122
+ /** Whether the set may take one more case (the configured maximum). */
123
+ async roomCheck(ctx, setId) {
124
+ const found = await this.setCheck(ctx, setId);
125
+ if (!found.ok)
126
+ return found;
127
+ const max = this.config.get().evals.maxCasesPerSet;
128
+ const set = await this.sets.get(ctx.orgId, setId);
129
+ return set.cases.length >= max
130
+ ? {
131
+ ok: false,
132
+ code: "eval.too_many_cases",
133
+ message: `The eval set already has ${max} cases, the most it can hold`,
134
+ }
135
+ : { ok: true };
136
+ }
137
+ setName(ctx, setId) {
138
+ return orElse(async () => named((await this.sets.get(ctx.orgId, setId)).name), setId);
139
+ }
140
+ onModuleInit() {
141
+ this.registry.register([
142
+ defineOperation({
143
+ id: "evals.list-sets",
144
+ description: "List the org's eval sets (org admins): name, agent, number of cases. Pages by 50: pass the returned next as params.cursor.",
145
+ input: z.object({ cursor: Cursor.optional() }).strict(),
146
+ example: {},
147
+ authz: { orgAction: "evals.manage" },
148
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-sets"],
149
+ extras: ["cursor"],
150
+ confirm: "read",
151
+ run: async (input, ctx) => {
152
+ const all = (await this.sets.list(ctx.orgId)).map(setRow);
153
+ return pageOf(all, startOf(input.cursor), PAGE);
154
+ },
155
+ }),
156
+ defineOperation({
157
+ id: "evals.get-set",
158
+ description: "Read one eval set with its cases, labelled case 1, case 2, ... (source conversation and run ids, agent version, replayable steps). Case titles and content are conversation content and are never returned; an org admin reads them on the web.",
159
+ input: z.object({ setId: SetId }).strict(),
160
+ example: { setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10" },
161
+ authz: { orgAction: "evals.manage" },
162
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-sets/:setId"],
163
+ confirm: "read",
164
+ errors: [
165
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
166
+ ],
167
+ run: async (input, ctx) => {
168
+ const { cases, ...set } = await this.sets.get(ctx.orgId, input.setId);
169
+ return { set, cases: cases.map((c, i) => caseRow(c, i + 1)) };
170
+ },
171
+ }),
172
+ defineOperation({
173
+ id: "evals.create-set",
174
+ description: "Create an eval set for one agent (org admins), optionally with a rubric the judge scores by. Add cases afterwards with evals.add-case or evals.sample-cases.",
175
+ input: EvalSetCreateBody,
176
+ example: {
177
+ agentId: "7c1a5b0e-9a53-4c6b-8d64-2f5a1b0c3e77",
178
+ name: "Refund questions",
179
+ rubric: "The answer states the refund window and does not promise exceptions.",
180
+ },
181
+ authz: { orgAction: "evals.manage" },
182
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-sets"],
183
+ confirm: "org",
184
+ errors: [
185
+ {
186
+ code: "agent.not_found",
187
+ next: "Check the agent id with agents.list; an eval set belongs to one agent of this org.",
188
+ },
189
+ ],
190
+ precheck: async (i, ctx) => {
191
+ const a = await this.kdb.db
192
+ .selectFrom("agents")
193
+ .select("id")
194
+ .where("id", "=", i.agentId)
195
+ .where("org_id", "=", ctx.orgId)
196
+ .where("deleted_at", "is", null)
197
+ .executeTakeFirst();
198
+ return a === undefined
199
+ ? { ok: false, code: "agent.not_found", message: "Agent not found" }
200
+ : { ok: true };
201
+ },
202
+ summary: (i) => ({
203
+ zh: `新建评测集「${named(i.name)}」(智能体 ${i.agentId})`,
204
+ en: `Create eval set "${named(i.name)}" for agent ${i.agentId}`,
205
+ }),
206
+ run: async (input, ctx) => ({
207
+ set: setRow(await this.sets.create(ctx.orgId, ctx.actorAccountId, {
208
+ agentId: input.agentId,
209
+ name: input.name,
210
+ ...(input.description !== undefined && { description: input.description }),
211
+ ...(input.rubric !== undefined && { rubric: input.rubric }),
212
+ }, undefined, viaAgent("evals.create-set", ctx))),
213
+ }),
214
+ }),
215
+ defineOperation({
216
+ id: "evals.update-set",
217
+ description: "Change an eval set's name, description or rubric (org admins); send only the fields to change. A null rubric clears it.",
218
+ input: EvalSetPatchBody.extend({ setId: SetId })
219
+ .strict()
220
+ .refine((v) => v.name !== undefined || v.description !== undefined || v.rubric !== undefined, {
221
+ message: "Send at least one of name, description or rubric",
222
+ }),
223
+ example: { setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10", name: "Refund questions v2" },
224
+ authz: { orgAction: "evals.manage" },
225
+ mirrors: ["PATCH /api/v1/orgs/:orgId/eval-sets/:setId"],
226
+ confirm: "org",
227
+ errors: [
228
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
229
+ ],
230
+ precheck: (i, ctx) => this.setCheck(ctx, i.setId),
231
+ summary: async (i, ctx) => {
232
+ const n = await this.setName(ctx, i.setId);
233
+ return {
234
+ zh: `修改评测集「${n}」`,
235
+ en: `Update eval set "${n}"`,
236
+ };
237
+ },
238
+ run: async (input, ctx) => {
239
+ const { setId, ...patch } = input;
240
+ return {
241
+ set: setRow(await this.sets.update(ctx.orgId, ctx.actorAccountId, setId, {
242
+ ...(patch.name !== undefined && { name: patch.name }),
243
+ ...(patch.description !== undefined && { description: patch.description }),
244
+ ...(patch.rubric !== undefined && { rubric: patch.rubric }),
245
+ }, undefined, viaAgent("evals.update-set", ctx))),
246
+ };
247
+ },
248
+ }),
249
+ defineOperation({
250
+ id: "evals.delete-set",
251
+ description: "Delete an eval set (org admins): its cases and their copied conversation content are removed, runs in progress are cancelled, past results disappear with it.",
252
+ input: z.object({ setId: SetId }).strict(),
253
+ example: { setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10" },
254
+ authz: { orgAction: "evals.manage" },
255
+ mirrors: ["DELETE /api/v1/orgs/:orgId/eval-sets/:setId"],
256
+ confirm: "org",
257
+ errors: [
258
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
259
+ ],
260
+ precheck: (i, ctx) => precheckBy(() => this.sets.get(ctx.orgId, i.setId)),
261
+ summary: async (i, ctx) => {
262
+ const set = await orElse(() => this.sets.get(ctx.orgId, i.setId), null);
263
+ const n = named(set?.name ?? i.setId);
264
+ const cases = set?.cases.length ?? 0;
265
+ return {
266
+ zh: `删除评测集「${n}」:${cases} 个用例及其复制的对话内容将被删除,进行中的运行将被取消`,
267
+ en: `Delete eval set "${n}": its ${cases} cases and their copied conversation content are removed and runs in progress are cancelled`,
268
+ };
269
+ },
270
+ run: async (input, ctx) => {
271
+ await this.sets.remove(ctx.orgId, ctx.actorAccountId, input.setId, undefined, viaAgent("evals.delete-set", ctx));
272
+ return { id: input.setId, deleted: true };
273
+ },
274
+ }),
275
+ defineOperation({
276
+ id: "evals.add-case",
277
+ description: "Add one finished run of a conversation to an eval set as a case (org admins): a snapshot of that run is stored in the set. The conversation must belong to the set's agent.",
278
+ input: EvalAddCaseBody.extend({ setId: SetId }).strict(),
279
+ example: {
280
+ setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10",
281
+ conversationId: "5d2e8f1a-0b3c-4d5e-8f9a-1b2c3d4e5f60",
282
+ runId: "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
283
+ },
284
+ authz: { orgAction: "evals.manage" },
285
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-sets/:setId/cases"],
286
+ confirm: "org",
287
+ errors: [
288
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
289
+ {
290
+ code: "conversation.not_found",
291
+ next: "The conversation or run is not in this org; check the ids on the conversation's page.",
292
+ },
293
+ {
294
+ code: "eval.agent_mismatch",
295
+ next: "The run belongs to another agent than the set's; add runs of the set's agent.",
296
+ },
297
+ { code: "eval.case_exists", next: "That run is already a case of the set." },
298
+ {
299
+ code: "eval.too_many_cases",
300
+ next: "The set is full; remove a case with evals.remove-case or use another set.",
301
+ },
302
+ {
303
+ code: "eval.run_not_finished",
304
+ next: "The run has not finished; add it after it ends.",
305
+ },
306
+ {
307
+ code: "eval.case_too_large",
308
+ next: "The run's snapshot is too large to store as a case.",
309
+ },
310
+ ],
311
+ precheck: async (i, ctx) => {
312
+ const found = await this.setCheck(ctx, i.setId);
313
+ if (!found.ok)
314
+ return found;
315
+ const set = await this.sets.get(ctx.orgId, i.setId);
316
+ const conv = await this.kdb.db
317
+ .selectFrom("conversations")
318
+ .select(["agent_id", "kind"])
319
+ .where("id", "=", i.conversationId)
320
+ .where("org_id", "=", ctx.orgId)
321
+ .executeTakeFirst();
322
+ if (conv?.kind !== "chat" && conv?.kind !== "subagent") {
323
+ return {
324
+ ok: false,
325
+ code: "conversation.not_found",
326
+ message: "Conversation or run not found",
327
+ };
328
+ }
329
+ const sets = await this.kdb.db
330
+ .selectFrom("eval_sets")
331
+ .select("agent_id")
332
+ .where("id", "=", i.setId)
333
+ .executeTakeFirstOrThrow();
334
+ if (conv.agent_id !== sets.agent_id) {
335
+ return {
336
+ ok: false,
337
+ code: "eval.agent_mismatch",
338
+ message: "The run belongs to a different agent",
339
+ };
340
+ }
341
+ if (set.cases.some((c) => c.sourceRunId === i.runId)) {
342
+ return {
343
+ ok: false,
344
+ code: "eval.case_exists",
345
+ message: "That run is already a case of the eval set",
346
+ };
347
+ }
348
+ const run = await this.kdb.db
349
+ .selectFrom("runs")
350
+ .select("status")
351
+ .where("id", "=", i.runId)
352
+ .where("conversation_id", "=", i.conversationId)
353
+ .executeTakeFirst();
354
+ if (run === undefined) {
355
+ return {
356
+ ok: false,
357
+ code: "conversation.not_found",
358
+ message: "Conversation or run not found",
359
+ };
360
+ }
361
+ if (run.status === "running" || run.status === "queued") {
362
+ return {
363
+ ok: false,
364
+ code: "eval.run_not_finished",
365
+ message: "The run has not finished yet",
366
+ };
367
+ }
368
+ return this.roomCheck(ctx, i.setId);
369
+ },
370
+ summary: async (i, ctx) => {
371
+ const n = await this.setName(ctx, i.setId);
372
+ return {
373
+ zh: `把对话 ${i.conversationId} 的一次运行加入评测集「${n}」作为用例`,
374
+ en: `Add a run of conversation ${i.conversationId} to eval set "${n}" as a case`,
375
+ };
376
+ },
377
+ run: async (input, ctx) => {
378
+ const { setId, ...body } = input;
379
+ const added = await this.sets.addCase(ctx.orgId, ctx.actorAccountId, setId, body, undefined, viaAgent("evals.add-case", ctx));
380
+ return { case: caseRow(added, await this.caseNo(ctx, setId, added.id)) };
381
+ },
382
+ }),
383
+ defineOperation({
384
+ id: "evals.sample-cases",
385
+ description: "Add random finished runs of the set's agent to an eval set as cases (org admins), up to count, optionally within a time range, by status or with a minimum number of tool calls. Returns how many were added and skipped.",
386
+ input: EvalSampleBody.extend({ setId: SetId }).strict(),
387
+ example: { setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10", count: 10 },
388
+ authz: { orgAction: "evals.manage" },
389
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-sets/:setId/cases/sample"],
390
+ confirm: "org",
391
+ errors: [
392
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
393
+ {
394
+ code: "eval.too_many_cases",
395
+ next: "The set is full; remove a case with evals.remove-case or use another set.",
396
+ },
397
+ ],
398
+ precheck: (i, ctx) => this.roomCheck(ctx, i.setId),
399
+ summary: async (i, ctx) => {
400
+ const n = await this.setName(ctx, i.setId);
401
+ return {
402
+ zh: `从评测集「${n}」的智能体的历史运行中随机抽样至多 ${i.count} 个用例`,
403
+ en: `Sample up to ${i.count} cases from the history of the agent of eval set "${n}"`,
404
+ };
405
+ },
406
+ run: async (input, ctx) => {
407
+ const { setId, ...body } = input;
408
+ return this.sets.sample(ctx.orgId, ctx.actorAccountId, setId, {
409
+ count: body.count,
410
+ ...(body.from !== undefined && { from: body.from }),
411
+ ...(body.to !== undefined && { to: body.to }),
412
+ ...(body.status !== undefined && { status: body.status }),
413
+ ...(body.minToolCalls !== undefined && { minToolCalls: body.minToolCalls }),
414
+ }, undefined, viaAgent("evals.sample-cases", ctx));
415
+ },
416
+ }),
417
+ defineOperation({
418
+ id: "evals.get-case",
419
+ description: "Read one eval case's metadata (org admins): its label in the set, source conversation and run ids, agent version and how many steps can be replayed. The case's messages and trajectory are conversation content and are never returned; an org admin reads them on the web.",
420
+ input: z.object({ setId: SetId, caseId: CaseId }).strict(),
421
+ example: {
422
+ setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10",
423
+ caseId: "6e5d4c3b-2a19-4f08-9e7d-6c5b4a392817",
424
+ },
425
+ authz: { orgAction: "evals.manage" },
426
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-sets/:setId/cases/:caseId"],
427
+ confirm: "read",
428
+ errors: [
429
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
430
+ {
431
+ code: "eval.case_not_found",
432
+ next: "Check the case id with evals.get-set.",
433
+ },
434
+ ],
435
+ run: async (input, ctx) => {
436
+ const set = await this.sets.get(ctx.orgId, input.setId);
437
+ const i = set.cases.findIndex((c) => c.id === input.caseId);
438
+ const found = set.cases[i];
439
+ if (found === undefined)
440
+ throw new ApiError("eval.case_not_found", "Eval case not found");
441
+ return { case: caseRow(found, i + 1) };
442
+ },
443
+ }),
444
+ defineOperation({
445
+ id: "evals.remove-case",
446
+ description: "Remove one case from an eval set (org admins); its copied conversation content and its results are deleted. Use the case id from evals.get-set.",
447
+ input: z.object({ setId: SetId, caseId: CaseId }).strict(),
448
+ example: {
449
+ setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10",
450
+ caseId: "6e5d4c3b-2a19-4f08-9e7d-6c5b4a392817",
451
+ },
452
+ authz: { orgAction: "evals.manage" },
453
+ mirrors: ["DELETE /api/v1/orgs/:orgId/eval-sets/:setId/cases/:caseId"],
454
+ confirm: "org",
455
+ errors: [
456
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
457
+ { code: "eval.case_not_found", next: "Check the case id with evals.get-set." },
458
+ ],
459
+ precheck: async (i, ctx) => {
460
+ const found = await this.setCheck(ctx, i.setId);
461
+ if (!found.ok)
462
+ return found;
463
+ return (await this.caseNo(ctx, i.setId, i.caseId)) === 0
464
+ ? { ok: false, code: "eval.case_not_found", message: "Eval case not found" }
465
+ : { ok: true };
466
+ },
467
+ summary: async (i, ctx) => {
468
+ const set = await orElse(() => this.sets.get(ctx.orgId, i.setId), null);
469
+ const no = (set?.cases.findIndex((c) => c.id === i.caseId) ?? -1) + 1;
470
+ const label = no === 0 ? i.caseId : `case ${no}`;
471
+ const n = named(set?.name ?? i.setId);
472
+ return {
473
+ zh: `从评测集「${n}」移除用例 ${label}`,
474
+ en: `Remove ${label} from eval set "${n}"`,
475
+ };
476
+ },
477
+ run: async (input, ctx) => {
478
+ await this.sets.removeCase(ctx.orgId, ctx.actorAccountId, input.setId, input.caseId, undefined, viaAgent("evals.remove-case", ctx));
479
+ return { id: input.caseId, removed: true };
480
+ },
481
+ }),
482
+ defineOperation({
483
+ id: "evals.estimate-run",
484
+ description: "Estimate an eval run without starting it (org admins): the candidate (another agent version, model, model params or instructions) replayed over the set's cases, in step mode (one model call per case step) or run mode (whole runs). Returns request counts, estimated tokens and cost, and the token cap that would apply.",
485
+ input: RunBody,
486
+ example: {
487
+ setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10",
488
+ mode: "step",
489
+ candidate: {},
490
+ judge: false,
491
+ },
492
+ authz: { orgAction: "evals.manage" },
493
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-sets/:setId/runs/estimate"],
494
+ confirm: "read",
495
+ errors: [
496
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
497
+ {
498
+ code: "eval.candidate_invalid",
499
+ next: "The candidate cannot run on the cases; fix it as the message and details say.",
500
+ },
501
+ {
502
+ code: "eval.token_cap_invalid",
503
+ next: "Send a tokenCap within the limits of the estimate, or leave it out for the default.",
504
+ },
505
+ ],
506
+ run: async (input, ctx) => this.runs.estimate(ctx.orgId, input.setId, {
507
+ mode: input.mode,
508
+ candidate: candidateOf(input.candidate),
509
+ judge: input.judge,
510
+ ...(input.tokenCap !== undefined && { tokenCap: input.tokenCap }),
511
+ }),
512
+ }),
513
+ defineOperation({
514
+ id: "evals.start-run",
515
+ description: "Start an eval run over a set's cases (org admins): the candidate is replayed on each case, optionally scored by the judge with the set's rubric. It spends model tokens up to the token cap; read evals.estimate-run first and show the estimate to the person.",
516
+ input: RunBody,
517
+ example: {
518
+ setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10",
519
+ mode: "step",
520
+ candidate: {},
521
+ judge: false,
522
+ },
523
+ authz: { orgAction: "evals.manage" },
524
+ // the same body as the estimate, with the setId of the path
525
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-sets/:setId/runs"],
526
+ confirm: "org",
527
+ errors: [
528
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
529
+ {
530
+ code: "eval.candidate_invalid",
531
+ next: "The candidate cannot run on the cases; fix it as the message and details say.",
532
+ },
533
+ {
534
+ code: "eval.nothing_to_replay",
535
+ next: "The set has nothing to replay in this mode; add cases with evals.add-case.",
536
+ },
537
+ {
538
+ code: "eval.token_cap_invalid",
539
+ next: "Send a tokenCap within the limits shown by evals.estimate-run, or leave it out.",
540
+ },
541
+ {
542
+ code: "agent.model_unavailable",
543
+ next: {
544
+ superAdmin: "The model cannot be used: configure its provider in the admin console, then start again.",
545
+ orgAdmin: "The model cannot be used in this org; choose another or ask the super admin.",
546
+ member: "The model cannot be used in this org; ask an org admin.",
547
+ },
548
+ },
549
+ ],
550
+ // a candidate or set the run cannot start with is denied before the card (read-only)
551
+ precheck: async (i, ctx) => {
552
+ let cases = 0;
553
+ const checked = await precheckBy(async () => {
554
+ const e = await this.runs.estimate(ctx.orgId, i.setId, {
555
+ mode: i.mode,
556
+ candidate: candidateOf(i.candidate),
557
+ judge: i.judge,
558
+ ...(i.tokenCap !== undefined && { tokenCap: i.tokenCap }),
559
+ });
560
+ cases = e.estimate.cases;
561
+ });
562
+ if (checked.ok && cases === 0) {
563
+ return {
564
+ ok: false,
565
+ code: "eval.nothing_to_replay",
566
+ message: "The eval set has nothing to replay",
567
+ };
568
+ }
569
+ return checked;
570
+ },
571
+ summary: async (i, ctx) => {
572
+ const n = await this.setName(ctx, i.setId);
573
+ const est = await orElse(() => this.runs.estimate(ctx.orgId, i.setId, {
574
+ mode: i.mode,
575
+ candidate: candidateOf(i.candidate),
576
+ judge: i.judge,
577
+ ...(i.tokenCap !== undefined && { tokenCap: i.tokenCap }),
578
+ }), null);
579
+ const cand = candidateText(candidateOf(i.candidate));
580
+ const judge = i.judge;
581
+ const cost = est?.estimate.estimatedCost == null
582
+ ? ""
583
+ : ` ${est.estimate.estimatedCost} ${est.estimate.currency}`;
584
+ const tokens = est === null ? "" : `${est.estimate.estimatedTokens}`;
585
+ return {
586
+ zh: `在评测集「${n}」上运行评测(${i.mode === "step" ? "单步" : "整轮"},候选:${cand}${judge ? ",含评委" : ""})${tokens ? `:约 ${tokens} tokens${cost},上限 ${est?.effectiveTokenCap}` : ""}`,
587
+ en: `Run an eval on set "${n}" (${i.mode} mode, candidate: ${cand}${judge ? ", with the judge" : ""})${tokens ? `: about ${tokens} tokens${cost}, capped at ${est?.effectiveTokenCap}` : ""}`,
588
+ };
589
+ },
590
+ run: async (input, ctx) => ({
591
+ run: runRow(await this.runs.start(ctx.orgId, ctx.actorAccountId, input.setId, {
592
+ mode: input.mode,
593
+ candidate: candidateOf(input.candidate),
594
+ judge: input.judge,
595
+ ...(input.tokenCap !== undefined && { tokenCap: input.tokenCap }),
596
+ }, undefined, viaAgent("evals.start-run", ctx))),
597
+ }),
598
+ }),
599
+ defineOperation({
600
+ id: "evals.list-runs",
601
+ description: "List the runs of one eval set, newest first (org admins): id, mode, state and progress. Read one with evals.get-run. Pages by 50: pass the returned next as params.cursor.",
602
+ input: z.object({ setId: SetId, cursor: Cursor.optional() }).strict(),
603
+ example: { setId: "3b1f0c52-8d2a-4a57-9a43-6f1d2c9e7a10" },
604
+ authz: { orgAction: "evals.manage" },
605
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-sets/:setId/runs"],
606
+ extras: ["cursor"],
607
+ confirm: "read",
608
+ errors: [
609
+ { code: "eval.set_not_found", next: "Check the eval set id with evals.list-sets." },
610
+ ],
611
+ run: async (input, ctx) => pageOf((await this.runs.listForSet(ctx.orgId, input.setId)).map(runRow), startOf(input.cursor), PAGE),
612
+ }),
613
+ defineOperation({
614
+ id: "evals.get-run",
615
+ description: "Read one eval run: its candidate, state, progress, token use, estimate and, once finished, the summary (match rates, judge and human pass rates).",
616
+ input: z.object({ runId: RunId }).strict(),
617
+ example: { runId: "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f" },
618
+ authz: { orgAction: "evals.manage" },
619
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-runs/:runId"],
620
+ confirm: "read",
621
+ errors: [{ code: "eval.run_not_found", next: "Check the run id with evals.list-runs." }],
622
+ run: async (input, ctx) => ({ run: await this.runs.get(ctx.orgId, input.runId) }),
623
+ }),
624
+ defineOperation({
625
+ id: "evals.list-results",
626
+ description: "List the results of one eval run without their content (org admins): state, judge verdict, your label, drift and error code per case step. Pages by 50: pass the returned next as params.after. Read one result's scalar fields with evals.get-result.",
627
+ input: EvalRunResultsQuery.pick({ after: true, limit: true })
628
+ .extend({ runId: RunId, limit: z.number().int().min(1).max(50).default(50) })
629
+ .strict(),
630
+ example: { runId: "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f", limit: 50 },
631
+ authz: { orgAction: "evals.manage" },
632
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-runs/:runId/results"],
633
+ // the light view only; polling by `updatedSince` is the web's
634
+ omits: ["view", "updatedSince"],
635
+ confirm: "read",
636
+ errors: [{ code: "eval.run_not_found", next: "Check the run id with evals.list-runs." }],
637
+ run: async (input, ctx) => {
638
+ const out = await this.runs.resultsLight(ctx.orgId, ctx.actorAccountId, input.runId, { limit: input.limit, ...(input.after !== undefined && { after: input.after }) }, undefined, viaAgent("evals.list-results", ctx));
639
+ return {
640
+ items: out.results.map((r) => ({
641
+ id: r.id,
642
+ name: r.step === null ? "whole run" : `step ${r.step}`,
643
+ state: r.status,
644
+ ...(r.errorCode !== null && { reason: r.errorCode }),
645
+ caseId: r.caseId,
646
+ verdict: r.label ?? r.verdict,
647
+ toolCallsMatch: r.toolCallsMatch,
648
+ })),
649
+ next: out.next,
650
+ };
651
+ },
652
+ }),
653
+ defineOperation({
654
+ id: "evals.get-result",
655
+ description: "Read one eval result without its content (org admins): status, judge status and verdict, your label and note, whether the tool calls matched, text similarity, drift reasons and the error code. The baseline and candidate outputs and the diff are conversation content and are never returned; an org admin reads them on the web.",
656
+ input: z.object({ runId: RunId, resultId: ResultId }).strict(),
657
+ example: {
658
+ runId: "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
659
+ resultId: "7f6e5d4c-3b2a-4190-8f7e-6d5c4b3a2918",
660
+ },
661
+ authz: { orgAction: "evals.manage" },
662
+ mirrors: ["GET /api/v1/orgs/:orgId/eval-runs/:runId/results/:resultId"],
663
+ confirm: "read",
664
+ errors: [
665
+ { code: "eval.run_not_found", next: "Check the run id with evals.list-runs." },
666
+ {
667
+ code: "eval.result_not_found",
668
+ next: "Check the result id with evals.list-results.",
669
+ },
670
+ ],
671
+ run: async (input, ctx) => {
672
+ const r = await this.runs.result(ctx.orgId, ctx.actorAccountId, input.runId, input.resultId, undefined, viaAgent("evals.get-result", ctx));
673
+ const diff = (r.diff ?? {});
674
+ const judge = (r.judge ?? {});
675
+ const error = (r.error ?? {});
676
+ return {
677
+ result: {
678
+ id: r.id,
679
+ caseId: r.caseId,
680
+ step: r.step,
681
+ state: r.status,
682
+ judgeStatus: r.judgeStatus,
683
+ verdict: judge.verdict ?? null,
684
+ label: r.label,
685
+ labelNote: r.labelNote,
686
+ toolCallsMatch: diff.toolCallsMatch ?? null,
687
+ textSimilarity: diff.textSimilarity ?? null,
688
+ drift: r.drift,
689
+ errorCode: error.code ?? null,
690
+ },
691
+ };
692
+ },
693
+ }),
694
+ defineOperation({
695
+ id: "evals.cancel-run",
696
+ description: "Cancel an eval run that is queued or running (org admins): cases not started are skipped; requests in flight finish and are recorded.",
697
+ input: z.object({ runId: RunId }).strict(),
698
+ example: { runId: "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f" },
699
+ authz: { orgAction: "evals.manage" },
700
+ mirrors: ["POST /api/v1/orgs/:orgId/eval-runs/:runId/cancel"],
701
+ confirm: "org",
702
+ errors: [
703
+ { code: "eval.run_not_found", next: "Check the run id with evals.list-runs." },
704
+ { code: "eval.run_finished", next: "The run has already finished; nothing to cancel." },
705
+ ],
706
+ precheck: async (i, ctx) => {
707
+ const found = await precheckBy(() => this.runs.get(ctx.orgId, i.runId));
708
+ if (!found.ok)
709
+ return found;
710
+ const run = await this.runs.get(ctx.orgId, i.runId);
711
+ return run.status === "queued" || run.status === "running"
712
+ ? { ok: true }
713
+ : {
714
+ ok: false,
715
+ code: "eval.run_finished",
716
+ message: "The eval run has already finished",
717
+ };
718
+ },
719
+ summary: async (i, ctx) => {
720
+ const run = await orElse(() => this.runs.get(ctx.orgId, i.runId), null);
721
+ const progress = run === null ? "" : ` (${run.casesDone}/${run.casesTotal} cases done)`;
722
+ return {
723
+ zh: `取消评测运行 ${i.runId}${progress}`,
724
+ en: `Cancel eval run ${i.runId}${progress}`,
725
+ };
726
+ },
727
+ run: async (input, ctx) => ({
728
+ run: runRow(await this.runs.cancel(ctx.orgId, ctx.actorAccountId, input.runId, undefined, viaAgent("evals.cancel-run", ctx))),
729
+ }),
730
+ }),
731
+ defineOperation({
732
+ id: "evals.label-result",
733
+ description: "Label one eval result pass or fail with an optional note (org admins); a null label clears the label and its note.",
734
+ input: EvalLabelBody.extend({ resultId: ResultId }).strict(),
735
+ example: { resultId: "7f6e5d4c-3b2a-4190-8f7e-6d5c4b3a2918", label: "pass" },
736
+ authz: { orgAction: "evals.manage" },
737
+ mirrors: ["PUT /api/v1/orgs/:orgId/eval-results/:resultId/label"],
738
+ confirm: "org",
739
+ errors: [
740
+ {
741
+ code: "eval.result_not_found",
742
+ next: "Check the result id with evals.list-results.",
743
+ },
744
+ ],
745
+ precheck: async (i, ctx) => {
746
+ const r = await this.kdb.db
747
+ .selectFrom("eval_results as r")
748
+ .innerJoin("eval_runs as er", "er.id", "r.run_id")
749
+ .innerJoin("eval_sets as es", "es.id", "er.set_id")
750
+ .select("r.id")
751
+ .where("r.id", "=", i.resultId)
752
+ .where("r.org_id", "=", ctx.orgId)
753
+ .where("es.deleted_at", "is", null)
754
+ .executeTakeFirst();
755
+ return r === undefined
756
+ ? { ok: false, code: "eval.result_not_found", message: "Eval result not found" }
757
+ : { ok: true };
758
+ },
759
+ summary: (i) => ({
760
+ zh: i.label === null
761
+ ? `清除评测结果 ${i.resultId} 的人工标注`
762
+ : `把评测结果 ${i.resultId} 标注为${i.label === "pass" ? "通过" : "不通过"}`,
763
+ en: i.label === null
764
+ ? `Clear the label of eval result ${i.resultId}`
765
+ : `Label eval result ${i.resultId} as ${i.label}`,
766
+ }),
767
+ run: async (input, ctx) => {
768
+ const r = await this.runs.label(ctx.orgId, ctx.actorAccountId, input.resultId, { label: input.label, ...(input.note !== undefined && { note: input.note }) }, undefined, viaAgent("evals.label-result", ctx));
769
+ return { id: r.id, label: r.label, labelNote: r.labelNote };
770
+ },
771
+ }),
772
+ ]);
773
+ }
774
+ };
775
+ EvalsOperations = __decorate([
776
+ Injectable(),
777
+ __param(0, Inject(PlatformOperations)),
778
+ __param(1, Inject(EvalSetsService)),
779
+ __param(2, Inject(EvalRunsService)),
780
+ __param(3, Inject(KernelDb)),
781
+ __param(4, Inject(KernelConfigService))
782
+ ], EvalsOperations);
783
+ export { EvalsOperations };