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.
- evalkit/__init__.py +0 -0
- evalkit/api/__init__.py +0 -0
- evalkit/api/access.py +74 -0
- evalkit/api/agents.py +159 -0
- evalkit/api/app.py +360 -0
- evalkit/api/auth.py +225 -0
- evalkit/api/cli_dist.py +10 -0
- evalkit/api/datasets.py +169 -0
- evalkit/api/deps.py +79 -0
- evalkit/api/download.py +15 -0
- evalkit/api/evaluators.py +121 -0
- evalkit/api/experiments.py +616 -0
- evalkit/api/fixtures.py +95 -0
- evalkit/api/harness_check.py +48 -0
- evalkit/api/imports.py +180 -0
- evalkit/api/limits.py +84 -0
- evalkit/api/llm_providers.py +120 -0
- evalkit/api/mcp/__init__.py +0 -0
- evalkit/api/mcp/auth.py +100 -0
- evalkit/api/mcp/descriptions.py +336 -0
- evalkit/api/mcp/models.py +259 -0
- evalkit/api/mcp/server.py +101 -0
- evalkit/api/mcp/tools.py +844 -0
- evalkit/api/meta.py +19 -0
- evalkit/api/otel.py +350 -0
- evalkit/api/pull.py +197 -0
- evalkit/api/review.py +271 -0
- evalkit/api/runs.py +555 -0
- evalkit/api/server_keys.py +44 -0
- evalkit/api/tokens.py +51 -0
- evalkit/api/trace_imports.py +173 -0
- evalkit/api/trace_sources.py +49 -0
- evalkit/api/traces.py +196 -0
- evalkit/api/users.py +72 -0
- evalkit/api/workspaces.py +131 -0
- evalkit/bundled/contracts/atif-accepted.json +5 -0
- evalkit/bundled/contracts/custom-evaluator-api-v1.json +243 -0
- evalkit/bundled/contracts/harness-api-v1.json +938 -0
- evalkit/bundled/contracts/span-mapping-v1.json +314 -0
- evalkit/bundled/docs/concepts.md +26 -0
- evalkit/bundled/docs/config.md +38 -0
- evalkit/bundled/docs/harness-api.md +44 -0
- evalkit/bundled/docs/install.md +60 -0
- evalkit/bundled/docs/login.md +36 -0
- evalkit/bundled/docs/mappings.md +136 -0
- evalkit/bundled/docs/mcp.md +44 -0
- evalkit/bundled/docs/quickstart.md +142 -0
- evalkit/bundled/docs/sdk-runs.md +171 -0
- evalkit/bundled/docs/tracing.md +171 -0
- evalkit/bundled/docs/try-locally.md +288 -0
- evalkit/bundled/docs/workspaces.md +45 -0
- evalkit/bundled/skills/authoring-eval-cases/SKILL.md +387 -0
- evalkit/bundled/skills/authoring-eval-cases/references/overlays.md +83 -0
- evalkit/bundled/skills/authoring-eval-cases/references/tool-checks.md +71 -0
- evalkit/bundled/skills/connect-traces/SKILL.md +296 -0
- evalkit/bundled/skills/connect-traces/references/gen_ai.json +42 -0
- evalkit/bundled/skills/connect-traces/references/openinference.json +35 -0
- evalkit/bundled/skills/connect-traces/references/span-mapping-schema.md +88 -0
- evalkit/bundled/skills/eval-driven-development/SKILL.md +458 -0
- evalkit/bundled/skills/eval-driven-development/references/analyze-run.md +97 -0
- evalkit/bundled/skills/eval-driven-development/references/diagnose.md +130 -0
- evalkit/bundled/skills/eval-driven-development/references/synthesize-cases.md +87 -0
- evalkit/bundled/skills/eval-driven-development/references/synthesize.md +165 -0
- evalkit/bundled/skills/evalkit-deployment/SKILL.md +332 -0
- evalkit/bundled/skills/evalkit-deployment/config.example.yaml +49 -0
- evalkit/bundled/skills/evalkit-deployment/docker-compose.yml +51 -0
- evalkit/bundled/skills/evalkit-deployment/references/config-and-deploy.md +333 -0
- evalkit/bundled/skills/evalkit-deployment/references/harness-api.md +139 -0
- evalkit/bundled/skills/evalkit-deployment/try/.env.example +11 -0
- evalkit/bundled/skills/evalkit-deployment/try/agent.py +131 -0
- evalkit/bundled/skills/evalkit-deployment/try/cases/acme/balance-sheet/cases.yaml +25 -0
- evalkit/bundled/skills/evalkit-deployment/try/cases/acme/income-statement/cases.yaml +43 -0
- evalkit/bundled/skills/evalkit-deployment/try/config.yaml +17 -0
- evalkit/bundled/skills/evalkit-deployment/try/docker-compose.yml +82 -0
- evalkit/bundled/skills/evalkit-deployment/try/evalkit.yaml +4 -0
- evalkit/bundled/skills/evalkit-deployment/try/mapping.json +42 -0
- evalkit/bundled/skills/evalkit-deployment/try/run.py +33 -0
- evalkit/bundled/skills/evalkit-usage/SKILL.md +509 -0
- evalkit/bundled/skills/evalkit-usage/references/suite-fixtures.md +42 -0
- evalkit/bundled/ui/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- evalkit/bundled/ui/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- evalkit/bundled/ui/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- evalkit/bundled/ui/assets/abap-08VXUWAP.js +1 -0
- evalkit/bundled/ui/assets/apex-BWPQTe0t.js +1 -0
- evalkit/bundled/ui/assets/azcli-Bc_sGQ0U.js +1 -0
- evalkit/bundled/ui/assets/bat-i0X4ZdIN.js +1 -0
- evalkit/bundled/ui/assets/bicep-B5-_aFwp.js +2 -0
- evalkit/bundled/ui/assets/cameligo-DMUM7wLl.js +1 -0
- evalkit/bundled/ui/assets/clojure-Cm7r79vr.js +1 -0
- evalkit/bundled/ui/assets/codicon-DF1abBS2.ttf +0 -0
- evalkit/bundled/ui/assets/coffee-Ba7i2nA0.js +1 -0
- evalkit/bundled/ui/assets/cpp-C7h46wYY.js +1 -0
- evalkit/bundled/ui/assets/csharp-BKxtCVv1.js +1 -0
- evalkit/bundled/ui/assets/csp-bTuwJoIa.js +1 -0
- evalkit/bundled/ui/assets/css-DIMkf-bt.js +3 -0
- evalkit/bundled/ui/assets/css.worker-DwfUZ3fB.js +96 -0
- evalkit/bundled/ui/assets/cssMode-C97l1pbB.js +1 -0
- evalkit/bundled/ui/assets/cypher-CVaqCwHa.js +1 -0
- evalkit/bundled/ui/assets/dart-onAF5SnQ.js +1 -0
- evalkit/bundled/ui/assets/dockerfile-DZFCIeNp.js +1 -0
- evalkit/bundled/ui/assets/ecl-94qehhXe.js +1 -0
- evalkit/bundled/ui/assets/editor-DjpsE8to.css +1 -0
- evalkit/bundled/ui/assets/editor.api-NTesIxw5.js +908 -0
- evalkit/bundled/ui/assets/editor.worker-CRz__AKW.js +33 -0
- evalkit/bundled/ui/assets/elixir-6RTg0lbw.js +1 -0
- evalkit/bundled/ui/assets/flow9-C5_-GSwl.js +1 -0
- evalkit/bundled/ui/assets/freemarker2-BWqEFagp.js +3 -0
- evalkit/bundled/ui/assets/fsharp-C8Ef5oNN.js +1 -0
- evalkit/bundled/ui/assets/go-C-y9NEjX.js +1 -0
- evalkit/bundled/ui/assets/graphql-fmXr3nnJ.js +1 -0
- evalkit/bundled/ui/assets/handlebars-DkIF-whN.js +1 -0
- evalkit/bundled/ui/assets/hcl-CpzslTdj.js +1 -0
- evalkit/bundled/ui/assets/html-C_rpeQXJ.js +1 -0
- evalkit/bundled/ui/assets/html.worker-D9ugpX4y.js +509 -0
- evalkit/bundled/ui/assets/htmlMode-B0YIq3DF.js +1 -0
- evalkit/bundled/ui/assets/index-Cw-jBH6M.js +736 -0
- evalkit/bundled/ui/assets/index-DKtoQZtm.css +1 -0
- evalkit/bundled/ui/assets/ini-sBoK_t0W.js +1 -0
- evalkit/bundled/ui/assets/java-BEtHBSE6.js +1 -0
- evalkit/bundled/ui/assets/javascript-D4EGhYA6.js +1 -0
- evalkit/bundled/ui/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- evalkit/bundled/ui/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- evalkit/bundled/ui/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- evalkit/bundled/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- evalkit/bundled/ui/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- evalkit/bundled/ui/assets/json.worker-CV9fqkUp.js +65 -0
- evalkit/bundled/ui/assets/jsonMode-pQjSfIH6.js +7 -0
- evalkit/bundled/ui/assets/julia-Bri6UV-V.js +1 -0
- evalkit/bundled/ui/assets/kotlin-BOotOW0E.js +1 -0
- evalkit/bundled/ui/assets/less-B9JPFI3C.js +2 -0
- evalkit/bundled/ui/assets/lexon-CfSJPG6W.js +1 -0
- evalkit/bundled/ui/assets/liquid-DbrvoYjD.js +1 -0
- evalkit/bundled/ui/assets/lspLanguageFeatures-D0B7cH6y.js +4 -0
- evalkit/bundled/ui/assets/lua-CsQS60Ue.js +1 -0
- evalkit/bundled/ui/assets/m3-D-oSqn_W.js +1 -0
- evalkit/bundled/ui/assets/markdown-Cimd5fb3.js +1 -0
- evalkit/bundled/ui/assets/mdx-B0HrujLR.js +1 -0
- evalkit/bundled/ui/assets/mips-CIPQ_RoX.js +1 -0
- evalkit/bundled/ui/assets/monacoEditor-DsoPncxW.js +68 -0
- evalkit/bundled/ui/assets/monacoEditor-n7clI0si.css +1 -0
- evalkit/bundled/ui/assets/msdax-DauUninz.js +1 -0
- evalkit/bundled/ui/assets/mysql-SOo6toE5.js +1 -0
- evalkit/bundled/ui/assets/objective-c-FvmIjYaQ.js +1 -0
- evalkit/bundled/ui/assets/pascal-DrH0SRf2.js +1 -0
- evalkit/bundled/ui/assets/pascaligo-D-ptJ9y-.js +1 -0
- evalkit/bundled/ui/assets/perl-oz_6vUea.js +1 -0
- evalkit/bundled/ui/assets/pgsql-DTj74zXo.js +1 -0
- evalkit/bundled/ui/assets/php-nr791fC2.js +1 -0
- evalkit/bundled/ui/assets/pla-CopQ2nXW.js +1 -0
- evalkit/bundled/ui/assets/postiats-43DmfD33.js +1 -0
- evalkit/bundled/ui/assets/powerquery-D3hlyOfw.js +1 -0
- evalkit/bundled/ui/assets/powershell-DmHpPYUd.js +1 -0
- evalkit/bundled/ui/assets/protobuf-C531GsRP.js +2 -0
- evalkit/bundled/ui/assets/pug-Z5eAx3Zn.js +1 -0
- evalkit/bundled/ui/assets/python-CieHVM9n.js +1 -0
- evalkit/bundled/ui/assets/qsharp-DkqhCAOL.js +1 -0
- evalkit/bundled/ui/assets/r-BwWrilGY.js +1 -0
- evalkit/bundled/ui/assets/razor-sLewSMyp.js +1 -0
- evalkit/bundled/ui/assets/redis-ClamHrr6.js +1 -0
- evalkit/bundled/ui/assets/redshift-DT7zqm-g.js +1 -0
- evalkit/bundled/ui/assets/restructuredtext-BYgofb2h.js +1 -0
- evalkit/bundled/ui/assets/ruby-DezsRK8O.js +1 -0
- evalkit/bundled/ui/assets/rust-DdL9SqIa.js +1 -0
- evalkit/bundled/ui/assets/sb-CcwsVR0C.js +1 -0
- evalkit/bundled/ui/assets/scala-DHpiXF5c.js +1 -0
- evalkit/bundled/ui/assets/scheme-BeGwcela.js +1 -0
- evalkit/bundled/ui/assets/scss-gp-XZpBa.js +3 -0
- evalkit/bundled/ui/assets/shell-CC2rA5mh.js +1 -0
- evalkit/bundled/ui/assets/solidity-BEEn4gHE.js +1 -0
- evalkit/bundled/ui/assets/sophia-CRfGWb83.js +1 -0
- evalkit/bundled/ui/assets/sparql-D_Lu-MrJ.js +1 -0
- evalkit/bundled/ui/assets/sql-NEE52Syq.js +1 -0
- evalkit/bundled/ui/assets/st-DbInun42.js +1 -0
- evalkit/bundled/ui/assets/swift-Bxkupp3x.js +1 -0
- evalkit/bundled/ui/assets/systemverilog-Bz4Y3fRF.js +1 -0
- evalkit/bundled/ui/assets/tcl-DISqw1ZD.js +1 -0
- evalkit/bundled/ui/assets/ts.worker-DIAQkoB3.js +67741 -0
- evalkit/bundled/ui/assets/tsMode-BcVQ1nu0.js +11 -0
- evalkit/bundled/ui/assets/twig-De2hgUGE.js +1 -0
- evalkit/bundled/ui/assets/typescript-CUvNWd9p.js +1 -0
- evalkit/bundled/ui/assets/typespec-B8J7ngcE.js +1 -0
- evalkit/bundled/ui/assets/vb-DV3o63ZY.js +1 -0
- evalkit/bundled/ui/assets/wgsl-DpFanUEy.js +298 -0
- evalkit/bundled/ui/assets/workers-CwpYQtzp.js +1 -0
- evalkit/bundled/ui/assets/xml-C1HnXMdF.js +1 -0
- evalkit/bundled/ui/assets/yaml-D7Ey3HQu.js +1 -0
- evalkit/bundled/ui/favicon.svg +6 -0
- evalkit/bundled/ui/index.html +14 -0
- evalkit/cli/__init__.py +0 -0
- evalkit/cli/admin_commands.py +590 -0
- evalkit/cli/client.py +67 -0
- evalkit/cli/init_server.py +165 -0
- evalkit/cli/local_run.py +195 -0
- evalkit/cli/main.py +1365 -0
- evalkit/cli/runs_commands.py +539 -0
- evalkit/cli/server_commands.py +130 -0
- evalkit/cli/skill_targets.py +43 -0
- evalkit/cli/tokens_commands.py +52 -0
- evalkit/cli/traces_commands.py +332 -0
- evalkit/cli/update.py +85 -0
- evalkit/client/__init__.py +0 -0
- evalkit/client/agents.py +25 -0
- evalkit/client/api.py +193 -0
- evalkit/client/blob.py +104 -0
- evalkit/client/connection.py +88 -0
- evalkit/client/evaluators.py +11 -0
- evalkit/client/sessions.py +17 -0
- evalkit/client/store.py +139 -0
- evalkit/client/summary.py +46 -0
- evalkit/client/sync.py +198 -0
- evalkit/config.py +227 -0
- evalkit/contracts/__init__.py +0 -0
- evalkit/contracts/atif.py +115 -0
- evalkit/contracts/cases.py +456 -0
- evalkit/contracts/custom_evaluator.py +58 -0
- evalkit/contracts/enums.py +86 -0
- evalkit/contracts/esf.py +120 -0
- evalkit/contracts/harness.py +281 -0
- evalkit/contracts/notes.json +4 -0
- evalkit/contracts/notes.py +7 -0
- evalkit/contracts/settings.py +41 -0
- evalkit/core/__init__.py +0 -0
- evalkit/core/access.py +75 -0
- evalkit/core/agents.py +65 -0
- evalkit/core/blob.py +46 -0
- evalkit/core/capabilities.py +36 -0
- evalkit/core/costmap.py +90 -0
- evalkit/core/custom_eval.py +50 -0
- evalkit/core/data/cost_map.json +81546 -0
- evalkit/core/endpoints.py +31 -0
- evalkit/core/evaluators/__init__.py +29 -0
- evalkit/core/evaluators/base.py +121 -0
- evalkit/core/evaluators/gauges.py +84 -0
- evalkit/core/evaluators/presentation.py +166 -0
- evalkit/core/evaluators/response_time.py +21 -0
- evalkit/core/evaluators/rubrics.py +494 -0
- evalkit/core/evaluators/tool_trajectory.py +187 -0
- evalkit/core/evaluators/trajectory_rubrics.py +198 -0
- evalkit/core/fixtures.py +57 -0
- evalkit/core/harness.py +227 -0
- evalkit/core/harness_check.py +191 -0
- evalkit/core/importer.py +257 -0
- evalkit/core/judge.py +78 -0
- evalkit/core/lint.py +265 -0
- evalkit/core/overlays.py +76 -0
- evalkit/core/paths.py +25 -0
- evalkit/core/promotion.py +94 -0
- evalkit/core/pull.py +198 -0
- evalkit/core/python_eval.py +59 -0
- evalkit/core/remote_evaluators.py +32 -0
- evalkit/core/review.py +220 -0
- evalkit/core/run_digest.py +421 -0
- evalkit/core/runner.py +995 -0
- evalkit/core/scorecard.py +255 -0
- evalkit/core/traces/__init__.py +0 -0
- evalkit/core/traces/convert.py +336 -0
- evalkit/core/traces/importer.py +113 -0
- evalkit/core/traces/mapping.py +385 -0
- evalkit/core/traces/poll.py +38 -0
- evalkit/core/traces/raw.py +21 -0
- evalkit/core/traces/sessions.py +172 -0
- evalkit/core/traces/settle.py +14 -0
- evalkit/core/traces/sources/__init__.py +19 -0
- evalkit/core/traces/sources/base.py +25 -0
- evalkit/core/traces/sources/phoenix.py +121 -0
- evalkit/core/trajectory.py +248 -0
- evalkit/core/workspace.py +30 -0
- evalkit/credentials.py +119 -0
- evalkit/db/__init__.py +0 -0
- evalkit/db/agents.py +289 -0
- evalkit/db/alembic/env.py +90 -0
- evalkit/db/alembic/script.py.mako +28 -0
- evalkit/db/alembic/versions/0011_baseline.py +1002 -0
- evalkit/db/alembic/versions/0012_ticket_token_kind.py +27 -0
- evalkit/db/alembic/versions/0013_keys_and_llm_providers.py +67 -0
- evalkit/db/cases.py +608 -0
- evalkit/db/crypto.py +12 -0
- evalkit/db/evaluators.py +156 -0
- evalkit/db/experiments.py +363 -0
- evalkit/db/fixture_blobs.py +91 -0
- evalkit/db/keys.py +78 -0
- evalkit/db/llm_providers.py +176 -0
- evalkit/db/locks.py +6 -0
- evalkit/db/mappings.py +168 -0
- evalkit/db/models.py +567 -0
- evalkit/db/promotion.py +271 -0
- evalkit/db/rekey.py +46 -0
- evalkit/db/review.py +250 -0
- evalkit/db/review_state.py +50 -0
- evalkit/db/runs.py +533 -0
- evalkit/db/scorecard.py +300 -0
- evalkit/db/session.py +71 -0
- evalkit/db/sessions.py +90 -0
- evalkit/db/spans.py +360 -0
- evalkit/db/store.py +209 -0
- evalkit/db/tokens.py +100 -0
- evalkit/db/trace_imports.py +308 -0
- evalkit/db/trace_sources.py +131 -0
- evalkit/db/users.py +186 -0
- evalkit/db/workspaces.py +232 -0
- evalkit/paths.py +33 -0
- evalkit/sdk/__init__.py +29 -0
- evalkit/sdk/binding.py +69 -0
- evalkit/sdk/evaluators.py +56 -0
- evalkit/sdk/runner.py +957 -0
- evalkit/sdk/tracing.py +166 -0
- evalkit/store/__init__.py +0 -0
- evalkit/store/base.py +354 -0
- evalkit/store/blob.py +69 -0
- evalkit/version.py +44 -0
- evalkit_py-0.2.0.dev12.dist-info/METADATA +205 -0
- evalkit_py-0.2.0.dev12.dist-info/RECORD +371 -0
- evalkit_py-0.2.0.dev12.dist-info/WHEEL +4 -0
- evalkit_py-0.2.0.dev12.dist-info/entry_points.txt +2 -0
- evalkit_py-0.2.0.dev12.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: eval-driven-development
|
|
3
|
+
description: Drives eval-driven development (EDD) against an evalkit deployment in two loops. Improve the agent — run a dataset, pull the runs, diagnose each failure, synthesize file-cited fixes, apply and re-run until green. Mine cases — pull a batch of an agent's app runs (production, staging or manual traffic), analyze each, cluster the failure patterns and author new eval cases for review. Use whenever working with agent or LLM evals — running a dataset, turning a failing experiment into fixes, capturing an app-run issue as a regression guard, building a capability cases-first, or generating cases from real traffic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Eval-Driven Development
|
|
7
|
+
|
|
8
|
+
Two loops share one toolbox. **Loop 1 — Improve the agent** runs cases and
|
|
9
|
+
turns failures into file-cited fixes until nothing scores below threshold.
|
|
10
|
+
**Loop 2 — Mine cases** reads a batch of the agent's app runs and turns the
|
|
11
|
+
failure patterns it finds into new cases for review. Pick one loop first (see
|
|
12
|
+
"Pick a loop") and stay on it; the two meet only at the handoffs in "Where
|
|
13
|
+
the loops meet".
|
|
14
|
+
|
|
15
|
+
All eval operations go through the `evalkit` CLI. Discover exact command
|
|
16
|
+
shapes with `evalkit --help` (and `--help` on any subcommand) instead of
|
|
17
|
+
guessing. Loop 1 leans on `sync`, `run`, `runs pull --experiment` and
|
|
18
|
+
`summary`; Loop 2 on `runs list`, `runs pull`, `lint`, `sync` and
|
|
19
|
+
`review request`.
|
|
20
|
+
|
|
21
|
+
## Terms
|
|
22
|
+
|
|
23
|
+
| Term | Meaning |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Loop 1 — Improve the agent | Run cases, diagnose failures, fix the agent's code, prompts, tools or data. Output: a scorecard and agent changes. |
|
|
26
|
+
| Loop 2 — Mine cases | Pull app runs, analyze each, cluster failure patterns, author cases. Output: cases sent to review. |
|
|
27
|
+
| App run | A run of the agent outside any experiment: production, staging or by hand. |
|
|
28
|
+
| Experiment | One run of one dataset (or a case subset) against one agent. Referenced by id or name. |
|
|
29
|
+
| Run | One case executed once against the agent, in a fresh session. |
|
|
30
|
+
| Case | One eval question: input, expected behaviour, evaluator config. A YAML document. |
|
|
31
|
+
| Surface | The place a fix lands: a skill, a tool description, a prompt, or a data source. |
|
|
32
|
+
| Working set | The failing case ids plus sibling cases that exercise the same surfaces; what Step 6 re-runs. |
|
|
33
|
+
| Run directory | One run pulled by `evalkit runs pull` — `runs/<run_id>/` with `run.json`, `trajectory.json`, `case.json`, `evaluations.json`; `files.json` and `files/` only after `evalkit runs files`. |
|
|
34
|
+
| Finding | The one JSON diagnosis Step 4 produces per failing case. |
|
|
35
|
+
| Proposal group | One set of related fixes in `proposals.md`; Step 6 applies one group per iteration. |
|
|
36
|
+
| Overlay | A client extension of a case by id, attaching custom-evaluator config or the built-in tool checks for the agents it names. |
|
|
37
|
+
| Blackbox / whitebox | Blackbox: what any observer could see — the portable case. Whitebox: harness-specific checks — the overlay. |
|
|
38
|
+
| Coverage gap | A Loop 1 finding that says no case covers a scenario, or that the case itself is wrong. |
|
|
39
|
+
| Observation | The one JSON a Loop 2 analysis writes per app run. |
|
|
40
|
+
| Pattern | A group of observations that share a failure; the unit of the case plan. |
|
|
41
|
+
| Case plan | `case-plan.md`, Loop 2's ranked list of patterns with proposed cases. |
|
|
42
|
+
| EDD-infra note | A one-line nudge from diagnose/synthesize about a gap in the eval setup itself. |
|
|
43
|
+
|
|
44
|
+
## Case levels
|
|
45
|
+
|
|
46
|
+
Every case is layered:
|
|
47
|
+
|
|
48
|
+
- **Blackbox case** — asserts only what any observer could see: the answer and
|
|
49
|
+
the trajectory in natural language (`answer_rubrics`, `trajectory_rubrics`,
|
|
50
|
+
`presentation_judge`, `max_response_time`). No tool/skill vocabulary —
|
|
51
|
+
portable across harnesses. Authoring doctrine lives in the
|
|
52
|
+
`authoring-eval-cases` skill.
|
|
53
|
+
- **Whitebox enrichment** — additive harness-specific assertions, attached as
|
|
54
|
+
an **overlay** on the case and scored by evalkit's built-in tool checks
|
|
55
|
+
(`tool_trajectory_match`, `required_tools_called`) or the client's own
|
|
56
|
+
Custom Evaluator API endpoints. A case in the client's own
|
|
57
|
+
harness-specific dataset may carry the built-in tool checks directly
|
|
58
|
+
instead (see the authoring skill's
|
|
59
|
+
[`references/tool-checks.md`](../authoring-eval-cases/references/tool-checks.md)).
|
|
60
|
+
Enrichment never edits blackbox evaluators; stripping the
|
|
61
|
+
overlay leaves a portable case. See the authoring skill's
|
|
62
|
+
[`references/overlays.md`](../authoring-eval-cases/references/overlays.md).
|
|
63
|
+
|
|
64
|
+
## Pick a loop
|
|
65
|
+
|
|
66
|
+
| Developer gives | Wants back | Loop |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| A dataset to run, an experiment id or name, an app-run issue, a new capability | A scorecard, or agent changes | 1 |
|
|
69
|
+
| An agent and a time window ("look at last week's traffic", "what are users hitting?") | New cases | 2 |
|
|
70
|
+
|
|
71
|
+
If a request fits neither row, ask which output they want. Once a loop is
|
|
72
|
+
picked, follow only its steps. Loop 2's steps are named M1–M5 so they never
|
|
73
|
+
mix with Loop 1's Steps 1–6.
|
|
74
|
+
|
|
75
|
+
## Runs are history
|
|
76
|
+
|
|
77
|
+
This applies to both loops. Every pulled run shows the agent as it was when
|
|
78
|
+
the run happened (`run.json` `started_at`, `index.json` `created_at`), not as
|
|
79
|
+
the code is now. Prompts,
|
|
80
|
+
skills, tools and data may have changed since, so a failure in a run may
|
|
81
|
+
already be fixed. Before diagnosing or proposing a fix, check the git history
|
|
82
|
+
of the agent repo for changes made after the run:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
git log --since=<run started_at> --oneline -- <paths of the surfaces involved>
|
|
86
|
+
git log --since=<run started_at> --oneline -S '<tool or prompt text from the trajectory>'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`--since` compares commit dates, which a rebase or squash merge resets, so
|
|
90
|
+
treat it as a first pass: also read the last few commits that touch the
|
|
91
|
+
surface (`git log -n 10 -- <path>`) whatever their date. Read any commit that
|
|
92
|
+
touches the failing surface. If it already addresses the failure:
|
|
93
|
+
|
|
94
|
+
- **Loop 1** — the finding says so (`already_addressed`) instead of proposing
|
|
95
|
+
the same fix again; re-run the case to confirm the fix rather than editing
|
|
96
|
+
code. Diagnose against the code at `HEAD`, and cite what changed since the
|
|
97
|
+
run.
|
|
98
|
+
- **Loop 2** — the observation says so (`fixed_since`). Still author cases for
|
|
99
|
+
the pattern: they guard the fix against regressions. The case plan marks
|
|
100
|
+
them "expected green" with the commit, so nobody reads them as open
|
|
101
|
+
failures.
|
|
102
|
+
|
|
103
|
+
## Loop 1 — Improve the agent
|
|
104
|
+
|
|
105
|
+
**Output is a scorecard and agent changes. New cases come only from Step 1 or
|
|
106
|
+
from the coverage-gap handoff; never edit cases to make a run pass.**
|
|
107
|
+
|
|
108
|
+
Four entry points, one shared loop. Infer the entry point from what the
|
|
109
|
+
developer gave you: a dataset to run → D; an experiment id or name → A; a
|
|
110
|
+
described app-run issue → B; a feature/behaviour intent → C.
|
|
111
|
+
|
|
112
|
+
One flag: `--apply` in the invocation runs the autonomous apply → re-run loop
|
|
113
|
+
(Step 6). Without it, stop after the proposal for the human to act.
|
|
114
|
+
|
|
115
|
+
```mermaid
|
|
116
|
+
stateDiagram-v2
|
|
117
|
+
author: Step 1 — author case(s)
|
|
118
|
+
sync_run: Step 2 — evalkit lint + sync + run
|
|
119
|
+
pull: Step 3 — pull runs, pick failures
|
|
120
|
+
diagnose: Step 4 — diagnose each failure
|
|
121
|
+
synthesize: Step 5 — synthesize grouped proposal
|
|
122
|
+
apply: Step 6 — apply one group
|
|
123
|
+
state check <<choice>>
|
|
124
|
+
|
|
125
|
+
[*] --> pull: A · experiment id/name given
|
|
126
|
+
[*] --> sync_run: D · run a dataset
|
|
127
|
+
[*] --> author: B · app-run issue / C · new or changed capability
|
|
128
|
+
|
|
129
|
+
author --> sync_run
|
|
130
|
+
sync_run --> [*]: D · summary, stop
|
|
131
|
+
sync_run --> pull
|
|
132
|
+
pull --> check
|
|
133
|
+
check --> [*]: green, or cap reached → human review
|
|
134
|
+
check --> diagnose: failures, no proposal yet
|
|
135
|
+
check --> apply: still red, proposal ready, iterations left
|
|
136
|
+
diagnose --> synthesize
|
|
137
|
+
synthesize --> [*]: without --apply → human review
|
|
138
|
+
synthesize --> apply: with --apply
|
|
139
|
+
apply --> sync_run: re-run full working set
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- **A — fix a failing experiment (regression).** An experiment already ran;
|
|
143
|
+
the developer names it (`runs pull --experiment` takes its numeric id). →
|
|
144
|
+
start at Step 3.
|
|
145
|
+
- **B — capture an app-run issue as a regression guard.** An app run (one
|
|
146
|
+
outside any experiment: production, staging or by hand) misbehaved. →
|
|
147
|
+
Step 1: author a case (from the run *and* the developer's input) asserting the correct behaviour, then run and loop. The case stays in
|
|
148
|
+
the suite afterwards as a permanent guard. If the developer points at a
|
|
149
|
+
run/session id, pull it with `evalkit runs pull <agent> --run-id <id>` and
|
|
150
|
+
read its `trajectory.json` before authoring.
|
|
151
|
+
- **C — build or change a capability, cases-first.** New or changed behaviour,
|
|
152
|
+
code not written yet. → Step 1: author cases for the desired behaviour;
|
|
153
|
+
expect the first run to be red.
|
|
154
|
+
- **D — run a dataset.** The developer wants to know how the agent does on a
|
|
155
|
+
dataset (or part of one). → Step 2: `evalkit run`, then `evalkit summary
|
|
156
|
+
<experiment-id>`, and stop there. Continue at Step 3 only if they ask for the
|
|
157
|
+
failures to be fixed.
|
|
158
|
+
|
|
159
|
+
### Step 1 — author / select cases (B and C)
|
|
160
|
+
|
|
161
|
+
Use the `authoring-eval-cases` skill. Ground every case in the material at
|
|
162
|
+
hand — the request in this conversation, any app run or links shared, files
|
|
163
|
+
already open — and ask the developer to fill any gap (the exact input, the
|
|
164
|
+
correct output) rather than guessing. The case asserts the **ideal
|
|
165
|
+
behaviour** — a time-anchored input and specific expected values — never the
|
|
166
|
+
current broken behaviour: don't write rubrics that merely guard against the
|
|
167
|
+
failure you just saw, or the case overfits to today's bug instead of stating
|
|
168
|
+
what correct output looks like for this input and every sibling like it.
|
|
169
|
+
|
|
170
|
+
### Step 2 — lint, sync, run (B, C and D)
|
|
171
|
+
|
|
172
|
+
After authoring or editing any case YAML — in any entry point — run
|
|
173
|
+
`evalkit lint <file> --dataset <slug>` first; errors block sync. Then
|
|
174
|
+
`evalkit run <dataset> --agent <agent>`: with an `evalkit.yaml` in the repo
|
|
175
|
+
this syncs the dataset directory to your workspace and runs your local agent
|
|
176
|
+
from this machine. For a tight loop, run only the relevant cases
|
|
177
|
+
(`evalkit run <dataset>/<file>.yaml`, `evalkit run <dataset>/<subfolder>`, or
|
|
178
|
+
`--case-id`, repeatable) rather than the whole dataset.
|
|
179
|
+
|
|
180
|
+
`evalkit run` executes every selected case, in personal and shared datasets
|
|
181
|
+
alike; review state never filters a run.
|
|
182
|
+
When you are confident the case is correct and it has reached a shared
|
|
183
|
+
dataset, ask for review:
|
|
184
|
+
`evalkit review request <dataset>@dev --case-id <id> --reviewer <user>`. If `dev` is
|
|
185
|
+
linked to a promotion target such as `prod`, the reviewer's approval also puts
|
|
186
|
+
the case into `<dataset>@prod`, approved; nothing else is needed to release
|
|
187
|
+
it. Whether the
|
|
188
|
+
agent passes the case has no bearing on review; a red case that asserts the
|
|
189
|
+
right behaviour is exactly what a reviewer should approve.
|
|
190
|
+
|
|
191
|
+
`run` executes two phases: agent runs, then evaluators. If a run crashes or is
|
|
192
|
+
killed before evaluation, don't re-run the cases — `evalkit evaluate
|
|
193
|
+
<experiment-id>` scores the runs that already persisted, and `evalkit run
|
|
194
|
+
--resume <experiment-id>` finishes a partially-run experiment.
|
|
195
|
+
|
|
196
|
+
### Step 3 — pull runs and pick the failures
|
|
197
|
+
|
|
198
|
+
`evalkit runs pull --experiment <experiment-id>` downloads every run of the
|
|
199
|
+
experiment to `evalkit-runs/experiment-<id>/` (keep that directory out of
|
|
200
|
+
git): `index.json` and one `runs/<run_id>/` per run with `run.json` (status,
|
|
201
|
+
answer, metrics), `trajectory.json` (ATIF), `case.json` (the case version the
|
|
202
|
+
run answered) and `evaluations.json` (every evaluator's score and explanation).
|
|
203
|
+
|
|
204
|
+
The pull does not fetch files: not the run's workspace files (deliverables)
|
|
205
|
+
and not the full outputs of tool results the harness shortened (the
|
|
206
|
+
trajectory keeps the shortened one). Fetch them only for the failures you
|
|
207
|
+
diagnose, and only when the trajectory is not enough:
|
|
208
|
+
`evalkit runs files <dir> <run_id>` prints the run's file tree (also written
|
|
209
|
+
to `runs/<run_id>/files.json`); then
|
|
210
|
+
`evalkit runs files <dir> <run_id> --path <file or folder>` fetches just those
|
|
211
|
+
into `runs/<run_id>/files/<path>`. A tool result's `extra.full_output_path` is
|
|
212
|
+
such a path, even when the tree does not list it. The first file that fails
|
|
213
|
+
stops the command and names it; rerun with the remaining paths if you still
|
|
214
|
+
need them. Never fetch a whole heavy workspace when one file answers the
|
|
215
|
+
question.
|
|
216
|
+
|
|
217
|
+
Pick the failures yourself from `index.json` `runs`: a run fails when its
|
|
218
|
+
`status` is not `completed` or any value in `scores` is below 0.8 (use another
|
|
219
|
+
threshold if the developer asked, and only their evaluator if they named one).
|
|
220
|
+
A row with `pull_error` set could not be fetched in full (its run directory
|
|
221
|
+
has no `trajectory.json`); pull it again into the same directory with
|
|
222
|
+
`evalkit runs pull <index.json agent> --run-id <run_id> --out <same dir>`, and
|
|
223
|
+
if it still fails, list it for the developer instead of diagnosing it. If
|
|
224
|
+
`index.json` has a `note`, tell the developer (for example, the harness scan
|
|
225
|
+
stopped early).
|
|
226
|
+
If none fail, report "no failures below threshold" and STOP (for B/C, an empty
|
|
227
|
+
failure set on the first run means the capability already works — confirm and
|
|
228
|
+
stop). Diagnose failures only; the passing runs are there for profiling.
|
|
229
|
+
|
|
230
|
+
### Step 4 — diagnose (fan-out, capped at 5 concurrent)
|
|
231
|
+
|
|
232
|
+
For each failing case, run the instructions in
|
|
233
|
+
[`references/diagnose.md`](references/diagnose.md) against its failing run
|
|
234
|
+
directories. On agents with subagent support, dispatch each diagnosis as a
|
|
235
|
+
subagent, batched 5 at a time (one message with 5 parallel dispatches, wait,
|
|
236
|
+
then the next batch); otherwise run them inline, sequentially. Each diagnosis
|
|
237
|
+
produces a single JSON finding — write each one to
|
|
238
|
+
`<review-dir>/findings/<case_id>.json` (create `findings/` first).
|
|
239
|
+
|
|
240
|
+
Trajectory efficiency is in scope for every diagnosis, not just wrong output:
|
|
241
|
+
errored, retried, or redundant tool calls and wrong-first-call discovery
|
|
242
|
+
overhead are diagnosable defects in their own right. Don't let a
|
|
243
|
+
plausibly-correct final answer mask a wasteful trajectory.
|
|
244
|
+
|
|
245
|
+
### Step 5 — synthesize (once)
|
|
246
|
+
|
|
247
|
+
Run the instructions in [`references/synthesize.md`](references/synthesize.md)
|
|
248
|
+
once (as a subagent where supported), passing: the `findings/` dir, the
|
|
249
|
+
`index.json` path, and the proposal output path `<review-dir>/proposals.md`.
|
|
250
|
+
It writes the proposal. Print the proposal path and a one-line summary
|
|
251
|
+
(`<N> failures diagnosed, proposal at <path>`).
|
|
252
|
+
|
|
253
|
+
If not `--apply`, STOP here for human review.
|
|
254
|
+
|
|
255
|
+
### Interpreting Loop 1 outputs
|
|
256
|
+
|
|
257
|
+
Findings and the proposal carry flags addressed to you, not just to the
|
|
258
|
+
proposal's reader. Handle each explicitly instead of skimming past them:
|
|
259
|
+
|
|
260
|
+
- **`unverified` proposal groups** — the synthesizer could not confirm the
|
|
261
|
+
change against real code, or concluded the case itself may be wrong. Never
|
|
262
|
+
apply one autonomously in Step 6; carry it to the developer with the stated
|
|
263
|
+
reason.
|
|
264
|
+
- **Possibly-wrong case** — when the proposal says the expected answer is not
|
|
265
|
+
derivable from the data or domain (a `wrong_case` coverage gap), the fix is
|
|
266
|
+
a dataset fix. Escalate to the developer; do not bake the expected answer
|
|
267
|
+
into any prompt surface.
|
|
268
|
+
- **`verdict: borderline` findings** — near-threshold, not clearly broken.
|
|
269
|
+
Deprioritize below `failed` findings; mention them in the exit summary
|
|
270
|
+
rather than spending iterations on them.
|
|
271
|
+
- **`already_addressed` findings** — a commit after the run already changed
|
|
272
|
+
the failing surface. Don't apply anything for them; re-run those cases first
|
|
273
|
+
and only diagnose again if they still fail.
|
|
274
|
+
- **Case proposals (coverage gaps)** — `proposals.md` lists them apart from
|
|
275
|
+
the fix groups. Never apply them in Step 6. Offer them to the developer at
|
|
276
|
+
the end; accepted ones go through Loop 2's M5 (author, lint, sync, request
|
|
277
|
+
review). See "Where the loops meet".
|
|
278
|
+
- **`root_cause: unknown` or low `confidence`** — don't force these into a fix
|
|
279
|
+
group. List them for the developer with whatever evidence the finding has.
|
|
280
|
+
- **`EDD-infra note:` lines** — diagnose and synthesize may append one when
|
|
281
|
+
the eval setup itself has a gap. Collect every note and relay them in the
|
|
282
|
+
final summary (see Self-feedback); they are never a reason to edit evalkit
|
|
283
|
+
or the pulled runs yourself mid-loop.
|
|
284
|
+
|
|
285
|
+
### Step 6 — apply & re-run (only with `--apply`)
|
|
286
|
+
|
|
287
|
+
The autonomous inner loop, capped at 3 iterations (a global cap on total
|
|
288
|
+
iterations across all groups; the developer can raise it in the request). Each iteration applies a single
|
|
289
|
+
proposal group, then re-runs the whole working set and pulls it again. One group
|
|
290
|
+
per iteration keeps each change attributable; re-running the full working set
|
|
291
|
+
catches a fix that regresses a sibling.
|
|
292
|
+
|
|
293
|
+
Copy this checklist and track progress:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
EDD loop:
|
|
297
|
+
- [ ] Build the working set (failing ids ∪ cases touching the same surfaces)
|
|
298
|
+
- [ ] Iteration 1: apply highest-leverage group → run full working set → re-pull
|
|
299
|
+
- [ ] Iteration 2 (if still red): apply next group / refine → run full set → re-pull
|
|
300
|
+
- [ ] Iteration 3 (if still red): apply next group / refine → run full set → re-pull
|
|
301
|
+
- [ ] Summarize (green, or what is still red + groups not reached at the cap) → hand to human
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Build the working set (once, before the loop):** seed = the failing
|
|
305
|
+
`case_id`s you picked from `index.json`; widen with sibling cases that exercise the same
|
|
306
|
+
surfaces the proposal touches (search the case YAML for related scenarios).
|
|
307
|
+
|
|
308
|
+
**Each iteration:**
|
|
309
|
+
|
|
310
|
+
1. Apply the chosen proposal group — edit the cited file at the surface the
|
|
311
|
+
proposal names. Create a brand-new surface only when the developer asked
|
|
312
|
+
for one or the proposal shows no existing surface can host the capability.
|
|
313
|
+
Any change to a prompt surface follows the prompt-change guidelines inside
|
|
314
|
+
[`references/synthesize.md`](references/synthesize.md): describe the
|
|
315
|
+
mechanism first, escalate to rule-style wording only when a re-run shows
|
|
316
|
+
the behaviour persisted, prefer deterministic guards, no eval awareness.
|
|
317
|
+
2. `evalkit run <dataset> --agent <agent> --case-id <id> [--case-id …]`
|
|
318
|
+
over the working set (the run syncs your edits first).
|
|
319
|
+
3. `evalkit runs pull --experiment <id>` for that experiment and pick the
|
|
320
|
+
failures from the new `index.json`.
|
|
321
|
+
4. Stop when no failure scores below threshold (**green**) or when the
|
|
322
|
+
iteration cap is reached.
|
|
323
|
+
|
|
324
|
+
**On exit:** summarize what changed, what is green, and — if the cap was hit —
|
|
325
|
+
what is still red. List the case proposals, if any. Hand to the human; do not
|
|
326
|
+
keep looping.
|
|
327
|
+
|
|
328
|
+
## Loop 2 — Mine cases from app runs
|
|
329
|
+
|
|
330
|
+
**Output is cases sent to review. Never edit the agent in this loop; to fix
|
|
331
|
+
the agent for the new cases, hand off to Loop 1 (see "Where the loops
|
|
332
|
+
meet").**
|
|
333
|
+
|
|
334
|
+
```mermaid
|
|
335
|
+
stateDiagram-v2
|
|
336
|
+
m1: M1 — get app runs locally
|
|
337
|
+
m2: M2 — choose the window, pull every run
|
|
338
|
+
m3: M3 — analyze each run
|
|
339
|
+
m4: M4 — synthesize the case plan
|
|
340
|
+
m5: M5 — author, lint, sync, request review
|
|
341
|
+
[*] --> m1
|
|
342
|
+
m1 --> m2
|
|
343
|
+
m2 --> m3
|
|
344
|
+
m3 --> m4
|
|
345
|
+
m4 --> [*]: developer reviews case-plan.md
|
|
346
|
+
[*] --> m5: developer picks patterns
|
|
347
|
+
m5 --> [*]: cases in review (optionally → Loop 1 C)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Work in one directory for the whole batch, `<dir>` (default
|
|
351
|
+
`evalkit-runs/<agent>/<YYYYMMDD-HHMMSS>/`, kept out of git): the pulled runs,
|
|
352
|
+
`observations/` and `case-plan.md` all live there.
|
|
353
|
+
|
|
354
|
+
### M1 — get app runs locally
|
|
355
|
+
|
|
356
|
+
Check how the agent's runs reach evalkit (`evalkit agents show <agent>` says
|
|
357
|
+
OTel or harness), then take one route:
|
|
358
|
+
|
|
359
|
+
1. **OTel agent that exports app traffic to evalkit** — the runs are already
|
|
360
|
+
on the server. Go to M2.
|
|
361
|
+
2. **Traces live in an external tracing tool** — import them first with
|
|
362
|
+
`evalkit traces import` (Phoenix is the only supported source today), wait
|
|
363
|
+
for the import (`evalkit traces imports <agent> <id>`), then go to M2.
|
|
364
|
+
3. **Harness agent** — `evalkit runs list` reads the harness's run list (the
|
|
365
|
+
server does it for a shared agent, your CLI for a personal one). Go to M2.
|
|
366
|
+
|
|
367
|
+
If `evalkit runs list <agent> --source app` returns nothing, stop: tell the
|
|
368
|
+
developer the agent sends only eval traffic to evalkit, and point at route 2
|
|
369
|
+
or at the connect-traces skill. Never continue with zero runs.
|
|
370
|
+
|
|
371
|
+
### M2 — choose the window, pull every run
|
|
372
|
+
|
|
373
|
+
Analyze every app run in the window; don't sample.
|
|
374
|
+
|
|
375
|
+
1. Ask for the time window (default: the last 7 days). Fix `until` to the
|
|
376
|
+
current time for the whole batch, so new runs don't shift the pages.
|
|
377
|
+
2. Count: `evalkit runs list <agent> --source app --since <since> --until
|
|
378
|
+
<until> --json` (one row per line).
|
|
379
|
+
3. If the count is 0, stop (see M1). If it is 100 or fewer, go on. Above 100,
|
|
380
|
+
tell the developer the count and the cost — one subagent per run, 5 at a
|
|
381
|
+
time — and offer to narrow the window. Go on with more than 100 only when
|
|
382
|
+
the developer states the number; "all" is not a number.
|
|
383
|
+
4. Pull 25 runs per call into the same directory:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
evalkit runs pull <agent> --source app --since <since> --until <until> \
|
|
387
|
+
--limit 25 --offset <0, 25, 50, …> --out <dir>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Every call adds to the same `index.json`; `runs/` stays flat. No files
|
|
391
|
+
come with the runs; M3 fetches them per run when it needs them.
|
|
392
|
+
5. Rows with `pull_error` could not be fetched in full: list them for the
|
|
393
|
+
developer and skip them in M3. If `index.json` has a `note`, pass it on.
|
|
394
|
+
|
|
395
|
+
### M3 — analyze each run (fan-out, capped at 5 concurrent)
|
|
396
|
+
|
|
397
|
+
For every row in `index.json` without a `pull_error`, run the instructions in
|
|
398
|
+
[`references/analyze-run.md`](references/analyze-run.md) against
|
|
399
|
+
`<dir>/<row.dir>`. On agents with subagent support, dispatch each analysis as
|
|
400
|
+
a subagent, 5 at a time; otherwise run them inline, one at a time. Each
|
|
401
|
+
writes `<dir>/observations/<run_id>.json` (create `observations/` first; use
|
|
402
|
+
the row's `dir` name for the file).
|
|
403
|
+
|
|
404
|
+
### M4 — synthesize the case plan (once)
|
|
405
|
+
|
|
406
|
+
Run [`references/synthesize-cases.md`](references/synthesize-cases.md) once
|
|
407
|
+
(as a subagent where supported), passing `<dir>/observations/`,
|
|
408
|
+
`<dir>/index.json`, the target suite directory (the case YAML the new cases
|
|
409
|
+
will join; ask the developer if there is more than one), and the output path
|
|
410
|
+
`<dir>/case-plan.md`.
|
|
411
|
+
|
|
412
|
+
Print the plan path and one line (`<P> patterns from <N> runs, plan at
|
|
413
|
+
<path>`), then STOP until the developer picks which patterns to author.
|
|
414
|
+
|
|
415
|
+
### M5 — author, lint, sync, request review
|
|
416
|
+
|
|
417
|
+
For each pattern the developer picked:
|
|
418
|
+
|
|
419
|
+
1. Author its proposed cases with the `authoring-eval-cases` skill. Its
|
|
420
|
+
interview fills every `NEEDS DEVELOPER` ground truth; never guess one.
|
|
421
|
+
2. `evalkit lint <file> --dataset <slug>`; errors block sync.
|
|
422
|
+
3. `evalkit sync <dataset dir>` (with `--workspace <ws>` for a shared
|
|
423
|
+
workspace you write to).
|
|
424
|
+
4. On a shared dataset, `evalkit review request <dataset>@<ws> --case-id <id>
|
|
425
|
+
--reviewer <user>`. The cases start Unreviewed.
|
|
426
|
+
|
|
427
|
+
Loop 2 ends here. It does not run the new cases; that is Loop 1's job.
|
|
428
|
+
|
|
429
|
+
### Interpreting Loop 2 outputs
|
|
430
|
+
|
|
431
|
+
- **`fixed_since` patterns** — author them like any other, as regression
|
|
432
|
+
guards, and keep the "expected green" mark in the summary.
|
|
433
|
+
- **`Already covered by`** — a partly covered pattern still gets cases for the
|
|
434
|
+
part no case asserts; a fully covered one is dropped from the plan.
|
|
435
|
+
- **Unclear or low-confidence observations** — the plan lists them at the end.
|
|
436
|
+
Mention them to the developer; don't author cases from them.
|
|
437
|
+
|
|
438
|
+
## Where the loops meet
|
|
439
|
+
|
|
440
|
+
Two handoffs, nothing else:
|
|
441
|
+
|
|
442
|
+
1. **Loop 2 → Loop 1.** After M5 the developer may ask to fix the agent for
|
|
443
|
+
the new cases. Enter Loop 1 at **C** (new cases, red expected) with the new
|
|
444
|
+
case ids as the working set.
|
|
445
|
+
2. **Loop 1 → authoring.** A diagnosis may find that a failure shows a scenario
|
|
446
|
+
no case covers, or that the case itself is wrong (`coverage_gap` on the
|
|
447
|
+
finding). `synthesize.md` lists these as "Case proposals" in
|
|
448
|
+
`proposals.md`, apart from the fix groups. Loop 1 keeps fixing the agent;
|
|
449
|
+
at the end, offer the case proposals to the developer, and author the
|
|
450
|
+
accepted ones through M5.
|
|
451
|
+
|
|
452
|
+
## Self-feedback
|
|
453
|
+
|
|
454
|
+
If you hit a gap in the EDD setup itself while running either loop (data missing
|
|
455
|
+
from a run directory, a CLI flag the loop wanted, an evaluator that should exist),
|
|
456
|
+
tell the developer in one line at the end. A nudge, not a report.
|
|
457
|
+
|
|
458
|
+
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,97 @@
|
|
|
1
|
+
# Analyze one app run
|
|
2
|
+
|
|
3
|
+
Instructions for analyzing **one** app run (a run of the agent outside any
|
|
4
|
+
experiment) and returning one structured JSON observation: what the user
|
|
5
|
+
wanted, whether the agent served it, and how it failed. On agents with
|
|
6
|
+
subagent support, dispatch these instructions as a read-only subagent, one
|
|
7
|
+
per run; otherwise follow them inline, one run at a time. Input: the absolute
|
|
8
|
+
path of one `runs/<run_id>/` directory produced by `evalkit runs pull
|
|
9
|
+
--source app`, plus the repo checkout(s) of the agent.
|
|
10
|
+
|
|
11
|
+
There is no expected answer and no score. The verdict comes from the
|
|
12
|
+
trajectory alone.
|
|
13
|
+
|
|
14
|
+
## What you may touch
|
|
15
|
+
|
|
16
|
+
- **Read access to the entire repo.** Use read-only inspection (`cat`,
|
|
17
|
+
`grep`, `jq`, `ls`, `git log`/`git show` — never anything that writes).
|
|
18
|
+
- **Hard rule: never modify the code repo.** Your observation IS your final
|
|
19
|
+
output.
|
|
20
|
+
|
|
21
|
+
## How to analyze
|
|
22
|
+
|
|
23
|
+
1. Read `run.json` and `trajectory.json` end to end. Steps run in `step_id`
|
|
24
|
+
order; each step's `tool_calls` carry structured `arguments`, their results
|
|
25
|
+
are in `observation.results` (matched by `source_call_id`; `extra.is_error:
|
|
26
|
+
true` marks a failed call), and `timestamp` shows where time went.
|
|
27
|
+
Delegated work is in `subagent_trajectories`. `evalkit runs pull` does
|
|
28
|
+
not fetch the run's files. If a shortened tool result is not enough, fetch
|
|
29
|
+
its full output with `evalkit runs files <pull dir> <run_id> --path
|
|
30
|
+
<extra.full_output_path>`; to see the deliverables, list the tree with
|
|
31
|
+
`evalkit runs files <pull dir> <run_id>` and fetch only the paths you need.
|
|
32
|
+
Fetched files land in `runs/<run_id>/files/<path>`.
|
|
33
|
+
2. Infer the user's intent: what they asked for, as of when, and what a good
|
|
34
|
+
answer would have contained.
|
|
35
|
+
3. Look for failure signals, strongest first:
|
|
36
|
+
- the user correcting the agent, re-asking the same thing, or giving up
|
|
37
|
+
mid-conversation;
|
|
38
|
+
- tool errors, retries of the same call, timeouts;
|
|
39
|
+
- an answer that hedges, refuses without reason, or states figures no tool
|
|
40
|
+
result supports;
|
|
41
|
+
- a wrong tool, a missing step (data the answer needed but never fetched),
|
|
42
|
+
wrong arguments;
|
|
43
|
+
- wasteful steps: redundant calls, discovery overhead, dead-end pivots;
|
|
44
|
+
- presentation problems: the right content badly shaped for the user.
|
|
45
|
+
4. Decide the verdict: `failed` (the user did not get what they needed),
|
|
46
|
+
`degraded` (they got it, with real waste or friction), `ok` (no failure),
|
|
47
|
+
`unclear` (the trajectory does not show enough to judge). Record `ok` runs
|
|
48
|
+
too; synthesis needs them.
|
|
49
|
+
5. For each failure, trace the surface (skill, tool, prompt, data source) in
|
|
50
|
+
the repo and name the file when you can.
|
|
51
|
+
6. **The run is history.** It shows the agent as of `run.json` /
|
|
52
|
+
`index.json` `created_at`. Check what changed since:
|
|
53
|
+
`git log --since=<created_at> -- <surface files>` and
|
|
54
|
+
`git log -S '<tool or prompt text from the trajectory>'`. Commit dates reset
|
|
55
|
+
on rebase and squash merge, so also read the last few commits on each
|
|
56
|
+
surface file (`git log -n 10 -- <file>`) whatever their date. If a later
|
|
57
|
+
commit already fixes the failure, fill `fixed_since`.
|
|
58
|
+
7. Write a case seed: a new, time-anchored input that exercises the same
|
|
59
|
+
failure, and the ideal behaviour. Don't copy the user's words or data; the
|
|
60
|
+
seed generalises the run.
|
|
61
|
+
|
|
62
|
+
## Output — return ONLY this JSON object
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"run_id": "<from index.json>",
|
|
67
|
+
"created_at": "<from index.json>",
|
|
68
|
+
"intent": "<one line: what the user asked for>",
|
|
69
|
+
"task_type": "<a case type from the authoring-eval-cases skill>",
|
|
70
|
+
"verdict": "failed | degraded | ok | unclear",
|
|
71
|
+
"signals": ["<short label, e.g. 'user re-asked', 'tool error x3'>"],
|
|
72
|
+
"failures": [
|
|
73
|
+
{
|
|
74
|
+
"kind": "wrong_answer | wrong_tool | missing_step | inefficiency | presentation | refusal",
|
|
75
|
+
"evidence": "<one specific line, citing main:<step_id> or <trajectory_id>:<step_id>>",
|
|
76
|
+
"steps": [12, 14],
|
|
77
|
+
"surface": {"kind": "skill | tool | prompt | mcp | data | absent", "file": "<repo path or null>"}
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"ideal_behaviour": "<one or two lines: what a good run does>",
|
|
81
|
+
"case_seed": {"input": "<new input, not the user's>", "anchor_date": "<YYYY-MM-DD>", "ground_truth_known": false},
|
|
82
|
+
"fixed_since": null,
|
|
83
|
+
"confidence": "high | medium | low"
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Rules:
|
|
88
|
+
|
|
89
|
+
- `failures` is empty when `verdict` is `ok`.
|
|
90
|
+
- Every `evidence` line cites a concrete step, tool result or artifact.
|
|
91
|
+
- `ground_truth_known` is `true` only when the correct answer can be checked
|
|
92
|
+
from the run's own tool results or the agent's data sources.
|
|
93
|
+
- `fixed_since` is `null`, or `{"commit": "<sha>", "detail": "<what it
|
|
94
|
+
changed>"}` when a commit made after the run already fixes every failure
|
|
95
|
+
listed.
|
|
96
|
+
- Never put user names, account ids or other personal data from the run into
|
|
97
|
+
the observation.
|