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
evalkit/api/review.py
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, HTTPException, Request
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
6
|
+
|
|
7
|
+
from evalkit.api.access import ActorDep, require, workspace_ref
|
|
8
|
+
from evalkit.api.auth import CurrentUser
|
|
9
|
+
from evalkit.api.deps import ReviewLogDep, SessionDep
|
|
10
|
+
from evalkit.contracts.enums import WorkspaceRole
|
|
11
|
+
from evalkit.core.access import WorkspaceRef, can_review
|
|
12
|
+
from evalkit.core.promotion import MissingTargetDataset, PromotionPlan
|
|
13
|
+
from evalkit.core.review import (
|
|
14
|
+
CaseReview,
|
|
15
|
+
CaseState,
|
|
16
|
+
CaseVersion,
|
|
17
|
+
NewCaseComment,
|
|
18
|
+
NotReviewable,
|
|
19
|
+
ensure_reviewable,
|
|
20
|
+
group_threads,
|
|
21
|
+
is_reviewable,
|
|
22
|
+
review_summary,
|
|
23
|
+
)
|
|
24
|
+
from evalkit.core.workspace import parse_slug
|
|
25
|
+
from evalkit.db.cases import current_cases, dataset_by_ref, list_datasets
|
|
26
|
+
from evalkit.db.promotion import execute_promotion, plan_promotion
|
|
27
|
+
from evalkit.db.review import ReviewLog
|
|
28
|
+
from evalkit.db.workspaces import WorkspaceStore
|
|
29
|
+
from evalkit.store.base import CaseView, DatasetRow, Selection, select_cases
|
|
30
|
+
|
|
31
|
+
router = APIRouter(prefix="/api", tags=["review"])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ReviewRequest(BaseModel):
|
|
35
|
+
selection: Selection
|
|
36
|
+
reviewer: str
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DecisionRequest(BaseModel):
|
|
40
|
+
action: Literal["approve", "request_changes"]
|
|
41
|
+
comment: str | None = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CommentRequest(BaseModel):
|
|
45
|
+
body: str
|
|
46
|
+
parent_id: int | None = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ResolveRequest(BaseModel):
|
|
50
|
+
resolved: bool
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def _suite(session: SessionDep, ref: str) -> tuple[DatasetRow, list[CaseView]]:
|
|
54
|
+
dataset = await dataset_by_ref(session, ref)
|
|
55
|
+
try:
|
|
56
|
+
ensure_reviewable(dataset)
|
|
57
|
+
except NotReviewable as exc:
|
|
58
|
+
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
|
59
|
+
return dataset, await current_cases(session, dataset)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def _dataset_workspace(session: SessionDep, ref: str) -> WorkspaceRef:
|
|
63
|
+
return await workspace_ref(session, (await dataset_by_ref(session, ref)).workspace)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def _not_target(request: Request, ws: WorkspaceRef, slug: str, case_id: str | None) -> None:
|
|
67
|
+
if not ws.is_target:
|
|
68
|
+
return
|
|
69
|
+
assert ws.promoted_from is not None
|
|
70
|
+
source = await WorkspaceStore(request.app.state.session_factory).get_by_id(ws.promoted_from)
|
|
71
|
+
where = f"{parse_slug(slug).name}@{source.name}"
|
|
72
|
+
what = f"review {case_id} in {where}" if case_id else f"request review in {where}"
|
|
73
|
+
raise HTTPException(status_code=409, detail=f"{slug} is fed by promotion; {what}")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async def _load_case_review(
|
|
77
|
+
session: SessionDep, review_log: ReviewLog, ref: str, case_id: str
|
|
78
|
+
) -> CaseReview:
|
|
79
|
+
_, cases = await _suite(session, ref)
|
|
80
|
+
case = next((c for c in cases if c.case_id == case_id), None)
|
|
81
|
+
if case is None:
|
|
82
|
+
raise HTTPException(status_code=404, detail=f"unknown case: {case_id}")
|
|
83
|
+
reviews = await review_log.load(ref, [CaseVersion.of(case)])
|
|
84
|
+
return reviews[case_id]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@router.post("/datasets/{slug}/review-requests")
|
|
88
|
+
async def request_review(
|
|
89
|
+
slug: str,
|
|
90
|
+
body: ReviewRequest,
|
|
91
|
+
review_log: ReviewLogDep,
|
|
92
|
+
session: SessionDep,
|
|
93
|
+
request: Request,
|
|
94
|
+
user: CurrentUser,
|
|
95
|
+
) -> dict:
|
|
96
|
+
_, cases = await _suite(session, slug)
|
|
97
|
+
ws = await _dataset_workspace(session, slug)
|
|
98
|
+
await _not_target(request, ws, slug, None)
|
|
99
|
+
reviewers = await WorkspaceStore(request.app.state.session_factory).members(
|
|
100
|
+
ws.name, WorkspaceRole.REVIEWER
|
|
101
|
+
)
|
|
102
|
+
if body.reviewer not in {m.username for m in reviewers}:
|
|
103
|
+
raise HTTPException(
|
|
104
|
+
status_code=400, detail=f"{body.reviewer} is not a reviewer of {ws.name}"
|
|
105
|
+
)
|
|
106
|
+
matched = select_cases(cases, body.selection)
|
|
107
|
+
reviews = await review_log.load(slug, [CaseVersion.of(case) for case in matched])
|
|
108
|
+
await review_log.append(
|
|
109
|
+
[r.request_review(user.username, body.reviewer) for r in reviews.values()]
|
|
110
|
+
)
|
|
111
|
+
return {"requested": sorted(reviews)}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@router.post("/datasets/{slug}/cases/{case_id}/review")
|
|
115
|
+
async def decide(
|
|
116
|
+
slug: str,
|
|
117
|
+
case_id: str,
|
|
118
|
+
body: DecisionRequest,
|
|
119
|
+
review_log: ReviewLogDep,
|
|
120
|
+
session: SessionDep,
|
|
121
|
+
request: Request,
|
|
122
|
+
user: ActorDep,
|
|
123
|
+
) -> dict:
|
|
124
|
+
ws = await _dataset_workspace(session, slug)
|
|
125
|
+
require(can_review(user, ws), "only reviewers of this workspace decide")
|
|
126
|
+
await _not_target(request, ws, slug, case_id)
|
|
127
|
+
text = (body.comment or "").strip()
|
|
128
|
+
if body.action == "request_changes" and not text:
|
|
129
|
+
raise HTTPException(status_code=400, detail="request_changes needs a comment")
|
|
130
|
+
review = await _load_case_review(session, review_log, slug, case_id)
|
|
131
|
+
plan: PromotionPlan | None = None
|
|
132
|
+
if body.action == "approve" and ws.promotes_to is not None:
|
|
133
|
+
dataset, cases = await _suite(session, slug)
|
|
134
|
+
case = next(c for c in cases if c.case_id == case_id)
|
|
135
|
+
try:
|
|
136
|
+
plan = await plan_promotion(session, ws, dataset, case)
|
|
137
|
+
except MissingTargetDataset as exc:
|
|
138
|
+
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
|
139
|
+
comment = (
|
|
140
|
+
NewCaseComment(
|
|
141
|
+
dataset=slug,
|
|
142
|
+
case_id=case_id,
|
|
143
|
+
content_hash=review.content_hash,
|
|
144
|
+
author=user.username,
|
|
145
|
+
body=text,
|
|
146
|
+
)
|
|
147
|
+
if text
|
|
148
|
+
else None
|
|
149
|
+
)
|
|
150
|
+
event = (
|
|
151
|
+
review.approve(user.username)
|
|
152
|
+
if body.action == "approve"
|
|
153
|
+
else review.request_changes(user.username)
|
|
154
|
+
)
|
|
155
|
+
actor_id = user.id
|
|
156
|
+
|
|
157
|
+
async def promote(db: AsyncSession, event_id: int) -> None:
|
|
158
|
+
assert plan is not None
|
|
159
|
+
await execute_promotion(db, plan, actor_id=actor_id, event_id=event_id)
|
|
160
|
+
|
|
161
|
+
await review_log.decide(event, comment, promote if plan is not None else None)
|
|
162
|
+
summary = review_summary(await _load_case_review(session, review_log, slug, case_id))
|
|
163
|
+
return {**summary, "promoted_to": plan.target_ref if plan is not None else None}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@router.get("/datasets/{slug}/cases/{case_id}/events")
|
|
167
|
+
async def events(slug: str, case_id: str, session: SessionDep, review_log: ReviewLogDep) -> dict:
|
|
168
|
+
await _load_case_review(session, review_log, slug, case_id)
|
|
169
|
+
return {"events": [e.model_dump() for e in await review_log.history(slug, case_id)]}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@router.get("/datasets/{slug}/cases/{case_id}/comments")
|
|
173
|
+
async def comments(slug: str, case_id: str, session: SessionDep, review_log: ReviewLogDep) -> dict:
|
|
174
|
+
await _load_case_review(session, review_log, slug, case_id)
|
|
175
|
+
return {"threads": group_threads(await review_log.comments(slug, case_id))}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@router.post("/datasets/{slug}/cases/{case_id}/comments")
|
|
179
|
+
async def add_comment(
|
|
180
|
+
slug: str,
|
|
181
|
+
case_id: str,
|
|
182
|
+
body: CommentRequest,
|
|
183
|
+
session: SessionDep,
|
|
184
|
+
review_log: ReviewLogDep,
|
|
185
|
+
user: CurrentUser,
|
|
186
|
+
) -> dict:
|
|
187
|
+
review = await _load_case_review(session, review_log, slug, case_id)
|
|
188
|
+
if body.parent_id is not None:
|
|
189
|
+
parent = await review_log.get_comment(body.parent_id)
|
|
190
|
+
if (
|
|
191
|
+
parent is None
|
|
192
|
+
or parse_slug(parent.dataset) != parse_slug(slug)
|
|
193
|
+
or parent.case_id != case_id
|
|
194
|
+
):
|
|
195
|
+
raise HTTPException(status_code=400, detail="parent comment is not on this case")
|
|
196
|
+
if parent.parent_id is not None:
|
|
197
|
+
raise HTTPException(status_code=400, detail="replies nest one level only")
|
|
198
|
+
if not body.body.strip():
|
|
199
|
+
raise HTTPException(status_code=400, detail="comment body is empty")
|
|
200
|
+
stored = await review_log.add_comment(
|
|
201
|
+
NewCaseComment(
|
|
202
|
+
dataset=slug,
|
|
203
|
+
case_id=case_id,
|
|
204
|
+
content_hash=review.content_hash,
|
|
205
|
+
parent_id=body.parent_id,
|
|
206
|
+
author=user.username,
|
|
207
|
+
body=body.body.strip(),
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
return stored.model_dump()
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@router.patch("/datasets/{slug}/cases/{case_id}/comments/{comment_id}")
|
|
214
|
+
async def resolve_comment(
|
|
215
|
+
slug: str,
|
|
216
|
+
case_id: str,
|
|
217
|
+
comment_id: int,
|
|
218
|
+
body: ResolveRequest,
|
|
219
|
+
review_log: ReviewLogDep,
|
|
220
|
+
session: SessionDep,
|
|
221
|
+
user: ActorDep,
|
|
222
|
+
) -> dict:
|
|
223
|
+
comment = await review_log.get_comment(comment_id)
|
|
224
|
+
if (
|
|
225
|
+
comment is None
|
|
226
|
+
or parse_slug(comment.dataset) != parse_slug(slug)
|
|
227
|
+
or comment.case_id != case_id
|
|
228
|
+
):
|
|
229
|
+
raise HTTPException(status_code=404, detail=f"unknown comment: {comment_id}")
|
|
230
|
+
ws = await _dataset_workspace(session, slug)
|
|
231
|
+
if comment.author != user.username and not can_review(user, ws):
|
|
232
|
+
raise HTTPException(status_code=403, detail="only a reviewer or the author may resolve")
|
|
233
|
+
return (await review_log.set_resolved(comment_id, body.resolved)).model_dump()
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
QueueState = Literal["review_requested", "changes_requested"]
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@router.get("/review/queue")
|
|
240
|
+
async def queue(
|
|
241
|
+
session: SessionDep,
|
|
242
|
+
review_log: ReviewLogDep,
|
|
243
|
+
reviewer: str | None = None,
|
|
244
|
+
state: QueueState = "review_requested",
|
|
245
|
+
workspace: str | None = None,
|
|
246
|
+
) -> dict:
|
|
247
|
+
items: list[dict] = []
|
|
248
|
+
for dataset in await list_datasets(session, workspace):
|
|
249
|
+
if not is_reviewable(dataset):
|
|
250
|
+
continue
|
|
251
|
+
cases = await current_cases(session, dataset)
|
|
252
|
+
reviews = await review_log.load(dataset.ref, [CaseVersion.of(case) for case in cases])
|
|
253
|
+
for case in cases:
|
|
254
|
+
r = reviews[case.case_id]
|
|
255
|
+
if r.last_event is None or r.state() is not CaseState(state):
|
|
256
|
+
continue
|
|
257
|
+
if reviewer is not None and r.requested_to != reviewer:
|
|
258
|
+
continue
|
|
259
|
+
question = case.input.get("question")
|
|
260
|
+
items.append(
|
|
261
|
+
{
|
|
262
|
+
"dataset": dataset.ref,
|
|
263
|
+
"case_id": case.case_id,
|
|
264
|
+
"requested_to": r.requested_to,
|
|
265
|
+
"requested_by": r.last_event.actor,
|
|
266
|
+
"requested_at": r.last_event.created_at,
|
|
267
|
+
"input": question if isinstance(question, str) else str(case.input),
|
|
268
|
+
}
|
|
269
|
+
)
|
|
270
|
+
items.sort(key=lambda i: (str(i["requested_at"]), i["dataset"], i["case_id"]), reverse=True)
|
|
271
|
+
return {"items": items}
|