evalkit-py 0.2.0.dev12__py3-none-any.whl

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 (371) hide show
  1. evalkit/__init__.py +0 -0
  2. evalkit/api/__init__.py +0 -0
  3. evalkit/api/access.py +74 -0
  4. evalkit/api/agents.py +159 -0
  5. evalkit/api/app.py +360 -0
  6. evalkit/api/auth.py +225 -0
  7. evalkit/api/cli_dist.py +10 -0
  8. evalkit/api/datasets.py +169 -0
  9. evalkit/api/deps.py +79 -0
  10. evalkit/api/download.py +15 -0
  11. evalkit/api/evaluators.py +121 -0
  12. evalkit/api/experiments.py +616 -0
  13. evalkit/api/fixtures.py +95 -0
  14. evalkit/api/harness_check.py +48 -0
  15. evalkit/api/imports.py +180 -0
  16. evalkit/api/limits.py +84 -0
  17. evalkit/api/llm_providers.py +120 -0
  18. evalkit/api/mcp/__init__.py +0 -0
  19. evalkit/api/mcp/auth.py +100 -0
  20. evalkit/api/mcp/descriptions.py +336 -0
  21. evalkit/api/mcp/models.py +259 -0
  22. evalkit/api/mcp/server.py +101 -0
  23. evalkit/api/mcp/tools.py +844 -0
  24. evalkit/api/meta.py +19 -0
  25. evalkit/api/otel.py +350 -0
  26. evalkit/api/pull.py +197 -0
  27. evalkit/api/review.py +271 -0
  28. evalkit/api/runs.py +555 -0
  29. evalkit/api/server_keys.py +44 -0
  30. evalkit/api/tokens.py +51 -0
  31. evalkit/api/trace_imports.py +173 -0
  32. evalkit/api/trace_sources.py +49 -0
  33. evalkit/api/traces.py +196 -0
  34. evalkit/api/users.py +72 -0
  35. evalkit/api/workspaces.py +131 -0
  36. evalkit/bundled/contracts/atif-accepted.json +5 -0
  37. evalkit/bundled/contracts/custom-evaluator-api-v1.json +243 -0
  38. evalkit/bundled/contracts/harness-api-v1.json +938 -0
  39. evalkit/bundled/contracts/span-mapping-v1.json +314 -0
  40. evalkit/bundled/docs/concepts.md +26 -0
  41. evalkit/bundled/docs/config.md +38 -0
  42. evalkit/bundled/docs/harness-api.md +44 -0
  43. evalkit/bundled/docs/install.md +60 -0
  44. evalkit/bundled/docs/login.md +36 -0
  45. evalkit/bundled/docs/mappings.md +136 -0
  46. evalkit/bundled/docs/mcp.md +44 -0
  47. evalkit/bundled/docs/quickstart.md +142 -0
  48. evalkit/bundled/docs/sdk-runs.md +171 -0
  49. evalkit/bundled/docs/tracing.md +171 -0
  50. evalkit/bundled/docs/try-locally.md +288 -0
  51. evalkit/bundled/docs/workspaces.md +45 -0
  52. evalkit/bundled/skills/authoring-eval-cases/SKILL.md +387 -0
  53. evalkit/bundled/skills/authoring-eval-cases/references/overlays.md +83 -0
  54. evalkit/bundled/skills/authoring-eval-cases/references/tool-checks.md +71 -0
  55. evalkit/bundled/skills/connect-traces/SKILL.md +296 -0
  56. evalkit/bundled/skills/connect-traces/references/gen_ai.json +42 -0
  57. evalkit/bundled/skills/connect-traces/references/openinference.json +35 -0
  58. evalkit/bundled/skills/connect-traces/references/span-mapping-schema.md +88 -0
  59. evalkit/bundled/skills/eval-driven-development/SKILL.md +458 -0
  60. evalkit/bundled/skills/eval-driven-development/references/analyze-run.md +97 -0
  61. evalkit/bundled/skills/eval-driven-development/references/diagnose.md +130 -0
  62. evalkit/bundled/skills/eval-driven-development/references/synthesize-cases.md +87 -0
  63. evalkit/bundled/skills/eval-driven-development/references/synthesize.md +165 -0
  64. evalkit/bundled/skills/evalkit-deployment/SKILL.md +332 -0
  65. evalkit/bundled/skills/evalkit-deployment/config.example.yaml +49 -0
  66. evalkit/bundled/skills/evalkit-deployment/docker-compose.yml +51 -0
  67. evalkit/bundled/skills/evalkit-deployment/references/config-and-deploy.md +333 -0
  68. evalkit/bundled/skills/evalkit-deployment/references/harness-api.md +139 -0
  69. evalkit/bundled/skills/evalkit-deployment/try/.env.example +11 -0
  70. evalkit/bundled/skills/evalkit-deployment/try/agent.py +131 -0
  71. evalkit/bundled/skills/evalkit-deployment/try/cases/acme/balance-sheet/cases.yaml +25 -0
  72. evalkit/bundled/skills/evalkit-deployment/try/cases/acme/income-statement/cases.yaml +43 -0
  73. evalkit/bundled/skills/evalkit-deployment/try/config.yaml +17 -0
  74. evalkit/bundled/skills/evalkit-deployment/try/docker-compose.yml +82 -0
  75. evalkit/bundled/skills/evalkit-deployment/try/evalkit.yaml +4 -0
  76. evalkit/bundled/skills/evalkit-deployment/try/mapping.json +42 -0
  77. evalkit/bundled/skills/evalkit-deployment/try/run.py +33 -0
  78. evalkit/bundled/skills/evalkit-usage/SKILL.md +509 -0
  79. evalkit/bundled/skills/evalkit-usage/references/suite-fixtures.md +42 -0
  80. evalkit/bundled/ui/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  81. evalkit/bundled/ui/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  82. evalkit/bundled/ui/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  83. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  84. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  85. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  86. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  87. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  88. evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  89. evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  90. evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  91. evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  92. evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  93. evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  94. evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  95. evalkit/bundled/ui/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  96. evalkit/bundled/ui/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  97. evalkit/bundled/ui/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  98. evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  99. evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  100. evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  101. evalkit/bundled/ui/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  102. evalkit/bundled/ui/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  103. evalkit/bundled/ui/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  104. evalkit/bundled/ui/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  105. evalkit/bundled/ui/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  106. evalkit/bundled/ui/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  107. evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  108. evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  109. evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  110. evalkit/bundled/ui/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  111. evalkit/bundled/ui/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  112. evalkit/bundled/ui/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  113. evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  114. evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  115. evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  116. evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  117. evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  118. evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  119. evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  120. evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  121. evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  122. evalkit/bundled/ui/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  123. evalkit/bundled/ui/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  124. evalkit/bundled/ui/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  125. evalkit/bundled/ui/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  126. evalkit/bundled/ui/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  127. evalkit/bundled/ui/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  128. evalkit/bundled/ui/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  129. evalkit/bundled/ui/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  130. evalkit/bundled/ui/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  131. evalkit/bundled/ui/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  132. evalkit/bundled/ui/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  133. evalkit/bundled/ui/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  134. evalkit/bundled/ui/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  135. evalkit/bundled/ui/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  136. evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  137. evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  138. evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  139. evalkit/bundled/ui/assets/abap-08VXUWAP.js +1 -0
  140. evalkit/bundled/ui/assets/apex-BWPQTe0t.js +1 -0
  141. evalkit/bundled/ui/assets/azcli-Bc_sGQ0U.js +1 -0
  142. evalkit/bundled/ui/assets/bat-i0X4ZdIN.js +1 -0
  143. evalkit/bundled/ui/assets/bicep-B5-_aFwp.js +2 -0
  144. evalkit/bundled/ui/assets/cameligo-DMUM7wLl.js +1 -0
  145. evalkit/bundled/ui/assets/clojure-Cm7r79vr.js +1 -0
  146. evalkit/bundled/ui/assets/codicon-DF1abBS2.ttf +0 -0
  147. evalkit/bundled/ui/assets/coffee-Ba7i2nA0.js +1 -0
  148. evalkit/bundled/ui/assets/cpp-C7h46wYY.js +1 -0
  149. evalkit/bundled/ui/assets/csharp-BKxtCVv1.js +1 -0
  150. evalkit/bundled/ui/assets/csp-bTuwJoIa.js +1 -0
  151. evalkit/bundled/ui/assets/css-DIMkf-bt.js +3 -0
  152. evalkit/bundled/ui/assets/css.worker-DwfUZ3fB.js +96 -0
  153. evalkit/bundled/ui/assets/cssMode-C97l1pbB.js +1 -0
  154. evalkit/bundled/ui/assets/cypher-CVaqCwHa.js +1 -0
  155. evalkit/bundled/ui/assets/dart-onAF5SnQ.js +1 -0
  156. evalkit/bundled/ui/assets/dockerfile-DZFCIeNp.js +1 -0
  157. evalkit/bundled/ui/assets/ecl-94qehhXe.js +1 -0
  158. evalkit/bundled/ui/assets/editor-DjpsE8to.css +1 -0
  159. evalkit/bundled/ui/assets/editor.api-NTesIxw5.js +908 -0
  160. evalkit/bundled/ui/assets/editor.worker-CRz__AKW.js +33 -0
  161. evalkit/bundled/ui/assets/elixir-6RTg0lbw.js +1 -0
  162. evalkit/bundled/ui/assets/flow9-C5_-GSwl.js +1 -0
  163. evalkit/bundled/ui/assets/freemarker2-BWqEFagp.js +3 -0
  164. evalkit/bundled/ui/assets/fsharp-C8Ef5oNN.js +1 -0
  165. evalkit/bundled/ui/assets/go-C-y9NEjX.js +1 -0
  166. evalkit/bundled/ui/assets/graphql-fmXr3nnJ.js +1 -0
  167. evalkit/bundled/ui/assets/handlebars-DkIF-whN.js +1 -0
  168. evalkit/bundled/ui/assets/hcl-CpzslTdj.js +1 -0
  169. evalkit/bundled/ui/assets/html-C_rpeQXJ.js +1 -0
  170. evalkit/bundled/ui/assets/html.worker-D9ugpX4y.js +509 -0
  171. evalkit/bundled/ui/assets/htmlMode-B0YIq3DF.js +1 -0
  172. evalkit/bundled/ui/assets/index-Cw-jBH6M.js +736 -0
  173. evalkit/bundled/ui/assets/index-DKtoQZtm.css +1 -0
  174. evalkit/bundled/ui/assets/ini-sBoK_t0W.js +1 -0
  175. evalkit/bundled/ui/assets/java-BEtHBSE6.js +1 -0
  176. evalkit/bundled/ui/assets/javascript-D4EGhYA6.js +1 -0
  177. evalkit/bundled/ui/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  178. evalkit/bundled/ui/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  179. evalkit/bundled/ui/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  180. evalkit/bundled/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  181. evalkit/bundled/ui/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  182. evalkit/bundled/ui/assets/json.worker-CV9fqkUp.js +65 -0
  183. evalkit/bundled/ui/assets/jsonMode-pQjSfIH6.js +7 -0
  184. evalkit/bundled/ui/assets/julia-Bri6UV-V.js +1 -0
  185. evalkit/bundled/ui/assets/kotlin-BOotOW0E.js +1 -0
  186. evalkit/bundled/ui/assets/less-B9JPFI3C.js +2 -0
  187. evalkit/bundled/ui/assets/lexon-CfSJPG6W.js +1 -0
  188. evalkit/bundled/ui/assets/liquid-DbrvoYjD.js +1 -0
  189. evalkit/bundled/ui/assets/lspLanguageFeatures-D0B7cH6y.js +4 -0
  190. evalkit/bundled/ui/assets/lua-CsQS60Ue.js +1 -0
  191. evalkit/bundled/ui/assets/m3-D-oSqn_W.js +1 -0
  192. evalkit/bundled/ui/assets/markdown-Cimd5fb3.js +1 -0
  193. evalkit/bundled/ui/assets/mdx-B0HrujLR.js +1 -0
  194. evalkit/bundled/ui/assets/mips-CIPQ_RoX.js +1 -0
  195. evalkit/bundled/ui/assets/monacoEditor-DsoPncxW.js +68 -0
  196. evalkit/bundled/ui/assets/monacoEditor-n7clI0si.css +1 -0
  197. evalkit/bundled/ui/assets/msdax-DauUninz.js +1 -0
  198. evalkit/bundled/ui/assets/mysql-SOo6toE5.js +1 -0
  199. evalkit/bundled/ui/assets/objective-c-FvmIjYaQ.js +1 -0
  200. evalkit/bundled/ui/assets/pascal-DrH0SRf2.js +1 -0
  201. evalkit/bundled/ui/assets/pascaligo-D-ptJ9y-.js +1 -0
  202. evalkit/bundled/ui/assets/perl-oz_6vUea.js +1 -0
  203. evalkit/bundled/ui/assets/pgsql-DTj74zXo.js +1 -0
  204. evalkit/bundled/ui/assets/php-nr791fC2.js +1 -0
  205. evalkit/bundled/ui/assets/pla-CopQ2nXW.js +1 -0
  206. evalkit/bundled/ui/assets/postiats-43DmfD33.js +1 -0
  207. evalkit/bundled/ui/assets/powerquery-D3hlyOfw.js +1 -0
  208. evalkit/bundled/ui/assets/powershell-DmHpPYUd.js +1 -0
  209. evalkit/bundled/ui/assets/protobuf-C531GsRP.js +2 -0
  210. evalkit/bundled/ui/assets/pug-Z5eAx3Zn.js +1 -0
  211. evalkit/bundled/ui/assets/python-CieHVM9n.js +1 -0
  212. evalkit/bundled/ui/assets/qsharp-DkqhCAOL.js +1 -0
  213. evalkit/bundled/ui/assets/r-BwWrilGY.js +1 -0
  214. evalkit/bundled/ui/assets/razor-sLewSMyp.js +1 -0
  215. evalkit/bundled/ui/assets/redis-ClamHrr6.js +1 -0
  216. evalkit/bundled/ui/assets/redshift-DT7zqm-g.js +1 -0
  217. evalkit/bundled/ui/assets/restructuredtext-BYgofb2h.js +1 -0
  218. evalkit/bundled/ui/assets/ruby-DezsRK8O.js +1 -0
  219. evalkit/bundled/ui/assets/rust-DdL9SqIa.js +1 -0
  220. evalkit/bundled/ui/assets/sb-CcwsVR0C.js +1 -0
  221. evalkit/bundled/ui/assets/scala-DHpiXF5c.js +1 -0
  222. evalkit/bundled/ui/assets/scheme-BeGwcela.js +1 -0
  223. evalkit/bundled/ui/assets/scss-gp-XZpBa.js +3 -0
  224. evalkit/bundled/ui/assets/shell-CC2rA5mh.js +1 -0
  225. evalkit/bundled/ui/assets/solidity-BEEn4gHE.js +1 -0
  226. evalkit/bundled/ui/assets/sophia-CRfGWb83.js +1 -0
  227. evalkit/bundled/ui/assets/sparql-D_Lu-MrJ.js +1 -0
  228. evalkit/bundled/ui/assets/sql-NEE52Syq.js +1 -0
  229. evalkit/bundled/ui/assets/st-DbInun42.js +1 -0
  230. evalkit/bundled/ui/assets/swift-Bxkupp3x.js +1 -0
  231. evalkit/bundled/ui/assets/systemverilog-Bz4Y3fRF.js +1 -0
  232. evalkit/bundled/ui/assets/tcl-DISqw1ZD.js +1 -0
  233. evalkit/bundled/ui/assets/ts.worker-DIAQkoB3.js +67741 -0
  234. evalkit/bundled/ui/assets/tsMode-BcVQ1nu0.js +11 -0
  235. evalkit/bundled/ui/assets/twig-De2hgUGE.js +1 -0
  236. evalkit/bundled/ui/assets/typescript-CUvNWd9p.js +1 -0
  237. evalkit/bundled/ui/assets/typespec-B8J7ngcE.js +1 -0
  238. evalkit/bundled/ui/assets/vb-DV3o63ZY.js +1 -0
  239. evalkit/bundled/ui/assets/wgsl-DpFanUEy.js +298 -0
  240. evalkit/bundled/ui/assets/workers-CwpYQtzp.js +1 -0
  241. evalkit/bundled/ui/assets/xml-C1HnXMdF.js +1 -0
  242. evalkit/bundled/ui/assets/yaml-D7Ey3HQu.js +1 -0
  243. evalkit/bundled/ui/favicon.svg +6 -0
  244. evalkit/bundled/ui/index.html +14 -0
  245. evalkit/cli/__init__.py +0 -0
  246. evalkit/cli/admin_commands.py +590 -0
  247. evalkit/cli/client.py +67 -0
  248. evalkit/cli/init_server.py +165 -0
  249. evalkit/cli/local_run.py +195 -0
  250. evalkit/cli/main.py +1365 -0
  251. evalkit/cli/runs_commands.py +539 -0
  252. evalkit/cli/server_commands.py +130 -0
  253. evalkit/cli/skill_targets.py +43 -0
  254. evalkit/cli/tokens_commands.py +52 -0
  255. evalkit/cli/traces_commands.py +332 -0
  256. evalkit/cli/update.py +85 -0
  257. evalkit/client/__init__.py +0 -0
  258. evalkit/client/agents.py +25 -0
  259. evalkit/client/api.py +193 -0
  260. evalkit/client/blob.py +104 -0
  261. evalkit/client/connection.py +88 -0
  262. evalkit/client/evaluators.py +11 -0
  263. evalkit/client/sessions.py +17 -0
  264. evalkit/client/store.py +139 -0
  265. evalkit/client/summary.py +46 -0
  266. evalkit/client/sync.py +198 -0
  267. evalkit/config.py +227 -0
  268. evalkit/contracts/__init__.py +0 -0
  269. evalkit/contracts/atif.py +115 -0
  270. evalkit/contracts/cases.py +456 -0
  271. evalkit/contracts/custom_evaluator.py +58 -0
  272. evalkit/contracts/enums.py +86 -0
  273. evalkit/contracts/esf.py +120 -0
  274. evalkit/contracts/harness.py +281 -0
  275. evalkit/contracts/notes.json +4 -0
  276. evalkit/contracts/notes.py +7 -0
  277. evalkit/contracts/settings.py +41 -0
  278. evalkit/core/__init__.py +0 -0
  279. evalkit/core/access.py +75 -0
  280. evalkit/core/agents.py +65 -0
  281. evalkit/core/blob.py +46 -0
  282. evalkit/core/capabilities.py +36 -0
  283. evalkit/core/costmap.py +90 -0
  284. evalkit/core/custom_eval.py +50 -0
  285. evalkit/core/data/cost_map.json +81546 -0
  286. evalkit/core/endpoints.py +31 -0
  287. evalkit/core/evaluators/__init__.py +29 -0
  288. evalkit/core/evaluators/base.py +121 -0
  289. evalkit/core/evaluators/gauges.py +84 -0
  290. evalkit/core/evaluators/presentation.py +166 -0
  291. evalkit/core/evaluators/response_time.py +21 -0
  292. evalkit/core/evaluators/rubrics.py +494 -0
  293. evalkit/core/evaluators/tool_trajectory.py +187 -0
  294. evalkit/core/evaluators/trajectory_rubrics.py +198 -0
  295. evalkit/core/fixtures.py +57 -0
  296. evalkit/core/harness.py +227 -0
  297. evalkit/core/harness_check.py +191 -0
  298. evalkit/core/importer.py +257 -0
  299. evalkit/core/judge.py +78 -0
  300. evalkit/core/lint.py +265 -0
  301. evalkit/core/overlays.py +76 -0
  302. evalkit/core/paths.py +25 -0
  303. evalkit/core/promotion.py +94 -0
  304. evalkit/core/pull.py +198 -0
  305. evalkit/core/python_eval.py +59 -0
  306. evalkit/core/remote_evaluators.py +32 -0
  307. evalkit/core/review.py +220 -0
  308. evalkit/core/run_digest.py +421 -0
  309. evalkit/core/runner.py +995 -0
  310. evalkit/core/scorecard.py +255 -0
  311. evalkit/core/traces/__init__.py +0 -0
  312. evalkit/core/traces/convert.py +336 -0
  313. evalkit/core/traces/importer.py +113 -0
  314. evalkit/core/traces/mapping.py +385 -0
  315. evalkit/core/traces/poll.py +38 -0
  316. evalkit/core/traces/raw.py +21 -0
  317. evalkit/core/traces/sessions.py +172 -0
  318. evalkit/core/traces/settle.py +14 -0
  319. evalkit/core/traces/sources/__init__.py +19 -0
  320. evalkit/core/traces/sources/base.py +25 -0
  321. evalkit/core/traces/sources/phoenix.py +121 -0
  322. evalkit/core/trajectory.py +248 -0
  323. evalkit/core/workspace.py +30 -0
  324. evalkit/credentials.py +119 -0
  325. evalkit/db/__init__.py +0 -0
  326. evalkit/db/agents.py +289 -0
  327. evalkit/db/alembic/env.py +90 -0
  328. evalkit/db/alembic/script.py.mako +28 -0
  329. evalkit/db/alembic/versions/0011_baseline.py +1002 -0
  330. evalkit/db/alembic/versions/0012_ticket_token_kind.py +27 -0
  331. evalkit/db/alembic/versions/0013_keys_and_llm_providers.py +67 -0
  332. evalkit/db/cases.py +608 -0
  333. evalkit/db/crypto.py +12 -0
  334. evalkit/db/evaluators.py +156 -0
  335. evalkit/db/experiments.py +363 -0
  336. evalkit/db/fixture_blobs.py +91 -0
  337. evalkit/db/keys.py +78 -0
  338. evalkit/db/llm_providers.py +176 -0
  339. evalkit/db/locks.py +6 -0
  340. evalkit/db/mappings.py +168 -0
  341. evalkit/db/models.py +567 -0
  342. evalkit/db/promotion.py +271 -0
  343. evalkit/db/rekey.py +46 -0
  344. evalkit/db/review.py +250 -0
  345. evalkit/db/review_state.py +50 -0
  346. evalkit/db/runs.py +533 -0
  347. evalkit/db/scorecard.py +300 -0
  348. evalkit/db/session.py +71 -0
  349. evalkit/db/sessions.py +90 -0
  350. evalkit/db/spans.py +360 -0
  351. evalkit/db/store.py +209 -0
  352. evalkit/db/tokens.py +100 -0
  353. evalkit/db/trace_imports.py +308 -0
  354. evalkit/db/trace_sources.py +131 -0
  355. evalkit/db/users.py +186 -0
  356. evalkit/db/workspaces.py +232 -0
  357. evalkit/paths.py +33 -0
  358. evalkit/sdk/__init__.py +29 -0
  359. evalkit/sdk/binding.py +69 -0
  360. evalkit/sdk/evaluators.py +56 -0
  361. evalkit/sdk/runner.py +957 -0
  362. evalkit/sdk/tracing.py +166 -0
  363. evalkit/store/__init__.py +0 -0
  364. evalkit/store/base.py +354 -0
  365. evalkit/store/blob.py +69 -0
  366. evalkit/version.py +44 -0
  367. evalkit_py-0.2.0.dev12.dist-info/METADATA +205 -0
  368. evalkit_py-0.2.0.dev12.dist-info/RECORD +371 -0
  369. evalkit_py-0.2.0.dev12.dist-info/WHEEL +4 -0
  370. evalkit_py-0.2.0.dev12.dist-info/entry_points.txt +2 -0
  371. evalkit_py-0.2.0.dev12.dist-info/licenses/LICENSE +661 -0
@@ -0,0 +1,509 @@
1
+ ---
2
+ name: evalkit-usage
3
+ description: Everyday use of an already-deployed evalkit server from the CLI — install the CLI, log in, sync a suite, run experiments, read scorecards, collect failures, and move cases through review. Use when a developer on a client team needs to do anything with evalkit that is not deploying or upgrading the server itself (that is the evalkit-deployment skill).
4
+ ---
5
+
6
+ # evalkit usage
7
+
8
+ For any developer on a team whose evalkit server is already running. You do
9
+ not need to know how the server was deployed; you need its URL and a username
10
+ from whoever deployed it.
11
+
12
+ No server yet, or want a sandbox of your own? The try-it stack runs evalkit on
13
+ your machine with your LLM as the judge, and walks a sample agent through an
14
+ SDK run with traces: the kit is `try/` in the evalkit-deployment skill, and
15
+ the walkthrough is [Try locally](../evalkit-docs/try-locally.md).
16
+
17
+ `evalkit skills install` puts the evalkit user docs in `evalkit-docs/`
18
+ beside this skill; links to `../evalkit-docs/` point there. In the evalkit
19
+ repository the same pages are in `docs/user/`, and every evalkit server shows
20
+ them under `/docs`. In the docs, `{{origin}}` means your evalkit server's URL.
21
+
22
+ **The CLI is the reference.** `evalkit --help` lists every command and
23
+ `evalkit <command> --help` documents arguments, options and an example. Read
24
+ those instead of this file for syntax; this file only says which command does
25
+ what and explains the two things the help text cannot: how to get connected
26
+ and how case review works.
27
+
28
+ ## Install and log in
29
+
30
+ 1. Install the CLI from PyPI at the server's version. evalkit is on PyPI as
31
+ `evalkit-py`; `curl <server url>/api/cli` prints the server's version:
32
+
33
+ ```bash
34
+ uv tool install --reinstall "evalkit-py==<version>"
35
+ ```
36
+
37
+ With pipx: `pipx install --force "evalkit-py==<version>"`.
38
+ `<server url>/docs/install` in the web UI shows every command with the
39
+ version filled in. `evalkit --version` prints what you have.
40
+
41
+ For SDK runs, add evalkit to the project at the same version:
42
+ `uv add "evalkit-py[otel]==<version>"`; `uv.lock` pins it. To keep evalkit
43
+ out of the app's dependencies, run the eval script with
44
+ `uv run --with "evalkit-py[otel]==<version>" python eval/run.py` instead.
45
+ After a server deploy, local and SDK runs refuse to start until the
46
+ versions match: run `evalkit update` from the project root, which
47
+ reinstalls the CLI, moves the `evalkit-py` pin in `pyproject.toml` (and
48
+ runs `uv sync`) and refreshes the skills `evalkit skills install` put in
49
+ your repos, in one step.
50
+ 2. `evalkit login --url <url>` with your username, e.g. `evalkit login
51
+ --url https://evalkit.internal`. The login is stored in
52
+ `~/.evalkit/config.toml`. The CLI talks to one server at a time; logging
53
+ in again replaces the stored login. Dev and prod are shared workspaces on
54
+ that server (`@dev`, `@prod`), not separate logins. The token expires after
55
+ the TTL the deployer configured (default 30 days) — when commands start
56
+ failing with 401, log in again. `evalkit whoami` shows when the token
57
+ expires; run it before a long run.
58
+ 3. Scripts and CI have two options. Set `EVALKIT_SERVER_URL` and
59
+ `EVALKIT_TOKEN` in the environment to bypass the file. Or, better, keep a
60
+ password in the secret store and run a non-interactive `evalkit login`
61
+ at the start of every job (see `evalkit login --help`). A stored token
62
+ will expire and break the job; a stored password will not.
63
+ `EVALKIT_TIMEOUT` (seconds, default 120) sets how long the CLI and SDK
64
+ wait for each server call; it does not change the server's limits on
65
+ its own calls to a harness. Every server
66
+ call needs a login, lint included; only `evalkit lint --offline` runs
67
+ without one, and it skips the checks that need server state. The server
68
+ lint covers everything `--offline` does, fixture keys included, so CI
69
+ needs only the server lint. Log in as
70
+ `admin` (the deployer's `EVALKIT_ADMIN_PASSWORD`) in both the lint job
71
+ and the sync job. The sync job targets a shared workspace
72
+ (`--workspace dev`) and passes `--actor <merge author>` so the changelog
73
+ names the real author (`--actor` is admin only). Install
74
+ the CLI at the start of the job so CI always runs the server's build:
75
+
76
+ ```bash
77
+ uv tool install --reinstall "evalkit-py==$(curl -fsSL "$EVALKIT_SERVER_URL/api/cli" | jq -r .version)"
78
+ ```
79
+
80
+ The web UI serves at the server URL with the same credentials.
81
+
82
+ ## Workspaces, references and local runs
83
+
84
+ Every dataset and agent lives in a workspace:
85
+
86
+ - Every user owns a **personal workspace** named after their username.
87
+ - An admin creates **shared workspaces**, e.g. `dev` and `prod`, and adds
88
+ members as `writer` (may sync and create code-driven agents there) or
89
+ `reviewer` (may approve cases there). Only an admin may point a shared
90
+ agent or remote evaluator at a URL, since the server sends that
91
+ workspace's API keys there. `evalkit workspaces list` and
92
+ `evalkit workspaces members list <ws>` show them.
93
+ - CI syncs into the shared workspace the deployer picked (usually `dev`).
94
+
95
+ References:
96
+
97
+ - The CLI and SDK accept a bare name (`finance`, `myagent`). It means your
98
+ personal workspace.
99
+ - `name@workspace` names any other one: `finance@dev`, `ouragent@prod`.
100
+ - API paths and UI URLs always carry `@workspace`.
101
+
102
+ The agent you pick decides who drives the run:
103
+
104
+ - An agent without a `harness_url` is code-driven: your own code runs it with
105
+ `run_experiment` (an SDK run), and its trajectories come from its
106
+ OpenTelemetry traces. This is the default way to start, and the try-it
107
+ stack walks through it.
108
+ - An agent with a `harness_url` serves the Harness API. Use it for a deployed
109
+ agent: in a shared workspace the server drives it (a server run); in your
110
+ personal workspace your CLI drives it from this machine (a local run).
111
+
112
+ [Workspaces](../evalkit-docs/workspaces.md) has the
113
+ full table, with examples for `dev` and `prod`, and what happens when you run
114
+ from several branches.
115
+
116
+ ### Agents and remote evaluators
117
+
118
+ Agents and remote (HTTP) custom evaluators are rows on the server. You
119
+ create them once with the commands below.
120
+
121
+ ```bash
122
+ evalkit agents create myagent --trajectory-source otel --mapping mapping.json # code-driven, your workspace
123
+ evalkit agents create ouragent --workspace dev --harness-url https://ouragent.internal/evalkit/v1 # a deployed agent
124
+ evalkit evaluators create citation_check --endpoint http://localhost:9000/evaluate
125
+ evalkit agents list --workspace dev
126
+ ```
127
+
128
+ - `agents create|edit|show|list|archive|restore` and
129
+ `evaluators create|edit|list|archive`. Creating one in a shared workspace
130
+ needs the writer role there.
131
+ - An OTel agent (`--trajectory-source otel`) needs `--mapping <file.json>`
132
+ when you create it (see the **connect-traces** skill).
133
+ - `agents edit <agent> --trajectory-source otel|atif` switches an existing
134
+ agent. Switching to `otel` takes `--mapping <file.json>`, or reuses the
135
+ agent's last active mapping. It's refused while one of the agent's
136
+ experiments is running; finished experiments keep the source they ran with.
137
+ - A run scores with the remote evaluators in the agent's workspace.
138
+ - Agents cannot be renamed. Archive one and create another instead.
139
+
140
+ ### evalkit.yaml and credentials
141
+
142
+ Put an `evalkit.yaml` in your repo. `evalkit run finance --agent myagent`
143
+ then syncs `<cases>/finance` to `finance@<you>`, drives `myagent` from this
144
+ machine, scores, and writes everything to the server. Run `finance@dev` to
145
+ use the shared cases instead (Approved ones only, no sync). Fixture bytes are
146
+ read from the `fixtures` directory and uploaded by sha256 on every run or
147
+ sync.
148
+
149
+ ```yaml
150
+ cases: eval/cases # optional: directory whose children are datasets
151
+ fixtures: eval/fixtures # optional: fixture bytes, flat, keyed by filename
152
+ credentials: # env:NAME references only, never the key itself
153
+ agents:
154
+ myagent: env:MYAGENT_API_KEY # bare name = your workspace
155
+ evaluators:
156
+ citation_check: env:CITATION_API_KEY
157
+ llm_providers:
158
+ https://litellm.example.com: env:LITELLM_API_KEY # keyed by judge base URL
159
+ ```
160
+
161
+ - `credentials.agents` here is only for your personal Harness API agents.
162
+ The server drives shared agents (`ouragent@dev`) with keys stored in its
163
+ database (`evalkit agents create|edit … --api-key-env NAME`, by an admin or
164
+ a writer), so an entry for one here is never read. The same holds for
165
+ shared remote evaluators.
166
+ - Keys come from the environment or from a `.env` file next to
167
+ `evalkit.yaml`. A variable set in the environment wins over `.env`.
168
+ - An agent or evaluator with no `credentials` entry gets no auth header, and
169
+ the run prints one line saying so.
170
+ - A judge with no entry for its base URL fails the run before it starts:
171
+ `no credentials.llm_providers entry for <url>`.
172
+ - `credentials.judges` was renamed to `credentials.llm_providers`; the old
173
+ name fails to load.
174
+ - `cases` and `fixtures` are only needed to sync your own datasets by name.
175
+
176
+ ### The judge
177
+
178
+ The judge is chosen per experiment. By default it is the server's
179
+ default judge, which an admin sets with `evalkit judge-default set`
180
+ (`evalkit judge-default show` prints it); `evalkit run` takes `--judge-model`, `--judge-base-url` and
181
+ `--judge-effort` to change it for one experiment. `evalkit evaluate` reuses
182
+ the experiment's judge. A server run may only use a judge whose base URL is a
183
+ registered LLM provider (`evalkit llm-providers list`).
184
+
185
+ Inside a dataset directory, subfolders become tags (`finance/statement-analysis/x.yaml`
186
+ gets the tag `statement-analysis`), and `evalkit run finance/statement-analysis`
187
+ runs that split. Local runs require the CLI and server versions to match.
188
+
189
+ ## SDK runs
190
+
191
+ An agent that is a library, a notebook, or a service with its own job runner
192
+ does not need a Harness API. Install the SDK into the project (the web UI's
193
+ Docs → Install page has the exact command for your server; it is
194
+ `evalkit-py` with the `otel` extra), create a code-driven agent (no `--harness-url`),
195
+ and run the experiment from your own code. A local run uses
196
+ your own login for the API calls (the one from `evalkit login`, or
197
+ `EVALKIT_SERVER_URL` and `EVALKIT_TOKEN`), and for the exported traces when
198
+ the agent runs inside the same Python process. Any exporter outside that
199
+ process (a worker, a queue consumer, a service in another language) needs
200
+ an agent token from `evalkit tokens create --agent <name>`: it never expires,
201
+ while the login token runs out under a long-running worker and the export
202
+ fails silently.
203
+
204
+ ```python
205
+ # eval/run.py — uv run python eval/run.py
206
+ from evalkit.sdk import run_experiment, evaluator, tracing
207
+ from myagent import MyAgent, setup_tracing
208
+
209
+ setup_tracing() # your own OpenTelemetry provider
210
+ tracing.register(agent="myagent") # add evalkit as an export destination
211
+ agent = MyAgent()
212
+
213
+
214
+ def task(input: dict, files: list) -> str:
215
+ return agent.ask(input["question"], attachments=[f.path for f in files])
216
+
217
+
218
+ @evaluator(name="citation_check")
219
+ def citation_check(case, run) -> float:
220
+ return 1.0 if run.output and run.output.get("citations") else 0.0
221
+
222
+
223
+ if __name__ == "__main__":
224
+ print(
225
+ run_experiment(
226
+ dataset="finance", agent="myagent", task=task, evaluators=[citation_check]
227
+ ).url
228
+ )
229
+ ```
230
+
231
+ ```bash
232
+ # no --harness-url: a code-driven agent. Trajectories come from its spans.
233
+ cp <skills>/connect-traces/references/openinference.json eval/mapping.json
234
+ evalkit agents create myagent --trajectory-source otel --mapping eval/mapping.json
235
+ ```
236
+
237
+ Rules of the road:
238
+
239
+ - `run_experiment` is a push model: your process runs the task once per case
240
+ and repetition, exports the agent's OpenTelemetry spans to the server,
241
+ waits for each session to settle, and records runs and scores through the
242
+ API. `dataset`, `case_ids`, `split`, `repetitions`, `model` and `resume` mean
243
+ what they mean on `evalkit run` (see `evalkit --help`).
244
+ - The task's parameters bind **by name** from `input`, `files`, `model` and
245
+ `metadata`, in any order; any other required parameter is an error, and
246
+ a task with one parameter of another name (`def task(q)`) gets the input.
247
+ - `input`: the case input, minus `files`.
248
+ - `files`: a list of `Fixture` with `name` (the fixture key), `path` (the
249
+ downloaded file) and `context` (the file's description from the fixture
250
+ registry, the text a Harness API agent gets with the file; show it to
251
+ the agent).
252
+ - `model`: the `model` argument of `run_experiment`, else `None`. It is
253
+ the only way the override reaches the agent; `run_experiment` warns
254
+ when `model` is passed and the task has no `model` parameter.
255
+ - `metadata`: `session_id` (the SDK's session id), `experiment_id`
256
+ (`None` on a dry run), `case_id`, `repetition` (from 1) and `tags`.
257
+ - In a notebook use `await arun_experiment(...)`; the sync form refuses to
258
+ run inside an event loop.
259
+ - A task may return an ATIF document instead of tracing
260
+ (`RunResult(answer=..., trajectory=...)`).
261
+ - An agent in another process joins the run in one of two ways: the task
262
+ injects the W3C trace context (`opentelemetry.propagate.inject(headers)`)
263
+ and the agent continues the trace, or the agent stamps its own session id
264
+ (the attribute its mapping's `session_id` rule names) on its root span and the task returns `RunResult(answer=...,
265
+ session_id=...)`. A queue-backed agent that opens its session in a worker
266
+ returns `RunResult(session_id=...)` with the id its own API returns, or
267
+ the task passes `metadata["session_id"]` along with the job and the agent
268
+ uses it as its session id. The **connect-traces** skill has the details,
269
+ including how a shared worker exports only its eval runs if the developer
270
+ wants that: `tracing.eval_run(metadata)` marks a job, and
271
+ `tracing.processor(agent=..., only=tracing.is_eval_span)` keeps every span
272
+ of a marked trace, bridged spans included. Spans from another process go
273
+ through that process's own exporter, which makes its own choice.
274
+ - A pipeline that should not touch the global tracer provider, or code that
275
+ hands spans straight to a processor, uses `tracing.processor(agent=...)`
276
+ or `tracing.exporter(agent=...)` instead of `tracing.register`.
277
+ - evalkit records fixed capabilities for a code-driven agent (`thinking`,
278
+ `artifacts` and `workspace` false) and never reads them from spans. Pass
279
+ `--provides thinking=true` to `evalkit agents create` (or `edit`) when its
280
+ spans carry the model's reasoning.
281
+ - Python evaluators (`@evaluator`) see the same payload as the HTTP Custom
282
+ Evaluator API and are selected by name under a case's `evaluators.custom`.
283
+ Re-score with `evaluate_experiment(...)` from the same script;
284
+ `evalkit evaluate` refuses those experiments.
285
+ - `dry_run=True` runs one case without creating an experiment and prints
286
+ what the server made of the session. Use it while wiring up tracing, then
287
+ follow the **connect-traces** skill if the span kinds or messages look
288
+ wrong. The mapping you created the agent with decides how spans are read.
289
+ - `evalkit traces check <agent> <session id>` is the diagnostic; `evalkit
290
+ tokens create --agent <name>` mints a collector-only token for a deployed
291
+ agent that cannot carry your login.
292
+ - An agent token is bound to one agent on the server, and the agent must
293
+ exist first (`evalkit agents create`). Neither `tokens create` nor the
294
+ first span export creates an agent. You mint, list and revoke only your
295
+ own tokens.
296
+
297
+ ## Already have a Harness API?
298
+
299
+ Keep it. Create the agent with `--trajectory-source otel --mapping <file>`
300
+ next to its `--harness-url`, and only the trajectory moves to OpenTelemetry: evalkit still drives the agent through the Harness
301
+ API (`evalkit run`, server runs, the Workspace tab), and builds the
302
+ trajectory from the spans instead of `GET /runs/{id}/trajectory`. The harness
303
+ then has to:
304
+
305
+ - tag the spans of each run with the run id it returned from `POST /runs`, in
306
+ the attribute its mapping's `session_id` rule names (`session.id` in the
307
+ OpenInference reference, `gen_ai.conversation.id` in gen_ai). The root span
308
+ is enough; children inherit.
309
+ A queue-backed harness whose worker opens its own session can return that
310
+ session id as the `run_id` instead;
311
+ - export them to the collector (see the **connect-traces** skill). The
312
+ harness learns that a run is an eval run from the `metadata` of
313
+ `POST /runs` (`experiment_id`, `case_id`, `repetition`); a harness that
314
+ exports only eval runs passes that to `tracing.eval_run`, with the
315
+ `run_id` as `session_id`;
316
+ - declare `provides.trajectory: false`, or drop the trajectory endpoint.
317
+
318
+ Move to the SDK (`run_experiment`, no `harness_url`) only to stop hosting
319
+ the harness. You lose server-started runs and the Workspace tab, and
320
+ `run_experiment` refuses an agent that has a `harness_url`, so it is one or
321
+ the other per agent. Do not create a second agent for the same code just to
322
+ use `run_experiment`: the two names get separate run histories, tokens and
323
+ mappings.
324
+
325
+ ## What evalkit can see of your agent
326
+
327
+ Each Harness API endpoint lets evalkit do one thing. This table is about
328
+ agents that have a Harness API (deployment paths 3b and 3c). On the SDK +
329
+ traces path (3a) there is no harness and none of these endpoints exist; those
330
+ runs show only what the task returns and the spans it exports.
331
+
332
+ | Endpoint | Lets evalkit | Capability flag |
333
+ | -- | -- | -- |
334
+ | `GET /capabilities` | gate evaluators on what the agent supports | part of every Harness API |
335
+ | `POST /runs` | invoke the agent on a case | part of every Harness API |
336
+ | `GET /runs/{id}` | wait for the run, read its answer and output | part of every Harness API |
337
+ | `GET /runs/{id}/trajectory` | read the trajectory (or take it from traces for an `otel` agent) | `provides.trajectory` |
338
+ | `GET /runs/{id}/files[/{path}]` | read the workspace: the run's Workspace tab and artifact copies | `provides.workspace` |
339
+ | `GET /runs` | list the agent's sessions on the Runs page | `provides.run_listing` |
340
+ | `POST /runs/{id}/stop` | cancel a run that hit its time limit | `accepts.stop` |
341
+
342
+ The Workspace tab needs the files endpoints, so a code-driven agent never has one.
343
+ If a developer wants to see the files an agent wrote, the agent needs a
344
+ Harness API with at least the files endpoints; its trajectory can still come
345
+ from traces (a harness agent with `--trajectory-source otel`). The web UI's Docs →
346
+ Harness API page has the full table.
347
+
348
+ ## Which command
349
+
350
+ | You want to | Command |
351
+ |---|---|
352
+ | See what datasets exist and their versions | `evalkit datasets list` |
353
+ | List a dataset's cases with review state, tags and fixtures (to pick `--case-id`s) | `evalkit datasets list <dataset>` (`--state`, `--tag`) |
354
+ | Check case YAML before pushing | `evalkit lint` |
355
+ | Check case inputs against an agent's `input_schema` (on demand, not CI) | `evalkit lint <dir> --agent <name>` |
356
+ | Publish a dataset directory to your workspace (or `--workspace dev` as a writer there) | `evalkit sync` |
357
+ | Run a dataset against an agent (yours from this machine, or a shared one on the server) | `evalkit run` |
358
+ | Create or change agents and remote evaluators | `evalkit agents`, `evalkit evaluators` |
359
+ | See workspaces and who can write or review in them | `evalkit workspaces` |
360
+ | Check which server and user the CLI uses | `evalkit whoami` |
361
+ | Check on or summarise an experiment | `evalkit status`, `evalkit summary` |
362
+ | List an agent's runs: app runs (outside any experiment) and eval runs | `evalkit runs list` (`--source app\|eval`, `--since`, `--until`) |
363
+ | Pull runs to a local directory (ATIF trajectories, case versions, scores) for diagnosis or profiling | `evalkit runs pull <agent>` (same filters, `--limit`, `--offset`) or `evalkit runs pull --experiment <id>` |
364
+ | See or fetch a pulled run's workspace files and full tool outputs | `evalkit runs files <pull dir> <run_id>` lists the tree; add `--path <file or folder>` to fetch only those |
365
+ | Generate new eval cases from an agent's app runs (production, staging or manual traffic) | the `eval-driven-development` skill, Loop 2 (`runs list` / `runs pull --source app`, then analysis and authoring) |
366
+ | Re-score recorded runs after an evaluator change, or retry evaluators that errored | `evalkit evaluate` (`--refetch-trajectories` for runs whose trajectory arrived late) |
367
+ | Inspect a traced session, push or list a span mapping | `evalkit traces` (subcommands `check`, `mapping push`, `mapping list`, `import`) |
368
+ | Mint, list or revoke a collector token for a deployed agent | `evalkit tokens` |
369
+ | Move cases through review | `evalkit review` (subcommands below) |
370
+ | Ask about runs, failures, usage or experiments from Claude, Cursor or Codex | the MCP server at `{{origin}}/mcp` (below) |
371
+ | Update the CLI and a project's `evalkit-py` pin to the server's version | `evalkit update` |
372
+ | Add the SDK to a project | `uv add "evalkit-py[otel]==<server version>"` |
373
+ | Vendor these skills into a repo | `evalkit skills install` |
374
+
375
+ Read `evalkit <command> --help` before you run a command. It is the source of
376
+ truth for how the command behaves: for example, `run` executes only Approved
377
+ cases on shared datasets (personal datasets run every case) and checks
378
+ inputs against the agent's schema, `sync` on a directory prunes, and
379
+ `collect` bundles only failures unless `--all`.
380
+
381
+ Cases that need input files name a fixture key; see
382
+ [`references/suite-fixtures.md`](references/suite-fixtures.md) for how to
383
+ register the file and upload its bytes before you sync.
384
+
385
+ ## Case review
386
+
387
+ Review applies to datasets in shared workspaces. Datasets in a personal
388
+ workspace have no review state. Review never filters a run: `evalkit run`
389
+ executes every case the selection picks, whatever its state. Review decides
390
+ what gets promoted (below).
391
+
392
+ Every case in a shared suite dataset is in exactly one review state, derived from
393
+ its current content hash and the latest decisive event recorded at that
394
+ hash. Editing a case changes the hash, so an edit resets it to Unreviewed on the
395
+ next sync unless carry-over applies (below).
396
+
397
+ ```mermaid
398
+ stateDiagram-v2
399
+ [*] --> Unreviewed: sync creates case
400
+
401
+ Unreviewed --> ReviewRequested: request review
402
+ Unreviewed --> Approved: approve
403
+ Unreviewed --> ChangesRequested: request changes
404
+
405
+ ReviewRequested --> Approved: approve
406
+ ReviewRequested --> ChangesRequested: request changes
407
+ ReviewRequested --> ReviewRequested: request review (new reviewer)
408
+
409
+ ChangesRequested --> ReviewRequested: request review
410
+ ChangesRequested --> Approved: approve
411
+
412
+ Approved --> ChangesRequested: request changes (retrospective)
413
+ Approved --> ReviewRequested: request review (retrospective)
414
+
415
+ Approved --> Unreviewed: edit and sync
416
+ Unreviewed --> Unreviewed: edit and sync
417
+ ReviewRequested --> ReviewRequested: edit and sync (carry-over)
418
+ ChangesRequested --> ReviewRequested: edit and sync (carry-over)
419
+
420
+ Approved --> [*]: promoted to the target workspace (if linked)
421
+ ```
422
+
423
+ | State | Meaning |
424
+ |---|---|
425
+ | Unreviewed | No decisive event at the current content. Every new or edited case starts here. |
426
+ | Review requested | Someone asked a reviewer to look at this content. |
427
+ | Changes requested | A reviewer looked and wants an edit. |
428
+ | Approved | A reviewer approved this exact content. In a promotion source, approving promotes it. |
429
+
430
+ Rules the diagram encodes:
431
+
432
+ - Any decisive event may be recorded from any state; the latest one wins.
433
+ Requesting review or changes on an Approved case is a retrospective
434
+ re-review.
435
+ - An edit is not an event. Re-syncing a case that was in Review requested or
436
+ Changes requested carries the request over to the new content, so a fix
437
+ goes straight back to the reviewer instead of silently becoming Unreviewed.
438
+ - Only **reviewers** of that workspace (`evalkit workspaces members list
439
+ <ws> --role reviewer`) may approve or request changes. Everyone can author,
440
+ sync to their own workspace, request review and comment; a comment is
441
+ resolved by its author or a reviewer. Syncing to a shared workspace needs
442
+ the writer role there, which is why CI usually does it as admin.
443
+
444
+ ### Promotion between workspaces
445
+
446
+ An admin can link two shared workspaces, a **promotion source** and a
447
+ **promotion target**: `evalkit workspaces promote-to dev prod`. From then on,
448
+ approving a case in `finance@dev` also writes that exact version into
449
+ `finance@prod`, already Approved, together with the `dev` overlays that extend
450
+ it. Nothing else reaches the target:
451
+
452
+ - `evalkit sync --workspace prod` and review decisions on `prod` datasets are
453
+ refused with a 409 that names the source. Comments are still allowed; the
454
+ case page on the target links to the same case in the source.
455
+ - Removing a case from the source, or requesting changes on a newer version,
456
+ leaves the target untouched. The target keeps the last approved version
457
+ until a newer one is approved.
458
+ - Approving the same content again changes nothing in the target except the
459
+ overlays, which are refreshed.
460
+ - The target dataset must exist first: `evalkit datasets create finance@prod`
461
+ (a writer of `prod`). Datasets synced into the target *before* the link
462
+ keep their cases; those stay Unreviewed there, and still run, until a
463
+ version is approved in the source.
464
+
465
+ Both case pages show the twin: on the source, "prod: same version · approved
466
+ …" / "ahead of prod" / "not in prod"; on the target, "newer in dev" / "removed
467
+ in dev". The `twin` field on `GET /api/datasets/<ref>/cases` carries the same
468
+ information. `evalkit workspaces list` shows the link; `promote-to <source>
469
+ --none` clears it. One target per source, one source per target, no chains.
470
+
471
+ Commands, in the order a case usually moves: `evalkit review request` →
472
+ reviewer runs `evalkit review queue` → `evalkit review approve` or
473
+ `evalkit review request-changes` → author edits, syncs (carry-over) →
474
+ reviewer approves. `evalkit review show` prints state, changelog and comments
475
+ for a case; `evalkit review comment` and `evalkit review resolve` handle
476
+ discussion. The same actions are available on the case page in the web UI.
477
+
478
+ ## From an MCP client
479
+
480
+ The server is also a read-only MCP server at `{{origin}}/mcp`, for answering
481
+ questions from a coding agent or chat client without the CLI: an agent's runs
482
+ in a window, why a run failed, usage by day, user or tool, a run's
483
+ trajectory and files, and experiments with per-case scores. It cannot change
484
+ anything.
485
+
486
+ Connect with your evalkit login token (the one `evalkit login` stored in
487
+ `~/.evalkit/config.toml`):
488
+
489
+ ```bash
490
+ claude mcp add --transport http evalkit {{origin}}/mcp --header "Authorization: Bearer $EVALKIT_TOKEN"
491
+ ```
492
+
493
+ If your deployer configured `mcp.oauth`, an OAuth client (Claude, Cursor,
494
+ Codex) connects with the URL alone and signs in through your identity
495
+ provider. Agent tokens are refused. The tools, their limits and the shape of
496
+ what they return are in [MCP](../evalkit-docs/mcp.md).
497
+
498
+ ## Deeper work
499
+
500
+ - Connecting an agent's OpenTelemetry traces, and writing a span mapping
501
+ when its instrumentation is custom: the **connect-traces** skill.
502
+ - Writing or editing cases: the **authoring-eval-cases** skill.
503
+ - Turning a failing experiment into agent fixes: the
504
+ **eval-driven-development** skill.
505
+ - Anything about the server itself — config, credentials, shared
506
+ workspaces, upgrades, user accounts — is the deployer's job and the
507
+ **evalkit-deployment** skill.
508
+
509
+ For bugs, feature requests and feedback on evalkit, open an issue at https://github.com/inferedge-ai/evalkit/issues; questions go to https://github.com/inferedge-ai/evalkit/discussions.
@@ -0,0 +1,42 @@
1
+ # Suite fixtures: cases with input files
2
+
3
+ A case that needs an input file names a **fixture key** and the suite
4
+ directory declares the key once in `fixtures.yaml`:
5
+
6
+ ```yaml
7
+ # <suite-dir>/fixtures.yaml
8
+ fixtures:
9
+ - key: q3-board-pack.pdf
10
+ sha256: <sha256 of the file>
11
+ context: >-
12
+ Board pack for Q3 FY2026: management accounts, cash forecast, covenant
13
+ schedule. 42 pages.
14
+ ```
15
+
16
+ ```yaml
17
+ # <suite-dir>/cases/board.yaml
18
+ - id: board-pack-covenant-headroom
19
+ fixtures: [q3-board-pack.pdf]
20
+ input:
21
+ question: What is the covenant headroom at quarter end?
22
+ ```
23
+
24
+ Put the bytes in the `fixtures` directory named in your `evalkit.yaml`.
25
+ `evalkit run` and `evalkit sync` upload every fixture the synced cases
26
+ reference, keyed by its `sha256` (`PUT /api/fixtures/sha256/<sha256>`). They
27
+ skip bytes the server already holds, then upload the suite's YAML and import
28
+ the cases. The sync fails if a file is missing from the directory or its bytes
29
+ do not match the registry `sha256`. The same bytes serve every workspace, so
30
+ syncing the suite into a shared workspace needs no copy step, and nobody
31
+ uploads to blob storage by hand. At run time evalkit
32
+ hands the harness each file by url or as a multipart attachment, with the
33
+ file's `context` alongside it; the case's `input` goes through unchanged.
34
+ Rubric judges see the question with an "Attached files" block listing each
35
+ file's `context`.
36
+
37
+ Rules: keys are flat filenames. Replacing a file means changing the bytes in
38
+ your `fixtures` directory, updating its `sha256`, and running or syncing
39
+ again, which re-versions the cases that use it. Two branches with different
40
+ bytes under the same key never overwrite each other.
41
+ `evalkit lint <suite-dir>` checks keys against the registry before you sync;
42
+ `evalkit lint --offline` runs the same fixture checks without a server.