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,387 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: authoring-eval-cases
|
|
3
|
+
description: Authors evalkit eval cases — interviews the stakeholder in plain domain language, verifies ground truth, anchors dates, and writes blackbox YAML cases asserted as answer rubrics (plus trajectory rubrics and presentation checks where they matter). Use when creating or editing eval cases, turning a described scenario or production issue into a case, or reviewing case quality.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Authoring eval cases
|
|
7
|
+
|
|
8
|
+
A case is a contract: a realistic input plus what any observer could check
|
|
9
|
+
about a correct response. Cases are **blackbox** — no tool names, skill names,
|
|
10
|
+
or any harness vocabulary anywhere in the case; that is what keeps a case
|
|
11
|
+
portable across harnesses, and `evalkit lint` enforces it as an error on the
|
|
12
|
+
question and every rubric. Checks that do know the harness's internals go in
|
|
13
|
+
evaluator config, never in that text:
|
|
14
|
+
|
|
15
|
+
- The built-in tool checks (`required_tools_called`, `tool_trajectory_match`)
|
|
16
|
+
go straight in the case when it lives in the client's own harness-specific
|
|
17
|
+
dataset, or in an overlay on a portable case. See
|
|
18
|
+
[`references/tool-checks.md`](references/tool-checks.md).
|
|
19
|
+
- Checks scored by the client's own Custom Evaluator API endpoints go in an
|
|
20
|
+
overlay. See [`references/overlays.md`](references/overlays.md).
|
|
21
|
+
|
|
22
|
+
## Terms
|
|
23
|
+
|
|
24
|
+
| Term | Meaning |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Case | One eval question: input, expected behaviour, evaluator config. One YAML document. |
|
|
27
|
+
| Dataset | A named set of cases in the evalkit store; a YAML file or directory syncs into one. |
|
|
28
|
+
| Split | A selectable subset of a dataset, built from case tags. |
|
|
29
|
+
| Rubric | One typed sentence in `answer_rubrics` asserting something a correct answer contains. |
|
|
30
|
+
| Rubric type | `factual_retrieval`, `derived_computation`, or `analysis_interpretation`; drives the per-type rates. |
|
|
31
|
+
| Source | The attribution a `factual_retrieval` rubric requires; graded on its own citation axis, never in the content score. |
|
|
32
|
+
| Trajectory rubric | One sentence in `trajectory_rubrics.rubrics`: a checkpoint — an intermediate value or a process step — the recorded trajectory or final answer must show. |
|
|
33
|
+
| Overlay | A client extension of a case by id, attaching custom-evaluator config or the built-in tool checks — see `references/overlays.md`. |
|
|
34
|
+
| Tool check | A built-in evaluator over the recorded tool calls: `required_tools_called` or `tool_trajectory_match` — see `references/tool-checks.md`. |
|
|
35
|
+
| Judge | The LLM an evaluator uses to grade; configured on the deployment, never in the case. |
|
|
36
|
+
| Red / green case | Red: the case fails against the current agent; green: it passes. For a capability gap red is the expected starting state — ship it red. |
|
|
37
|
+
|
|
38
|
+
## Interviewing the case author
|
|
39
|
+
|
|
40
|
+
Route here when the case originates from a stakeholder description or a
|
|
41
|
+
high-level intent — the author knows the domain and the correct behaviour, not
|
|
42
|
+
the agent's internals. The same protocol serves a developer authoring
|
|
43
|
+
in-session and a relayed exchange (e.g. a chat thread via a bot): every
|
|
44
|
+
clarifying round is a plain message, so the flow works headlessly.
|
|
45
|
+
|
|
46
|
+
Fill every slot below before writing YAML. Ask clarifying questions in batches
|
|
47
|
+
of at most 3 per round, in plain domain language — never mention tools,
|
|
48
|
+
skills, or agent internals to the author (a rule of this protocol, not a
|
|
49
|
+
general conversational rule). Stop asking when the slots are full, not before.
|
|
50
|
+
|
|
51
|
+
| Slot | Becomes | Notes |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| The scenario, in the author's words | — | The raw material for everything below. |
|
|
54
|
+
| A realistic user phrasing | `input.question` | Derive it FROM the scenario and play it back for confirmation — authors are not expected to produce verbatim input. |
|
|
55
|
+
| A date anchor in the input | part of `input.question` | Whenever the answer is time-sensitive, anchor the question itself ("as of 30 September 2025") so pinned ground truth cannot drift under the case. |
|
|
56
|
+
| What a correct answer contains | `answer_rubrics` | Concrete values (or the correct honest negative), dated — see the rubric sections below. |
|
|
57
|
+
| The intermediate values and visible steps the work should show | `trajectory_rubrics` | Checkpoint sentences — see below. |
|
|
58
|
+
| Presentation requirements, if any | `presentation_judge` | Units shown, columns present, an artifact relayed rather than restated. |
|
|
59
|
+
| A latency bound, if the case has one | `max_response_time` | Seconds; settable file-wide via `defaults.max_response_time`. |
|
|
60
|
+
|
|
61
|
+
For agents that return a structured `output` (classifiers, taggers,
|
|
62
|
+
extractors) instead of prose: `answer_rubrics` still works, since the judge
|
|
63
|
+
reads the output as JSON text, so a rubric like "The label is EVENT" can be
|
|
64
|
+
graded. Skip `presentation_judge`, because layout and units mean nothing for
|
|
65
|
+
JSON. Exact field checks belong in a custom evaluator that reads
|
|
66
|
+
`run.output`.
|
|
67
|
+
|
|
68
|
+
## Ground-truth verification
|
|
69
|
+
|
|
70
|
+
Do not accept vague expectations. Verify the values yourself from whatever
|
|
71
|
+
verified data source is available in the session (the client's data tools,
|
|
72
|
+
primary documents):
|
|
73
|
+
|
|
74
|
+
1. Query the relevant data for the case's anchored date.
|
|
75
|
+
2. Show the author the concrete values ("I see revenue of X and margin of Y
|
|
76
|
+
for that quarter — is that what the agent should show?").
|
|
77
|
+
3. Pin the confirmed values as rubrics with the as-of date.
|
|
78
|
+
|
|
79
|
+
When no verified source in the session can produce the values, ask the author
|
|
80
|
+
for the exact numbers — a number the author supplies and stands behind is
|
|
81
|
+
verified ground truth; a model-asserted one never is. If neither you nor the
|
|
82
|
+
author can produce the values, tag the case `needs-ground-truth`, keep the
|
|
83
|
+
expectation as written, and keep the case out of the main runs — never soften
|
|
84
|
+
a case to make it passable.
|
|
85
|
+
|
|
86
|
+
## Writing answer rubrics
|
|
87
|
+
|
|
88
|
+
`answer_rubrics` is the output evaluator: everything the answer must contain,
|
|
89
|
+
one flat list of typed sentences. Field shapes are validated by `evalkit lint`;
|
|
90
|
+
the sections below are about judgement — what to assert, which type it is, and
|
|
91
|
+
how to phrase it.
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
evaluators:
|
|
95
|
+
output:
|
|
96
|
+
answer_rubrics:
|
|
97
|
+
rubrics:
|
|
98
|
+
- rubric: "States that the company's actual Q3 FY2024 non-GAAP gross margin was 28.1%."
|
|
99
|
+
type: factual_retrieval
|
|
100
|
+
source: "Q3 FY2024 results"
|
|
101
|
+
- rubric: "Calculates that the company beat its guidance midpoint by 160 bps (±10 bps),
|
|
102
|
+
measuring against the 26.5% midpoint rather than the endpoints of the range."
|
|
103
|
+
type: derived_computation
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`source` is optional and only valid on `factual_retrieval`. `type` is required.
|
|
107
|
+
There is no `points`, no `tolerance` field, and no judge model override — the
|
|
108
|
+
judge comes from the deployment config.
|
|
109
|
+
|
|
110
|
+
### Assert only what the question asks
|
|
111
|
+
|
|
112
|
+
A rubric holds the answer to the question as asked, not to the author's
|
|
113
|
+
unstated wishes. An expectation the question never expressed belongs in a
|
|
114
|
+
rubric only when it is an obvious implication of the ask or carries strong
|
|
115
|
+
convention (a "compare YoY" question implies both years' figures). Anything
|
|
116
|
+
else is the rubric unfairly penalizing a reasonable answer — if the
|
|
117
|
+
expectation matters, put it in the question.
|
|
118
|
+
|
|
119
|
+
### Answer rubric types
|
|
120
|
+
|
|
121
|
+
| `type` | The assertion is about |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `factual_retrieval` | anything stated in a source: a value, entity, date, category, classification, or a statement attributed to someone |
|
|
124
|
+
| `derived_computation` | a figure the answer works out rather than looks up, and the method or scope behind it |
|
|
125
|
+
| `analysis_interpretation` | what the figures show — a trend, a ranking, a cause, a driver, a comparison |
|
|
126
|
+
|
|
127
|
+
Apply in order and stop at the first that fits:
|
|
128
|
+
|
|
129
|
+
1. Is the assertion **quoted from a source** — some document, filing,
|
|
130
|
+
transcript or feed states it, and the work is retrieval plus faithful
|
|
131
|
+
reproduction? → `factual_retrieval`
|
|
132
|
+
2. Otherwise the answer **produced** it, and no source contains this sentence:
|
|
133
|
+
- a figure it computed, or the method or scope behind one →
|
|
134
|
+
`derived_computation`
|
|
135
|
+
- a statement about what the figures show → `analysis_interpretation`
|
|
136
|
+
|
|
137
|
+
This split is the one that tells you where to look when a case fails: it
|
|
138
|
+
separates "the data never arrived" from "the reasoning was wrong". An
|
|
139
|
+
assertion about **how the answer displays** something — a table, an ordering,
|
|
140
|
+
a unit label — is not an answer rubric at all; it goes under
|
|
141
|
+
`presentation_judge` (see below).
|
|
142
|
+
|
|
143
|
+
### An `analysis_interpretation` rubric is a reading of the facts, not an opinion
|
|
144
|
+
|
|
145
|
+
Every rubric of this type has one right answer, worked out from facts the
|
|
146
|
+
answer already has: given four quarterly beats, exactly one is the largest.
|
|
147
|
+
Where a question has more than one reasonable answer, **no rubric says which
|
|
148
|
+
answer to reach.** A rubric asks that a point be weighed — "Weighs the FY27
|
|
149
|
+
refinancing wall against the current cash position" — not that the answer
|
|
150
|
+
conclude the bond is overvalued. If grading a rubric would mean the judge
|
|
151
|
+
picking a side in a real disagreement, don't write that rubric, in this type
|
|
152
|
+
or any other.
|
|
153
|
+
|
|
154
|
+
### Numeric matching is lenient by default
|
|
155
|
+
|
|
156
|
+
A figure matches after unit conversion, and normal rounding of the rubric's
|
|
157
|
+
figure is accepted: against "3,172.6 million", an answer saying "3,173
|
|
158
|
+
million" or "3.17 billion" satisfies the rubric, while "3,180 million" is a
|
|
159
|
+
different figure, not a rounding. Write the plain correct value and let the
|
|
160
|
+
default do its work.
|
|
161
|
+
|
|
162
|
+
State an acceptance criterion in the sentence only when the case wants
|
|
163
|
+
something the default doesn't give — tighter ("exactly 3,172.6 million"),
|
|
164
|
+
wider ("±1 million"), or alternative ("either the standalone or the
|
|
165
|
+
consolidated figure", "any figure between X and Y"). A stated criterion
|
|
166
|
+
replaces the default, and stating it in the sentence keeps it visible to a
|
|
167
|
+
dataset reader.
|
|
168
|
+
|
|
169
|
+
### How specific to make a `source`
|
|
170
|
+
|
|
171
|
+
`source` asserts that the answer credits the fact to that source. It is graded
|
|
172
|
+
on its own citation axis and never counted in the content score, because
|
|
173
|
+
getting a fact right says nothing about citing it.
|
|
174
|
+
|
|
175
|
+
Write it at the granularity the case cares about. An over-specific source
|
|
176
|
+
string creates failures that are not real: a rubric naming the "earnings
|
|
177
|
+
release" against an answer citing the "earnings call" is a different document,
|
|
178
|
+
so it scores `incorrect` even when the figure appears in both. Where several
|
|
179
|
+
disclosures are acceptable, name the set loosely — "any Q3 FY2024 disclosure".
|
|
180
|
+
Attach a `source` to every `factual_retrieval` rubric whose provenance the
|
|
181
|
+
case actually cares about, not to a token handful.
|
|
182
|
+
|
|
183
|
+
### Methodology goes in the rubric text
|
|
184
|
+
|
|
185
|
+
A `derived_computation` rubric states its own method inline — the method
|
|
186
|
+
determines the value, so the figure already tests it. Where a case wants the
|
|
187
|
+
method stated explicitly (transparency the answer owes the reader, or two
|
|
188
|
+
methods give the same figure), that is its own `derived_computation` rubric.
|
|
189
|
+
A statement about what a source does or does not report ("X does not report
|
|
190
|
+
segment revenue") is itself a fact, so it is `factual_retrieval`.
|
|
191
|
+
|
|
192
|
+
### One rubric, one assertion
|
|
193
|
+
|
|
194
|
+
Split anything a reader could grade two ways into two rubrics. A rubric may
|
|
195
|
+
pair two periods where the comparison is the point — that is one comparison,
|
|
196
|
+
not two facts. A rubric bundling a figure with an explanation of it is two
|
|
197
|
+
rubrics.
|
|
198
|
+
|
|
199
|
+
### Honest negatives are ordinary rubrics
|
|
200
|
+
|
|
201
|
+
Where the correct answer *is* a negative the answer should state, write it as
|
|
202
|
+
a positive rubric: "States that the company does not report free cash flow."
|
|
203
|
+
That grades all three outcomes: claiming a reported figure is `incorrect`,
|
|
204
|
+
saying there is none is `satisfied`, ducking it is `absent`.
|
|
205
|
+
|
|
206
|
+
### No harness vocabulary
|
|
207
|
+
|
|
208
|
+
The corpus is published independently of any agent, so a rubric never names a
|
|
209
|
+
tool, skill, server, data provider or any other implementation concept. Assert
|
|
210
|
+
what a correct answer contains, not how it was obtained.
|
|
211
|
+
|
|
212
|
+
### What you get back
|
|
213
|
+
|
|
214
|
+
| Score | Meaning |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `answer_rubric_score` | share of the case's rubrics satisfied — the case's published score, and what `collect --threshold` compares against |
|
|
217
|
+
| `answer_rubric_coverage` | share of rubrics the answer engaged at all |
|
|
218
|
+
| `answer_rubric_accuracy` | of the rubrics it engaged, the share it got right |
|
|
219
|
+
| `answer_rubric_<type>` × 3 | the same recall within one type; skips where the case has no rubrics of that type |
|
|
220
|
+
| `answer_rubric_citation` | of the facts the answer stated, the share correctly attributed |
|
|
221
|
+
|
|
222
|
+
Each rubric gets one of three verdicts — `satisfied`, `incorrect`, `absent` —
|
|
223
|
+
and so does each `source`. The explanation JSON carries the counts, the
|
|
224
|
+
per-type breakdown, the citation block and the full verdict list, which is
|
|
225
|
+
what makes a failure diagnosable: which rubrics were wrong versus silent, what
|
|
226
|
+
the answer said instead, and whether a stated fact was misattributed or merely
|
|
227
|
+
uncited.
|
|
228
|
+
|
|
229
|
+
Every corpus-level number is pooled over rubrics, not averaged over cases, so
|
|
230
|
+
a 16-rubric case carries 16 times the weight of a 1-rubric case. That is also
|
|
231
|
+
why there are no points: a weight only means something next to its siblings,
|
|
232
|
+
and pooling would add a "3" in one case to a "3" in another as though they
|
|
233
|
+
meant the same thing.
|
|
234
|
+
|
|
235
|
+
## Presentation checks
|
|
236
|
+
|
|
237
|
+
How the answer displays its content — a table with named columns, an ordering,
|
|
238
|
+
units shown, an artifact relayed rather than restated — goes under
|
|
239
|
+
`presentation_judge`, never into `answer_rubrics`. Each entry is a property
|
|
240
|
+
the answer must have, phrased as the property rather than a description of
|
|
241
|
+
the answer having it ("A store count for each fiscal year FY2021–FY2025, as a
|
|
242
|
+
table or a labelled list"); `forbid` entries name properties the answer must
|
|
243
|
+
not have. Correctness of the figures stays in `answer_rubrics` — asserting
|
|
244
|
+
the same thing in both places reweights it rather than making the case
|
|
245
|
+
stricter.
|
|
246
|
+
|
|
247
|
+
## Writing trajectory rubrics
|
|
248
|
+
|
|
249
|
+
`trajectory_rubrics.rubrics` is a flat list of sentences. Each is a checkpoint
|
|
250
|
+
the recorded trajectory or the final answer must show. The judge sees the
|
|
251
|
+
question, the rubrics, the full ATIF trajectory — tool calls, tool results,
|
|
252
|
+
subagents, and the agent's reasoning where the harness records it — and the
|
|
253
|
+
final answer, and marks each rubric satisfied or unsatisfied on positive
|
|
254
|
+
evidence, citing steps as `main:<step_id>` or `<trajectory_id>:<step_id>`. The
|
|
255
|
+
score is satisfied ÷ total. Order is not graded. The whole trajectory goes to
|
|
256
|
+
the judge in one call, nothing truncated.
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
evaluators:
|
|
260
|
+
trajectory:
|
|
261
|
+
trajectory_rubrics:
|
|
262
|
+
rubrics:
|
|
263
|
+
- "Retrieves Roku's FY2024 Platform revenue as $3,522,776,000."
|
|
264
|
+
- "Retrieves Roku's FY2023 Platform revenue as $2,994,105,000."
|
|
265
|
+
- "Retrieves the FY2023 restructuring expense inside Platform cost of revenue as $67,032,000."
|
|
266
|
+
- "Calculates FY2023 Platform cost of revenue excluding restructuring as $1,360,514,000."
|
|
267
|
+
- "Calculates FY2023 adjusted Platform gross margin as 45.44% (±0.005pp)."
|
|
268
|
+
- "Calculates FY2024 adjusted Platform gross margin as 46.46% (±0.005pp)."
|
|
269
|
+
- "Computes the margin change from the two adjusted margins, not from the reported ones."
|
|
270
|
+
- "Rounds the final figure to the nearest basis point."
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Two kinds of rubric share the list:
|
|
274
|
+
|
|
275
|
+
1. **Checkpoints with a value** — every input the derivation retrieves and
|
|
276
|
+
every intermediate result it computes, each with its figure. The sentence
|
|
277
|
+
carries the subject, period, unit and value, and a band wherever rounding
|
|
278
|
+
is expected, exactly as an answer rubric does. "Retrieves FY2023 capital
|
|
279
|
+
expenditure as $3,100,000" — not "gathers the cash-flow data".
|
|
280
|
+
2. **Process steps in plain language** — a step whose evidence is an action
|
|
281
|
+
or a method rather than a figure: "Reads the debt footnote of the 10-Q for
|
|
282
|
+
27 September 2025", "Uses the guidance midpoint rather than the range
|
|
283
|
+
endpoints", "Rounds the final figure to the nearest basis point".
|
|
284
|
+
|
|
285
|
+
To decompose, work the derivation yourself: one rubric per input retrieved,
|
|
286
|
+
one per intermediate result, then the final figure. Ground-truth verification
|
|
287
|
+
covers every intermediate value the same way it covers the final ones — a
|
|
288
|
+
checkpoint figure you have not verified is a guess dressed as a rubric.
|
|
289
|
+
|
|
290
|
+
When an input is a series or a list — ten years of yields, forty trades, every
|
|
291
|
+
holding in a fund — do not write one rubric per point. Write spot checks: two
|
|
292
|
+
or three specific points with their values (the first, the last, and one that
|
|
293
|
+
is easy to get wrong), plus one rubric on the shape of the whole ("Retrieves
|
|
294
|
+
month-end 10-year G-sec yields for all 120 months from January 2016 to
|
|
295
|
+
December 2025"). A run that fetched the series passes the spot checks; a run
|
|
296
|
+
that fetched the wrong series or half of it fails them.
|
|
297
|
+
|
|
298
|
+
Specific-but-portable is the bar: naming *what* data (which company, which
|
|
299
|
+
metric, which period, which value) stays harness-agnostic — every harness
|
|
300
|
+
fetches data somehow and the recorded steps show it. Only naming *how* (tools,
|
|
301
|
+
skills, servers) breaks portability.
|
|
302
|
+
|
|
303
|
+
The final figure usually appears in both the answer rubrics and the trajectory
|
|
304
|
+
rubrics. That is fine: they are different evaluators in different buckets, one
|
|
305
|
+
asking what was delivered and the other how it was derived. Do not copy the
|
|
306
|
+
rest of the answer list across — the trajectory list is the derivation path.
|
|
307
|
+
|
|
308
|
+
Red flags: a rubric whose text is a dash-separated list of content ("— market
|
|
309
|
+
size, top players, risks, outlook") is several rubrics in disguise; a
|
|
310
|
+
checkpoint with no value where the derivation clearly has one; and an expected
|
|
311
|
+
answer containing values the user did not supply with no rubric saying where
|
|
312
|
+
each comes from.
|
|
313
|
+
|
|
314
|
+
## Red cases
|
|
315
|
+
|
|
316
|
+
A red case on first run is a finding, not a mistake — for a capability gap,
|
|
317
|
+
red is the expected starting state. Ship it red.
|
|
318
|
+
|
|
319
|
+
## Attaching files
|
|
320
|
+
|
|
321
|
+
When the question is about a document the agent must read, attach it as a
|
|
322
|
+
fixture rather than pasting its contents:
|
|
323
|
+
|
|
324
|
+
1. Put the file in the `fixtures` directory named in `evalkit.yaml`, under a
|
|
325
|
+
flat, descriptive filename: the fixture `<key>`
|
|
326
|
+
(`meridian-balance-sheet-fy2025.csv`).
|
|
327
|
+
2. Declare it once in the suite's `fixtures.yaml` with its `sha256`
|
|
328
|
+
(`shasum -a 256 <file>`) and a `context`: one or two sentences saying what
|
|
329
|
+
the file is, its period, its units and anything about its layout the agent
|
|
330
|
+
needs. This text is prepended to every question that uses the file, so the
|
|
331
|
+
question itself should not describe the file.
|
|
332
|
+
3. Reference it from the case with `fixtures: [<key>]`. Several cases can
|
|
333
|
+
share one key.
|
|
334
|
+
|
|
335
|
+
Only the registry entry goes into git; the bytes live in the `fixtures`
|
|
336
|
+
directory named in `evalkit.yaml`. `evalkit run` and `evalkit sync` upload
|
|
337
|
+
them to the server, stored by `sha256`, and fail naming any key whose file is
|
|
338
|
+
missing or whose bytes do not match the registry `sha256`. Nobody uploads to
|
|
339
|
+
blob storage by hand. To replace a file, change the
|
|
340
|
+
bytes under the same key and update the `sha256`; the next run re-versions
|
|
341
|
+
every case that uses the key. If the old version matters for comparison, use
|
|
342
|
+
a new key instead.
|
|
343
|
+
|
|
344
|
+
## Before sync
|
|
345
|
+
|
|
346
|
+
Run `evalkit lint <file-or-dir> --dataset <slug>` and fix every error (warnings
|
|
347
|
+
are advisory). `--dataset` is the dataset you will sync into; it lets the
|
|
348
|
+
server check case ids and overlay targets against every other dataset.
|
|
349
|
+
A jargon-leak error is fixed by rewording the case, never by renaming
|
|
350
|
+
internals. Then `evalkit run <dataset> --agent <agent>` syncs the directory
|
|
351
|
+
to your workspace and runs it; CI, logged in as `admin`, runs `evalkit sync
|
|
352
|
+
<dir> --workspace dev` (the team's shared workspace) on merge (see
|
|
353
|
+
`evalkit --help` for exact flags).
|
|
354
|
+
|
|
355
|
+
## After sync
|
|
356
|
+
|
|
357
|
+
```mermaid
|
|
358
|
+
stateDiagram-v2
|
|
359
|
+
[*] --> Unreviewed: sync
|
|
360
|
+
Unreviewed --> ReviewRequested: request review
|
|
361
|
+
ReviewRequested --> Approved: reviewer approves
|
|
362
|
+
ReviewRequested --> ChangesRequested: reviewer requests changes
|
|
363
|
+
ChangesRequested --> ReviewRequested: edit and re-sync
|
|
364
|
+
Approved --> Unreviewed: edit and re-sync
|
|
365
|
+
Approved --> ChangesRequested: reviewer requests changes
|
|
366
|
+
Approved --> [*]: promoted to the target workspace (if linked)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Review applies to datasets in a shared workspace (e.g. `finance@dev`);
|
|
370
|
+
datasets in your personal workspace have no review state. Review never
|
|
371
|
+
filters a run: experiments run every case, whatever its state. In a shared
|
|
372
|
+
dataset a synced case starts Unreviewed. When the case is right, request review:
|
|
373
|
+
`evalkit review request finance@dev --case-id <id> --reviewer <user>`, or
|
|
374
|
+
use the case page in the UI. Reviewers are the
|
|
375
|
+
workspace's members with the reviewer role. A reviewer approves it or
|
|
376
|
+
requests changes with a comment; `evalkit review show <slug> <id>` prints the
|
|
377
|
+
state, changelog and comments. Editing an approved case makes it Unreviewed
|
|
378
|
+
again.
|
|
379
|
+
|
|
380
|
+
If an admin has linked the workspace to a promotion target (for example
|
|
381
|
+
`dev → prod`), approval is also the release: the approved version lands in
|
|
382
|
+
the same-named dataset of the target, already approved, with its overlays.
|
|
383
|
+
The target accepts no sync and no review decisions of its own, so a fix
|
|
384
|
+
always goes back through the source. The case page shows the twin in the
|
|
385
|
+
other workspace; see the evalkit-usage skill, "Promotion between workspaces".
|
|
386
|
+
|
|
387
|
+
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,83 @@
|
|
|
1
|
+
# Whitebox enrichment via overlays
|
|
2
|
+
|
|
3
|
+
An on-demand flow — run it when the developer asks to enrich a case with
|
|
4
|
+
harness-specific assertions. Enrichment ADDS whitebox checks to a blackbox
|
|
5
|
+
case as an **overlay**: a YAML entry in the client's own cases directory
|
|
6
|
+
(`extends: <case-id>`) that extends a case in another suite by id and
|
|
7
|
+
attaches whitebox checks: evalkit's built-in tool checks under
|
|
8
|
+
`evaluators.trajectory`, or config for the client's Custom Evaluator API
|
|
9
|
+
endpoints under `evaluators.custom`.
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
overlays:
|
|
13
|
+
- extends: <case-id>
|
|
14
|
+
agents: [<agent name>]
|
|
15
|
+
tags: [<additive tags, optional>]
|
|
16
|
+
evaluators:
|
|
17
|
+
trajectory:
|
|
18
|
+
required_tools_called: { tools: [<real tool names>] }
|
|
19
|
+
tool_trajectory_match: { expected: [ ... ] }
|
|
20
|
+
custom:
|
|
21
|
+
<registered evaluator>: { ... }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set `agents` once for a whole file with `defaults:`:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
defaults:
|
|
28
|
+
agents: [<agent name>]
|
|
29
|
+
overlays:
|
|
30
|
+
- extends: <case-id>
|
|
31
|
+
evaluators: { ... }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Rules:
|
|
35
|
+
|
|
36
|
+
- `agents` is required. The overlay scores only runs of the agents it names;
|
|
37
|
+
every other agent runs the case without it. Agents match by name in any
|
|
38
|
+
workspace: `agents: [support-bot]` covers both `support-bot` and `support-bot@<you>`.
|
|
39
|
+
- Several overlay datasets may extend the same case. Two of them may not set
|
|
40
|
+
the same evaluator for the same agent on one case: the second sync fails
|
|
41
|
+
with `E-OVERLAY-CLASH`.
|
|
42
|
+
- An overlay may only carry `extends`, `agents`, additive `tags`,
|
|
43
|
+
`evaluators.trajectory` (only `tool_trajectory_match` and
|
|
44
|
+
`required_tools_called`) and `evaluators.custom`. Touching `input`,
|
|
45
|
+
`expected`, or any other built-in evaluator config is a lint error — ground
|
|
46
|
+
truth is not overlay-editable. Stripping the overlay must leave a portable
|
|
47
|
+
case.
|
|
48
|
+
- Every custom evaluator name must be registered in the deployment's
|
|
49
|
+
config.yaml (`custom_evaluators:`), and the client must host the matching
|
|
50
|
+
Custom Evaluator API endpoint that knows how to score that config against
|
|
51
|
+
the run's answer + ATIF trajectory. The built-in tool checks need no
|
|
52
|
+
endpoint; see [`tool-checks.md`](tool-checks.md) for their config.
|
|
53
|
+
- Overlays live in the client's YAML dir and reach the server via
|
|
54
|
+
`evalkit sync` — removing one from the dir strips the enrichment on the next
|
|
55
|
+
directory sync.
|
|
56
|
+
|
|
57
|
+
## Run-then-pin
|
|
58
|
+
|
|
59
|
+
1. Run the case single-case (`evalkit run <dataset> --agent <agent>
|
|
60
|
+
--case-id <id>`; the run syncs first); collect the experiment.
|
|
61
|
+
2. Read the observed trajectory from the collected bundle. Derive the
|
|
62
|
+
enrichment from what actually happened:
|
|
63
|
+
- required tools: the real data tools the run used;
|
|
64
|
+
- trajectory match: observed calls with their args (prefer `substring`
|
|
65
|
+
for free-text args);
|
|
66
|
+
- call caps: observed counts plus slack (a cap of observed+1 fails the case
|
|
67
|
+
on the first regression into retry-grinding without flaking on normal
|
|
68
|
+
variance).
|
|
69
|
+
3. Cross-check the observed tool choices against the harness's canonical tool
|
|
70
|
+
surface (its tool definitions / MCP server source). If a better tool or
|
|
71
|
+
trajectory exists than the one observed, pin the better one and let the
|
|
72
|
+
case go red: the case is the contract, and the red is a finding for the
|
|
73
|
+
EDD loop.
|
|
74
|
+
4. Curate — pin intent, not accident:
|
|
75
|
+
- Date literals in args are correct when the case input is date-anchored
|
|
76
|
+
(they assert the agent honoured the as-of). Do not pin values the agent
|
|
77
|
+
derived from run time.
|
|
78
|
+
- Do not pin incidental arg values (page sizes, orderings) that a
|
|
79
|
+
different-but-correct run would legitimately vary.
|
|
80
|
+
5. `evalkit lint <file> --dataset <slug>` the overlay file (unregistered
|
|
81
|
+
evaluator names and bad targets are errors; the target check needs
|
|
82
|
+
`--dataset`), then re-run the case to confirm the enriched assertions
|
|
83
|
+
hold.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Built-in tool checks
|
|
2
|
+
|
|
3
|
+
Two built-in evaluators check the tool calls in the run's ATIF trajectory,
|
|
4
|
+
subagents included: `required_tools_called` and `tool_trajectory_match`. Both
|
|
5
|
+
need a harness that declares `trajectory` and `tool_calls`; otherwise they
|
|
6
|
+
skip. Both score into the trajectory bucket.
|
|
7
|
+
|
|
8
|
+
Write each tool name exactly as the harness records it in the trajectory,
|
|
9
|
+
including any prefix the harness adds.
|
|
10
|
+
|
|
11
|
+
## Where they go
|
|
12
|
+
|
|
13
|
+
Tool checks name the harness's tools, so a case that carries them only works
|
|
14
|
+
against that harness. Put them in one of two places:
|
|
15
|
+
|
|
16
|
+
- **In the case itself**, under `evaluators.trajectory`, when the case lives
|
|
17
|
+
in the client's own harness-specific dataset (cases written only for that
|
|
18
|
+
client's agent). The rest of the case stays blackbox: `input.question`
|
|
19
|
+
and every rubric remain free of tool names, and lint still checks that.
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
- id: <case-id>
|
|
23
|
+
input: {question: "..."}
|
|
24
|
+
evaluators:
|
|
25
|
+
output:
|
|
26
|
+
answer_rubrics: {rubrics: [...]}
|
|
27
|
+
trajectory:
|
|
28
|
+
required_tools_called: {tools: [<real tool names>]}
|
|
29
|
+
tool_trajectory_match: {expected: [...]}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- **In an overlay**, under `evaluators.trajectory`, when the case belongs to
|
|
33
|
+
a portable suite someone else maintains. The overlay adds the checks
|
|
34
|
+
without touching the case; see [`overlays.md`](overlays.md).
|
|
35
|
+
|
|
36
|
+
## Config
|
|
37
|
+
|
|
38
|
+
`required_tools_called` — every listed tool must be called at least once.
|
|
39
|
+
Extra calls are fine. Score = tools called ÷ tools listed.
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
required_tools_called:
|
|
43
|
+
tools: [get_instrument_details, get_bond_trades]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`tool_trajectory_match` — expected calls, matched by name and args. Each
|
|
47
|
+
actual call can satisfy at most one expected entry. Score = entries matched ÷
|
|
48
|
+
entries.
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
tool_trajectory_match:
|
|
52
|
+
ordered: false # true: entries must also appear in this order
|
|
53
|
+
expected:
|
|
54
|
+
- name: get_bond_trades
|
|
55
|
+
args: {isins: "INE831R07540"}
|
|
56
|
+
args_mode: substring # subset (default) | exact | ignore | substring
|
|
57
|
+
- name: get_bond_vwap
|
|
58
|
+
args: {series: "SDL", isin: "INE"}
|
|
59
|
+
match_overrides: {isin: substring} # per-arg: equals | substring
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| `args_mode` | Matches when |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `subset` | every expected key is present and equal; extra actual keys allowed |
|
|
65
|
+
| `exact` | the actual args equal the expected args |
|
|
66
|
+
| `ignore` | the name matches; args are not checked |
|
|
67
|
+
| `substring` | like `subset`, but each expected value need only appear, case-insensitively, inside the actual value (lists and dicts compared as JSON text) |
|
|
68
|
+
|
|
69
|
+
`match_overrides` sets the mode for single keys of `args`; it is not allowed
|
|
70
|
+
with `exact` or `ignore`. Each unmatched entry reports why: `name miss`,
|
|
71
|
+
`args mismatch`, `out of order` or `no available matching call`.
|