coder-eval 0.8.3__tar.gz → 0.8.4__tar.gz
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.
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/harness-candidates.md +10 -4
- {coder_eval-0.8.3 → coder_eval-0.8.4}/CHANGELOG.md +59 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/CLAUDE.md +6 -4
- {coder_eval-0.8.3 → coder_eval-0.8.4}/PKG-INFO +8 -2
- {coder_eval-0.8.3 → coder_eval-0.8.4}/README.md +6 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/AB_EXPERIMENTS.md +34 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/TASK_DEFINITION_GUIDE.md +56 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/04-writing-a-task.md +1 -0
- coder_eval-0.8.4/evalboard/app/_components/__tests__/search-box.test.tsx +120 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/search-box.tsx +20 -4
- coder_eval-0.8.4/experiments/early-stop-ab.yaml +23 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/pyproject.toml +2 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/__init__.py +1 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agent.py +19 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/antigravity_agent.py +7 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/claude_code_agent.py +58 -11
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/codex_agent.py +6 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/noop_agent.py +6 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/plan_command.py +8 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/base.py +59 -1
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/command_executed.py +129 -37
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/skill_triggered.py +68 -2
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/__init__.py +4 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/criteria.py +12 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/limits.py +11 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/results.py +88 -0
- coder_eval-0.8.4/src/coder_eval/orchestration/early_stop.py +328 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/experiment.py +8 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestrator.py +49 -2
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/reports.py +8 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/reports_experiment.py +8 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/reports_html.py +15 -3
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/sandbox.py +43 -8
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/events.py +2 -0
- coder_eval-0.8.4/tests/lint/rules/ce025_live_verdict_consistency.py +111 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/runner.py +2 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_custom_lint.py +65 -0
- coder_eval-0.8.4/tests/test_early_stop.py +1278 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox.py +43 -2
- {coder_eval-0.8.3 → coder_eval-0.8.4}/uv.lock +6 -4
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-code-review-full.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-code-review-wf.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-code-review.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-create-plan.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-implement-plan.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-review.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-run-analysis.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/commands/coder-eval-task-create.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/shared/axes.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/shared/multi-model-review.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/shared/review-rubric.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/shared/run-layout.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/workflows/cr-axis.js +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.claude/workflows/cr-parent.js +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.env.example +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/CODEOWNERS +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/code_review.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/dependabot.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/claude-pr-review.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/codeql.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/conventional-commits.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/docker-publish.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/pr-checks.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/publish-testpypi.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.github/workflows/release.yml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.gitignore +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.pre-commit-config.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/.python-version +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/CODE_OF_CONDUCT.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/CONTRIBUTING.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/LICENSE +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/Makefile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/NOTICE +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/SECURITY.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docker/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docker/Dockerfile.runtime +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docker/coder_eval_entrypoint.sh +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docker/coder_eval_runtime_entrypoint.sh +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/BYOD.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/CODEX_AGENT_GUIDE.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/DOCKER_ISOLATION.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/IDEAS.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/USER_GUIDE.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/assets/hero.gif +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/01-first-evaluation.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/02-ci-pipeline.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/03-evalboard-local.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/05-comparing-models.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/06-use-docker-isolation.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/docs/tutorials/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/.gitignore +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/col-help.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/collapsible-rail.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/harness-badge.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/scroll-table.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/unit-toggle.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/version-list.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_components/window-selector.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_overview/daily-chart.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_overview/tag-rail.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_overview/turn-budget-chart.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/_overview/window-summary.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/api/download/route.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/api/file/route.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/api/refresh/__tests__/route.test.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/api/refresh/route.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/error.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/globals.css +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/icon.png +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/layout.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/page.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/path-to-ga/page.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/trends/__tests__/trends-view.test.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/trends/actions.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/trends/page.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/trends/trends-view.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/watchlist/__tests__/watchlist-view.test.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/watchlist/page.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/app/watchlist/watchlist-view.tsx +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/next-env.d.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/next.config.mjs +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/package.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/pnpm-lock.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/postcss.config.mjs +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/public/harness/antigravity.png +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/public/harness/claude-code.png +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/public/harness/codex.png +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/public/uipath.png +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/tailwind.config.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/tsconfig.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/vitest.config.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/evalboard/vitest.setup.ts +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/default.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/model-comparison.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/permissions-smoke.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/plugin-comparison.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/prompt-mutations-example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/experiments/smoke_variants.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/osv-scanner.toml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/.gitattributes +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/_logging.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/registry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/agents/watchdog.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/analysis.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/aggregate_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/console.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/evaluate_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/report_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/run_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/run_helpers.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/run_task_internal_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/cli/utils.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/_classification_aggregate.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/agent_judge.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/classification_match.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/commands_efficiency.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/file_check.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/file_contains.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/file_exists.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/file_matches_regex.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/json_check.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/llm_judge.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/reference_comparison.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/run_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/criteria/uipath_eval.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/budget.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/categories.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/categorization.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/executor.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/judge.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/retry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/errors/timeout.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/checker.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_anthropic.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_bedrock.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_context.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_persistence.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/judge_usage.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/sub_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/summaries.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/evaluation/verdict_tool.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/formatting.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/isolation/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/isolation/docker_runner.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/logging_config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/agent_config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/container_paths.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/enums.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/experiment.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/judge.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/judge_defaults.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/merge_strategy.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/mutations.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/routing.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/sandbox.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/tasks.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/models/templates.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/batch.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/config_merge.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/evaluation.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/overrides.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/orchestration/task_loader.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/path_utils.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/plugins.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/pricing.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/py.typed +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/reports_stats.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/resources/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/resources/default_ignore_patterns.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/resources/tags.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/ast_similarity.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/complexity.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/quality.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/signature_similarity.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/similarity.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/scoring/token_similarity.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/simulation/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/simulation/termination.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/simulation/user_simulator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/callbacks.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/collector.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/renderers.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/streaming/wire.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/src/coder_eval/utils.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agentless_smoke_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/antigravity_hello_world.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/antigravity_hello_world_docker.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/claude_hello_world.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/claude_hello_world_docker.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/claude_parallel_single_gen.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/claude_subagent_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_disallowed_tools_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_hello_world.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_parallel_commands.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_parallel_single_gen.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_skills_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_string_utils.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/codex_subagent_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/subagent_bash_long_input.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/agents/subagent_merge_sort.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/byod_smoke_test.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dataset_example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/datasets/sentiment.jsonl +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/dockerfile_build_example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/environment/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/environment/Dockerfile.workdir +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/environment/input.txt +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/working_dir_auto_example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/dockerfile_build_example/working_dir_concrete_example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/fibonacci_with_template.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/hello_date.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/inline_starter_example.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/internal/session_resumption.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_smoke.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_template_dir/mock-cli-bins/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/echo_args +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/fixtures/config.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_template_dir/mock-cli-bins/mocks/say_hello +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/mock_path_dirs_template_dir/task.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/python_cli_simulated_judged/echo_simulated_judged.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/3d-scan-calc.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/environment/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/environment/material_density_table.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/environment/scan_data.stl +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/verifier/test.sh +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/3d-scan-calc/verifier/test_outputs.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/court-form-filling/court-form-filling.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/court-form-filling/environment/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/court-form-filling/environment/sc100-blank.pdf +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/court-form-filling/verifier/test.sh +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/court-form-filling/verifier/test_outputs.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/dialogue-parser/dialogue-parser.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/dialogue-parser/environment/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/dialogue-parser/environment/script.txt +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/dialogue-parser/verifier/test.sh +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/samples/skillsbench/dialogue-parser/verifier/test_outputs.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/sentiment_classification.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_agent_judge.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_budget_exceeded.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_cost_budget_exceeded.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_llm_judge.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_negative_path.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_task_timeout.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/smoke_variants.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/test_sandbox.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tasks/token_check.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/templates/byod_smoke_test/Dockerfile +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/templates/fibonacci-starter/README.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/templates/fibonacci-starter/src/main.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/templates/fibonacci-starter/tests/test_main.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/_scrub.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/claude_fixtures.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/codex_fixtures.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_a_single_text_turn.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_b_tool_use_result.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_c_multi_emission_delta.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_d_subagent_terminal.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_e_model_usage_and_backfill.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_f_orphaned_tool.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_g_crash_format_placeholder.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_h1_timeout_process_error.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_h2_process_error_crash.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/claude_i_in_loop_deadline_break.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_a_agent_message_only.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_b_command_execution.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_c_reasoning_placeholder.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_d_cross_flush_is_error.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_e_orphan_tool.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_f_collab_fallback.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_g_items_rebuild.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/golden_streams/expected/codex_h_no_turn_completed_crash.json +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/_snapshot.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/experiment_2variant.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/experiment_3variant.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/experiment_replicates.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/run_full.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_fixtures/report_snapshots/run_minimal.md +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/_path_helpers.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/conftest.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/byoa_demo_plugin/byoa_demo.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/byoa_demo_plugin/pyproject.toml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/mock_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/tasks/test_task_multiple_criteria.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/tasks/test_task_pass.yaml +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/fixtures/text_stub_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/__init__.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/base.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce014_merge_strategy_declared.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce015_create_subprocess_limit.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce016_no_computed_tokenusage_kwargs.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce017_models_lazy_agent_imports.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce018_no_final_status_name_denylist.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce019_telemetry_non_fatal.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce020_no_sdk_typed_base_agent_fields.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce021_guarded_evaluationresult_parse.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce022_dialog_loop_statement_cap.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce023_no_proxy_shim_import.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/ce024_discriminated_unions.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_agent_timing_access.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_blocking_io_in_async.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_cli_imports_in_core.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_silent_except.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_submodule_model_imports.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_top_level_run_limits_access.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_transcript_regex_in_eval.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/no_type_name_string_dispatch.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/open_explicit_encoding.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/read_text_explicit_encoding.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/register_criterion_required.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/subprocess_run_explicit_encoding.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/rules/yaml_models_forbid_extras.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/lint/violation.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_config_no_timing_fields.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_config_optional_type.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_config_registry_dispatch.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_config_sdk_decoupling.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_golden_master.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_judge_criterion.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_telemetry_advanced.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agent_timeout.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_agentless.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_aggregate.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_antigravity_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_byoa_plugin.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_byoa_plugin_live.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_byod_feature.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_checker_logging.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_classification_match.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_claude_settings_enforcement_live.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cleanup_preservation_guard.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_backend_flag.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_empty_glob.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_sdk_options.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_set_overrides.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_cli_type_flag.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_code_review_bugs.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_codex_agent.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_codex_agent_live.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_codex_agent_unit.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_codex_token_mapping.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_command_executed.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_command_statistics.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_command_telemetry_result_data.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_commands_efficiency.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_config_lineage.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_config_merge_engine.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_config_precedence.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_continuous_scoring.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_criterion_result_round_trip.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_dataset_expansion.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_debug_logging.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_build_failure.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_runner_container_death.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_runner_mounts.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_runner_stream_limit.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_wildcard_env.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_docker_workdir_live.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_driver_resolver.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_error_handling.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_evaluate_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_evaluator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_event_collector.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_cli.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_loader.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_reports.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_resolver.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_experiment_runner.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_file_check.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_file_contains_scoring.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_formatting.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_git_clone_failure.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_heartbeat_watchdog.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_ignore_patterns_negation.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_image_from_dockerfiles.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_integration.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_json_check.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_anthropic.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_bedrock.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_burn_in_live.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_context_builder.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_judge_persistence.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_lint_no_top_level_run_limits.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_lint_runner.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_llm_judge_criterion.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_log_tail_buffer.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_logging.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_logging_isolation.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_merge_characterization.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_merge_strategy_annotations.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_merge_unification.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_mutations.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_new_criteria.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_node_env_config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_optional_dependencies.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_orchestrator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_orchestrator_error_log_tail.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_orchestrator_telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_overrides_engine.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_parallel.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_path_utils.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_plan_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_plugin_processing.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_plugins.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_post_run.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_pr_review_workflow.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_pre_run.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_preservation_mode.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_pricing_registry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reference_comparison_scoring.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reference_evaluator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reference_missing_file.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reference_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reference_orchestrator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_registry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_replicate_stats.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_report_command.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reports.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reports_experiment.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reports_html.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_reports_stats.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_resolve_task_files.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_resume.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_retry_logic_comprehensive.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_routing.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_run_command_stdout.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_run_limits_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_run_limits_orchestrator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_run_limits_resolver.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_runtime_tool_versions.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox_layer_builder.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox_optional.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox_security.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox_symlink_preservation.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sandbox_templates.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_scorers.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_scoring_quality.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sdk_option_classification.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_simulation_config.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_simulation_integration.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_simulation_termination.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_simulation_trials.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_skill_triggered.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_agent_integration.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_batch.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_callbacks.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_cli.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_events.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_orchestrator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_renderers.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_streaming_wire.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_sub_agent_runner.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_success_criterion_union.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_suite_rollup.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_summaries.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_tags.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_task_definition_unknown_fields.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_telemetry.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_template_env_expansion.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_threshold_enforcement.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_timeout_batch.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_timeout_categorization.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_timeout_exceptions.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_timeout_models.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_timeout_orchestrator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_token_usage.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_uipath_eval.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_user_simulator.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_utils.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_utterance_extraction.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_variant_prompt_file.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_verdict_tool.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_watchdog.py +0 -0
- {coder_eval-0.8.3 → coder_eval-0.8.4}/tests/test_yaml_migration.py +0 -0
|
@@ -5,21 +5,27 @@ Deferred lint/test guardrails surfaced during reviews. Promote to a `CExxx` rule
|
|
|
5
5
|
|
|
6
6
|
## From code review 260701-1954 (fix-review-top5 run) — deferred to a dedicated guardrail plan
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
> Numbering note: these are *proposed* ids. `CE024` (discriminated-unions) and
|
|
9
|
+
> `CE025` (live-verdict consistency) have since been **implemented** for other
|
|
10
|
+
> rules, so the candidates below were renumbered to the next free ids. Always
|
|
11
|
+
> claim the next unused number in `tests/lint/rules/` — the id-uniqueness assert
|
|
12
|
+
> in `tests/lint/runner.py` is the source of truth.
|
|
13
|
+
|
|
14
|
+
- **CE026** — workflow-YAML rule: forbid any `uses:` step pinned to a floating ref
|
|
9
15
|
(`@v3`, `@main`) rather than a 40-hex commit SHA. Would have caught
|
|
10
16
|
`mxschmitt/action-tmate@v3` (fixed manually in this run). >30 min: needs a
|
|
11
17
|
non-Python file-walk branch in `tests/lint/runner.py`.
|
|
12
|
-
- **
|
|
18
|
+
- **CE027** — retired-token grep gate: fail when a removed-subsystem token
|
|
13
19
|
(`LLMGW_`, `API_BACKEND=proxy`, `uipath_llmgw_client`) reappears outside an
|
|
14
20
|
allowlist across docs/config/src. Would have caught the LLM-Gateway residue
|
|
15
21
|
swept in this run. >30 min: needs an allowlist + repo-wide text scan.
|
|
16
|
-
- **
|
|
22
|
+
- **CE028** — assert the Makefile `lint:` help does not hardcode a stale `CE0NN`
|
|
17
23
|
upper bound (use `CE001+`). Would have caught the `CE001–CE005` drift fixed here.
|
|
18
24
|
- **docs-vs-harness smoke test** — execute the CI tutorial's `coder-eval run`
|
|
19
25
|
command against a NoOp task and assert the produced tree matches the documented
|
|
20
26
|
globs. Would have caught the `--run-dir runs` layout bug. Not statically
|
|
21
27
|
reachable (needs a live run).
|
|
22
|
-
- [ ] CE-rule: `type: Literal[...]` fields on models in `coder_eval/models/` must declare their tag default (`type: Literal["x"] = "x"`) — a member without the default degrades `validate_registry` diagnostics (PydanticUndefined in expected_types) and breaks direct construction. Nothing guards it today; needs a rule-design call (second violation class inside CE024 vs. a new
|
|
28
|
+
- [ ] CE-rule: `type: Literal[...]` fields on models in `coder_eval/models/` must declare their tag default (`type: Literal["x"] = "x"`) — a member without the default degrades `validate_registry` diagnostics (PydanticUndefined in expected_types) and breaks direct construction. Nothing guards it today; needs a rule-design call (second violation class inside CE024 vs. a new CExxx at the next free id), and the failure is already double-caught by the MINIMAL_PAYLOADS parity test + direct-construction tests — caught in the 2026-07-03 top5-review-fixes run (Phase 1 quality review).
|
|
23
29
|
|
|
24
30
|
## From 2026-07-03 open-source docs cleanup
|
|
25
31
|
|
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v0.8.4 (2026-07-13)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **deps**: Upgrade click to 8.4.2 to resolve PYSEC-2026-2132
|
|
10
|
+
([#19](https://github.com/UiPath/coder_eval/pull/19),
|
|
11
|
+
[`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
|
|
12
|
+
|
|
13
|
+
- **deps**: Upgrade click to 8.4.2 to resolve PYSEC-2026-2132
|
|
14
|
+
([#20](https://github.com/UiPath/coder_eval/pull/20),
|
|
15
|
+
[`bba8645`](https://github.com/UiPath/coder_eval/commit/bba8645fc3f6c7b6e9784af496641ac0eaf8bede))
|
|
16
|
+
|
|
17
|
+
- **evalboard**: Address search-box code review comments
|
|
18
|
+
([#13](https://github.com/UiPath/coder_eval/pull/13),
|
|
19
|
+
[`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
|
|
20
|
+
|
|
21
|
+
- **evalboard**: Fix search bar clear issue ([#13](https://github.com/UiPath/coder_eval/pull/13),
|
|
22
|
+
[`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
|
|
23
|
+
|
|
24
|
+
- **evalboard**: Prevent search bar from resetting mid-type
|
|
25
|
+
([#13](https://github.com/UiPath/coder_eval/pull/13),
|
|
26
|
+
[`382d80d`](https://github.com/UiPath/coder_eval/commit/382d80d4a84da39327b0196c97c01a367f094c0e))
|
|
27
|
+
|
|
28
|
+
- **sandbox**: Exclude home-dir dotfiles from capture_to artifacts
|
|
29
|
+
([#19](https://github.com/UiPath/coder_eval/pull/19),
|
|
30
|
+
[`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
|
|
31
|
+
|
|
32
|
+
- **sandbox**: Extend capture_to denylist with credential stores
|
|
33
|
+
([#19](https://github.com/UiPath/coder_eval/pull/19),
|
|
34
|
+
[`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
|
|
35
|
+
|
|
36
|
+
### Code Style
|
|
37
|
+
|
|
38
|
+
- Fix ruff formatting in _WORKSPACE_CAPTURE_IGNORE
|
|
39
|
+
([#19](https://github.com/UiPath/coder_eval/pull/19),
|
|
40
|
+
[`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
|
|
41
|
+
|
|
42
|
+
### Documentation
|
|
43
|
+
|
|
44
|
+
- **readme**: Clarify framing before hero gif ([#16](https://github.com/UiPath/coder_eval/pull/16),
|
|
45
|
+
[`b7dee1c`](https://github.com/UiPath/coder_eval/commit/b7dee1c0616d9a98dc98432ca066c1a8c9264ef4))
|
|
46
|
+
|
|
47
|
+
- **readme**: Reframe title toward agents & their skills
|
|
48
|
+
([#16](https://github.com/UiPath/coder_eval/pull/16),
|
|
49
|
+
[`b7dee1c`](https://github.com/UiPath/coder_eval/commit/b7dee1c0616d9a98dc98432ca066c1a8c9264ef4))
|
|
50
|
+
|
|
51
|
+
### Features
|
|
52
|
+
|
|
53
|
+
- **early-stop**: Opt-in early stop once armed criteria are decided
|
|
54
|
+
([#14](https://github.com/UiPath/coder_eval/pull/14),
|
|
55
|
+
[`b0c1ade`](https://github.com/UiPath/coder_eval/commit/b0c1ade364119573f172e4d64ee3fff0a387db32))
|
|
56
|
+
|
|
57
|
+
### Testing
|
|
58
|
+
|
|
59
|
+
- **sandbox**: Cover home-dir dotfile exclusion in capture_to
|
|
60
|
+
([#19](https://github.com/UiPath/coder_eval/pull/19),
|
|
61
|
+
[`a240d4e`](https://github.com/UiPath/coder_eval/commit/a240d4e2f8b970665743d0dc3d212c6c8e8a30ac))
|
|
62
|
+
|
|
63
|
+
|
|
5
64
|
## v0.8.3 (2026-07-09)
|
|
6
65
|
|
|
7
66
|
### Bug Fixes
|
|
@@ -36,7 +36,7 @@ coder_eval/
|
|
|
36
36
|
│ ├── experiment.py # ExperimentDefinition, ExperimentVariant, ResolvedTask, result models
|
|
37
37
|
│ ├── judge_defaults.py # DEFAULT_JUDGE_MODEL constant (cycle-free leaf)
|
|
38
38
|
│ ├── mutations.py # PromptMutation variants (prefix/suffix/replace/template/rephrase)
|
|
39
|
-
│ ├── results.py # CriterionResult (+ ClassificationCriterionResult), TurnRecord, EvaluationResult, CriterionAggregate, ThresholdCheck, SuiteRollup
|
|
39
|
+
│ ├── results.py # CriterionResult (+ ClassificationCriterionResult), TurnRecord, EvaluationResult, EarlyStopInfo/EarlyStopReason, CriterionAggregate, ThresholdCheck, SuiteRollup
|
|
40
40
|
│ ├── routing.py # ApiRoute (DirectRoute/BedrockRoute)
|
|
41
41
|
│ ├── sandbox.py # SandboxConfig, ResourceLimits
|
|
42
42
|
│ ├── tasks.py # TaskDefinition, AgentConfig, Dataset (dataset fan-out + sample)
|
|
@@ -79,6 +79,7 @@ coder_eval/
|
|
|
79
79
|
├── orchestration/ # Batch execution utilities
|
|
80
80
|
│ ├── batch.py # Parallel task execution (run_batch + run_batch_resolved)
|
|
81
81
|
│ ├── config.py # Batch run configuration
|
|
82
|
+
│ ├── early_stop.py # validate_early_stop guardrails + EarlyStopWatcher (armed live-verdict observer)
|
|
82
83
|
│ ├── evaluation.py # Evaluation helpers
|
|
83
84
|
│ ├── experiment.py # ExperimentRunner, resolve_task_for_variant, load_experiment
|
|
84
85
|
│ └── task_loader.py # YAML task loading
|
|
@@ -138,6 +139,7 @@ templates/ # Sandbox template directories
|
|
|
138
139
|
- **Reconciliation message (stream self-reconciles to the turn total)**: The per-message stream consistently under-reports the authoritative turn total — a fixed prompt slice (~512 input tokens on Claude) is billed on no SDK-emitted message, and sub-agent input/cache only partially bubbles up. So `EventCollector.build_turn_record` appends one synthetic `ReconciliationMessage` (`role="reconciliation"`, in the `TranscriptMessage` union) per turn, carrying the per-bucket residual = `token_usage` − Σ(assistant message buckets). The invariant: **summing the four token buckets across `TurnRecord.messages` (assistant + reconciliation) equals `token_usage` exactly**, for both Claude and Codex (Codex's stream is already complete after `_recover_subagent_tool_calls`, so its residual is usually 0 and no entry is emitted). This is what lets the evalboard SUM the message stream as the source of truth instead of reading a separate aggregate ("agent tokens"): `selectTokenTotals` returns the stream sum whenever a reconciliation entry is present, and the timeline renders it as its own row. It is agent-agnostic (booked at the single `EventCollector` seam), carries no cost (cost stays on `token_usage`), and is excluded from generation/turn counts and the cost simulator. The Python `token_usage`/`total_token_usage` aggregate is unchanged and still authoritative for budget/judges/reports.
|
|
139
140
|
- **sandbox isolation**: Tasks that don't need MCP servers should set `setting_sources: []` in their `agent:` block to isolate the sandbox from the host project's CLAUDE.md and settings. Without this, the host project's CLAUDE.md (often 20 KB+) is injected into every API call, inflating cache-creation tokens and cost significantly.
|
|
140
141
|
- **Run-time caps (non-criterion enforcement)**: `TaskDefinition.run_limits` (`RunLimits` model) is the single namespace for all run-time caps — `max_turns` / `task_timeout` / `turn_timeout` (structural) and `max_input_tokens` / `max_output_tokens` / `max_total_tokens` / `max_usd` (cumulative budget). Token/USD breaches abort with `FinalStatus.TOKEN_BUDGET_EXCEEDED` or `COST_BUDGET_EXCEEDED` (both `category == "failed"`). Structural caps are set from the CLI via `-D run_limits.max_turns=…` / `-D run_limits.task_timeout=…` / `-D run_limits.turn_timeout=…` (field-merged into `run_limits`); budget caps via `-D run_limits.max_usd=…` etc. or YAML. Layered config uses field-merge — a variant block overrides individual keys without replacing the task's block.
|
|
142
|
+
- **Early stop on criterion (opt-in)**: `run_limits.stop_early` (default off) ends a single-shot Claude run early once the run's **armed** criteria are decided, so a raised `max_turns` isn't wasted on the smoke flavor. A criterion is armed by `stop_when: pass|fail|decided`; only criteria that can decide from a partial trajectory may arm (they declare a non-empty `live_stop_polarities` ClassVar and override `live_verdict` on `BaseCriterion` — currently `skill_triggered`, `command_executed`; CE025 enforces the two stay consistent). It uses a cooperative `should_stop` seam on the Claude agent's between-messages guard (tool-call granularity, no SIGKILL) driven by `orchestration/early_stop.py::EarlyStopWatcher` (own `EventCollector` + stop rule). Live verdicts only *trigger* the stop; the standard `check_all` on the frozen trajectory is authoritative. An early-stopped run gates on the **armed subset** (`EvaluationResult.armed_criteria_passed`); a completed run gates on the full set. Every unsupported use (non-observable criterion, non-Claude agent, wrong polarity, no armed criterion, simulation mode) is an error at resolution (plan *and* run), and a runtime verdict bug **fails open** to a full run. Surfaces: `EarlyStopInfo` (reason + deciding criterion + when), report notes/badges, `stopped_early` run.json rows, and `EarlyStopped`/`EarlyStopReason` telemetry dims. Defaults off ⇒ behavior byte-for-behavior unchanged.
|
|
141
143
|
|
|
142
144
|
## Success Criteria (14 types)
|
|
143
145
|
|
|
@@ -158,7 +160,7 @@ templates/ # Sandbox template directories
|
|
|
158
160
|
| `llm_judge` | Continuous | LLM grades artifacts + optional trajectory + optional reference; routes through the run's backend (Bedrock / Anthropic) |
|
|
159
161
|
| `agent_judge` | Continuous | Spawns a Claude Code SDK agent in an isolated sandbox copy; judge uses tools (Bash/Read/Grep/…) to investigate and returns a JSON verdict. Expensive; runs with evaluator credentials — see SECURITY note in the criterion docstring. |
|
|
160
162
|
|
|
161
|
-
All criteria support `weight` (default 1.0) and `pass_threshold` (default 0.9). On dataset-backed tasks, criteria may also set `suite_thresholds: {metric: min_value}` — the suite gate passes iff every listed metric (from the criterion's `aggregate()` output) meets its minimum.
|
|
163
|
+
All criteria support `weight` (default 1.0) and `pass_threshold` (default 0.9), plus `stop_when` (`pass`/`fail`/`decided`, default `null`) which arms the criterion for early stop when `run_limits.stop_early` is set (observable criteria only). On dataset-backed tasks, criteria may also set `suite_thresholds: {metric: min_value}` — the suite gate passes iff every listed metric (from the criterion's `aggregate()` output) meets its minimum.
|
|
162
164
|
|
|
163
165
|
## Evaluation Flow
|
|
164
166
|
|
|
@@ -191,11 +193,11 @@ make format # ruff format
|
|
|
191
193
|
make check # ruff check (lint)
|
|
192
194
|
make typecheck # pyright
|
|
193
195
|
make test # pytest
|
|
194
|
-
make lint # custom architectural lint rules (CE001–
|
|
196
|
+
make lint # custom architectural lint rules (CE001–CE025)
|
|
195
197
|
make verify # All of the above + coverage check (CI equivalent)
|
|
196
198
|
```
|
|
197
199
|
|
|
198
|
-
When fixing a bug, ask: *could a custom lint rule have prevented this?* If the root cause is a mechanically detectable pattern (e.g., "always import from `coder_eval.models`", "never call blocking IO in async"), add a rule to `tests/lint/rules/` following the CE001–
|
|
200
|
+
When fixing a bug, ask: *could a custom lint rule have prevented this?* If the root cause is a mechanically detectable pattern (e.g., "always import from `coder_eval.models`", "never call blocking IO in async"), add a rule to `tests/lint/rules/` following the CE001–CE025 pattern and wire it up in `tests/lint/runner.py`. This turns a one-time fix into permanent enforcement. See `tests/test_custom_lint.py` for how rules are tested.
|
|
199
201
|
|
|
200
202
|
## Configuration
|
|
201
203
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coder-eval
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.4
|
|
4
4
|
Summary: Evaluate, benchmark, and A/B-test AI coding agents (Claude Code, Codex, Gemini/Antigravity) with sandboxed, reproducible YAML task suites.
|
|
5
5
|
Project-URL: Homepage, https://github.com/UiPath/coder_eval
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/coder_eval
|
|
@@ -27,6 +27,7 @@ Requires-Dist: anthropic>=0.86.0
|
|
|
27
27
|
Requires-Dist: anyio>=4.13.0
|
|
28
28
|
Requires-Dist: azure-monitor-opentelemetry-exporter<1.1.0,>=1.0.0b30
|
|
29
29
|
Requires-Dist: claude-agent-sdk>=0.2.82
|
|
30
|
+
Requires-Dist: click>=8.3.3
|
|
30
31
|
Requires-Dist: jmespath>=1.1.0
|
|
31
32
|
Requires-Dist: jsonschema>=4.26.0
|
|
32
33
|
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.30.0
|
|
@@ -59,7 +60,7 @@ Provides-Extra: uipath
|
|
|
59
60
|
Requires-Dist: uipath>=2.10.31; extra == 'uipath'
|
|
60
61
|
Description-Content-Type: text/markdown
|
|
61
62
|
|
|
62
|
-
# coder_eval — evaluate
|
|
63
|
+
# coder_eval — evaluate AI coding agents & their skills
|
|
63
64
|
|
|
64
65
|
[](https://pypi.org/project/coder-eval/)
|
|
65
66
|
[](LICENSE)
|
|
@@ -67,6 +68,11 @@ Description-Content-Type: text/markdown
|
|
|
67
68
|
[](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml)
|
|
68
69
|
[](https://github.com/astral-sh/ruff)
|
|
69
70
|
|
|
71
|
+
A framework for evaluating AI coding agents **and their skills** — built for CLI
|
|
72
|
+
and skill builders — with sandboxing, reproducibility, and data-driven analysis.
|
|
73
|
+
Not an "agentic coding" benchmark: it measures how effective your CLI and skills
|
|
74
|
+
are when used by coding agents.
|
|
75
|
+
|
|
70
76
|
<p align="center">
|
|
71
77
|
<img src="docs/assets/hero.gif" alt="coder_eval running the hello_date task: a sandboxed agent writes and runs a script from a YAML task, then the scored result is browsed in evalboard" width="100%">
|
|
72
78
|
</p>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# coder_eval — evaluate
|
|
1
|
+
# coder_eval — evaluate AI coding agents & their skills
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/coder-eval/)
|
|
4
4
|
[](LICENSE)
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
[](https://github.com/UiPath/coder_eval/actions/workflows/pr-checks.yml)
|
|
7
7
|
[](https://github.com/astral-sh/ruff)
|
|
8
8
|
|
|
9
|
+
A framework for evaluating AI coding agents **and their skills** — built for CLI
|
|
10
|
+
and skill builders — with sandboxing, reproducibility, and data-driven analysis.
|
|
11
|
+
Not an "agentic coding" benchmark: it measures how effective your CLI and skills
|
|
12
|
+
are when used by coding agents.
|
|
13
|
+
|
|
9
14
|
<p align="center">
|
|
10
15
|
<img src="docs/assets/hero.gif" alt="coder_eval running the hello_date task: a sandboxed agent writes and runs a script from a YAML task, then the scored result is browsed in evalboard" width="100%">
|
|
11
16
|
</p>
|
|
@@ -17,6 +17,7 @@ to the orchestrator are involved.
|
|
|
17
17
|
- [Recipe: A/B a Skill](#recipe-ab-a-skill)
|
|
18
18
|
- [Recipe: A/B a Model](#recipe-ab-a-model)
|
|
19
19
|
- [Recipe: A/B a Prompt](#recipe-ab-a-prompt)
|
|
20
|
+
- [Recipe: Smoke vs. e2e Flavors (Early Stop)](#recipe-smoke-vs-e2e-flavors-early-stop)
|
|
20
21
|
- [Replicates (Statistical Power)](#replicates-statistical-power)
|
|
21
22
|
- [Measuring the Difference](#measuring-the-difference)
|
|
22
23
|
- [CLI Reference](#cli-reference)
|
|
@@ -222,6 +223,39 @@ variants:
|
|
|
222
223
|
The full mutation catalog (prefix / suffix / replace / template / rephrase) is
|
|
223
224
|
defined in `coder_eval/models/mutations.py`.
|
|
224
225
|
|
|
226
|
+
## Recipe: Smoke vs. e2e Flavors (Early Stop)
|
|
227
|
+
|
|
228
|
+
Run the **same** task file as both a fast `smoke` flavor and a full `e2e` flavor
|
|
229
|
+
by flipping one boolean per variant — `run_limits.stop_early`. Arm the criteria
|
|
230
|
+
that define "the interesting thing happened" with `stop_when` in the task file;
|
|
231
|
+
the `smoke` variant cuts off as soon as they're decided, while `e2e` runs to
|
|
232
|
+
completion. Because the field merge is per-key, the variant sets only
|
|
233
|
+
`stop_early` without disturbing the task's `max_turns`.
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
experiment_id: early-stop-ab
|
|
237
|
+
description: "Smoke vs. e2e from one file via opt-in early stop"
|
|
238
|
+
|
|
239
|
+
variants:
|
|
240
|
+
- variant_id: e2e
|
|
241
|
+
run_limits:
|
|
242
|
+
stop_early: false # full run to completion (the reference flavor)
|
|
243
|
+
- variant_id: smoke
|
|
244
|
+
run_limits:
|
|
245
|
+
stop_early: true # cut off once the armed criteria are decided
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The task file supplies the arming (`stop_when` on the criteria that gate the
|
|
249
|
+
flavor) and a `max_turns` generous enough for `e2e`; see
|
|
250
|
+
[`stop_early`](TASK_DEFINITION_GUIDE.md#stop_early-opt-in-early-stop). This recipe
|
|
251
|
+
ships as `experiments/early-stop-ab.yaml`.
|
|
252
|
+
|
|
253
|
+
Expect **identical pass/fail verdicts** between the two variants — an
|
|
254
|
+
early-stopped run is gated on the armed subset only, and the non-armed criteria
|
|
255
|
+
become advisory (clearly marked in the report), so the `smoke` flavor can't
|
|
256
|
+
"pass for free" — with the `smoke` variant significantly lower on turns,
|
|
257
|
+
duration, and tokens.
|
|
258
|
+
|
|
225
259
|
## Replicates (Statistical Power)
|
|
226
260
|
|
|
227
261
|
Agents are stochastic — a single run per arm is noise, not signal. Set `repeats`
|
|
@@ -192,6 +192,61 @@ budgets consistently across a suite — the headline % is only comparable when
|
|
|
192
192
|
tasks are measured against realistic, like-for-like targets. Omit it (the
|
|
193
193
|
default) to exclude a task from the metric entirely.
|
|
194
194
|
|
|
195
|
+
### `stop_early` (opt-in early stop)
|
|
196
|
+
|
|
197
|
+
`run_limits.stop_early` (default `false`) ends a single-shot run **early** once
|
|
198
|
+
the run's **armed** criteria are decided — so you can raise `max_turns` for the
|
|
199
|
+
full-run flavor without paying for turns the smoke flavor doesn't need. A
|
|
200
|
+
criterion is *armed* by giving it a `stop_when` (see the criterion-fields table);
|
|
201
|
+
`stop_early` is the master switch that turns arming on for the run.
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
run_limits:
|
|
205
|
+
max_turns: 30
|
|
206
|
+
stop_early: true # opt in; default false leaves behavior unchanged
|
|
207
|
+
success_criteria:
|
|
208
|
+
- type: skill_triggered
|
|
209
|
+
skill_name: date-teller
|
|
210
|
+
expected_skill: date-teller
|
|
211
|
+
stop_when: decided # arm on pass OR definitive fail
|
|
212
|
+
- type: file_exists # not armed → advisory on an early-stopped run
|
|
213
|
+
path: report.md
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Semantics:
|
|
217
|
+
|
|
218
|
+
- **Opt-in, per run.** With `stop_early: false` (the default) the run behaves
|
|
219
|
+
exactly as before — `stop_when` is inert and every criterion gates normally.
|
|
220
|
+
- **Polarity.** `stop_when: pass` stops the moment all armed criteria are decided
|
|
221
|
+
in the pass direction; `stop_when: fail` stops on a definitive wrong-signal
|
|
222
|
+
fail; `stop_when: decided` stops on either. Only criteria that can decide from a
|
|
223
|
+
partial trajectory (currently `skill_triggered`, `command_executed`) may be
|
|
224
|
+
armed — arming any other criterion is a hard error at resolution (plan *and*
|
|
225
|
+
run), never a silent no-op. Decidability can also depend on a criterion's own
|
|
226
|
+
fields: `command_executed` can live-**pass** only with `max_count` unset and
|
|
227
|
+
`min_count > 0`, and live-**fail** only with `max_count` set (which includes
|
|
228
|
+
the `min_count: 0, max_count: 0` "must-NOT-run" form). Arming a polarity the
|
|
229
|
+
configured criterion can never reach (e.g. `stop_when: pass` alongside a
|
|
230
|
+
`max_count`) is likewise a hard error at resolution, not a silent full run.
|
|
231
|
+
- **Verdict.** An early-stopped run is gated on the **armed subset only**; the
|
|
232
|
+
non-armed criteria become **advisory** and are clearly marked (report badge +
|
|
233
|
+
per-criterion note + `stopped_early` row). A run that completes naturally is
|
|
234
|
+
gated on the **full** set, as always. This is what lets one file serve both a
|
|
235
|
+
`smoke` flavor (`stop_early: true`) and an `e2e` flavor (`stop_early: false`)
|
|
236
|
+
with identical verdicts — see [AB_EXPERIMENTS.md](AB_EXPERIMENTS.md).
|
|
237
|
+
- **Fail-safe.** A live-verdict bug **fails open** to a full run (logged loudly) —
|
|
238
|
+
it can never silently disable a criterion or cause a false early stop.
|
|
239
|
+
|
|
240
|
+
Observability (every early-stopped run is flagged everywhere so analysis never
|
|
241
|
+
compares a truncated run against a full one):
|
|
242
|
+
|
|
243
|
+
| Surface | Field / marker |
|
|
244
|
+
|---------|----------------|
|
|
245
|
+
| `run.json` row | `stopped_early`, `early_stop_reason`, `turns_remaining_at_stop` |
|
|
246
|
+
| `run.md` | `> **NOTE:** […] stopped early (<reason>); <= N turn(s) avoided …` |
|
|
247
|
+
| `task.html` | header badge `stopped early (<reason>)` + `advisory — not gated` markers |
|
|
248
|
+
| Telemetry | `EarlyStopped` / `EarlyStopReason` dimensions on `CoderEval.Task.End` |
|
|
249
|
+
|
|
195
250
|
## Sandbox Configuration
|
|
196
251
|
|
|
197
252
|
The `sandbox` block is optional. When omitted, it defaults to `driver: "tempdir"` with standard Python environment.
|
|
@@ -319,6 +374,7 @@ All criteria share these fields:
|
|
|
319
374
|
| `description` | — | Human-readable description (required) |
|
|
320
375
|
| `weight` | 1.0 | Relative importance for weighted score |
|
|
321
376
|
| `pass_threshold` | 0.9 | Minimum score (0.0–1.0) to pass |
|
|
377
|
+
| `stop_when` | `null` | Arms this criterion for early stop (`pass`/`fail`/`decided`); requires `run_limits.stop_early: true` and an observable criterion type (`skill_triggered`, `command_executed`). See [`stop_early`](#stop_early-opt-in-early-stop). |
|
|
322
378
|
|
|
323
379
|
**Scoring types:**
|
|
324
380
|
- **Binary** (1.0 or 0.0): `file_exists`, `run_command`, `file_matches_regex`
|
|
@@ -95,6 +95,7 @@ created are preserved under `runs/latest/<variant>/<task>/<NN>/` (`task.json`,
|
|
|
95
95
|
## Where to go deeper
|
|
96
96
|
|
|
97
97
|
- **All 14 criterion types, weights, thresholds** → [Task Definition Guide](../TASK_DEFINITION_GUIDE.md)
|
|
98
|
+
- **Stop a run early once the key criteria are decided** (opt-in `run_limits.stop_early` + `stop_when` on a criterion) → [Task Definition Guide → `stop_early`](../TASK_DEFINITION_GUIDE.md#stop_early-opt-in-early-stop)
|
|
98
99
|
- **Fan one task out over a dataset of rows** → [Bring Your Own Data](../BYOD.md)
|
|
99
100
|
- **Full CLI & config reference** → [User Guide](../USER_GUIDE.md)
|
|
100
101
|
- **Compare two configurations on this task** → [Tutorial 05](05-comparing-models.md)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { describe, expect, test, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { render, screen, act, fireEvent } from "@testing-library/react";
|
|
3
|
+
|
|
4
|
+
// vi.hoisted ensures these are initialized before vi.mock hoists its factory.
|
|
5
|
+
const { mockReplace, navState } = vi.hoisted(() => ({
|
|
6
|
+
mockReplace: vi.fn(),
|
|
7
|
+
navState: { q: "" as string },
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
vi.mock("next/navigation", () => ({
|
|
11
|
+
useRouter: () => ({ replace: mockReplace }),
|
|
12
|
+
usePathname: () => "/",
|
|
13
|
+
useSearchParams: () => new URLSearchParams(navState.q ? `q=${navState.q}` : ""),
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
const { SearchBox } = await import("../search-box");
|
|
17
|
+
|
|
18
|
+
describe("SearchBox — typing-ahead race condition", () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.useFakeTimers();
|
|
21
|
+
mockReplace.mockClear();
|
|
22
|
+
navState.q = "";
|
|
23
|
+
});
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
vi.useRealTimers();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("preserves in-progress input when a navigation resolves mid-typing", () => {
|
|
29
|
+
// Reproduces the race: user types "foo" → debounce fires → user types
|
|
30
|
+
// more → navigation for "foo" resolves → input must NOT reset to "foo".
|
|
31
|
+
const { rerender } = render(<SearchBox />);
|
|
32
|
+
const input = screen.getByRole("textbox");
|
|
33
|
+
|
|
34
|
+
fireEvent.change(input, { target: { value: "foo" } });
|
|
35
|
+
|
|
36
|
+
// Debounce fires; typingAhead becomes false.
|
|
37
|
+
act(() => { vi.advanceTimersByTime(300); });
|
|
38
|
+
expect(mockReplace).toHaveBeenCalledOnce();
|
|
39
|
+
|
|
40
|
+
// User types more before the navigation resolves.
|
|
41
|
+
fireEvent.change(input, { target: { value: "foobar" } });
|
|
42
|
+
|
|
43
|
+
// Navigation for "foo" resolves — URL now reports "foo".
|
|
44
|
+
navState.q = "foo";
|
|
45
|
+
rerender(<SearchBox />);
|
|
46
|
+
|
|
47
|
+
// typingAhead is true, so the sync effect must NOT overwrite the input.
|
|
48
|
+
expect(input).toHaveValue("foobar");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("syncs from URL when the user is not typing (external navigation)", () => {
|
|
52
|
+
// Back/forward nav or a tag click should still update the input when the
|
|
53
|
+
// user hasn't typed anything since the last URL write.
|
|
54
|
+
const { rerender } = render(<SearchBox />);
|
|
55
|
+
const input = screen.getByRole("textbox");
|
|
56
|
+
|
|
57
|
+
navState.q = "tag:alpha";
|
|
58
|
+
rerender(<SearchBox />);
|
|
59
|
+
|
|
60
|
+
expect(input).toHaveValue("tag:alpha");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("clears the input when the URL is cleared externally", () => {
|
|
64
|
+
navState.q = "foo";
|
|
65
|
+
const { rerender } = render(<SearchBox />);
|
|
66
|
+
const input = screen.getByRole("textbox");
|
|
67
|
+
|
|
68
|
+
expect(input).toHaveValue("foo");
|
|
69
|
+
|
|
70
|
+
navState.q = "";
|
|
71
|
+
rerender(<SearchBox />);
|
|
72
|
+
|
|
73
|
+
expect(input).toHaveValue("");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("clear button does not get repopulated when a stale navigation resolves", () => {
|
|
77
|
+
// The PR's named fix: user clicks × to clear a settled search, then a
|
|
78
|
+
// navigation that had already resolved with the old value re-renders the
|
|
79
|
+
// component — the input must stay empty, not snap back to the old value.
|
|
80
|
+
navState.q = "foo";
|
|
81
|
+
const { rerender } = render(<SearchBox />);
|
|
82
|
+
const input = screen.getByRole("textbox");
|
|
83
|
+
expect(input).toHaveValue("foo");
|
|
84
|
+
|
|
85
|
+
// User clicks ×.
|
|
86
|
+
fireEvent.click(screen.getByRole("button", { name: /clear search/i }));
|
|
87
|
+
expect(input).toHaveValue("");
|
|
88
|
+
|
|
89
|
+
// A stale navigation reports q="foo" — must NOT repopulate the input.
|
|
90
|
+
navState.q = "foo";
|
|
91
|
+
rerender(<SearchBox />);
|
|
92
|
+
|
|
93
|
+
expect(input).toHaveValue("");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("typingAhead latch releases after the debounce fires so later external nav syncs", () => {
|
|
97
|
+
// Guards against a stuck-true latch: after the debounce settles (user
|
|
98
|
+
// stops typing, timer fires, typingAhead → false), a subsequent genuine
|
|
99
|
+
// external navigation must still update the input.
|
|
100
|
+
const { rerender } = render(<SearchBox />);
|
|
101
|
+
const input = screen.getByRole("textbox");
|
|
102
|
+
|
|
103
|
+
fireEvent.change(input, { target: { value: "foo" } });
|
|
104
|
+
|
|
105
|
+
// Let the debounce fire — typingAhead resets to false.
|
|
106
|
+
act(() => { vi.advanceTimersByTime(300); });
|
|
107
|
+
|
|
108
|
+
// Simulate the navigation resolving (URL catches up).
|
|
109
|
+
navState.q = "foo";
|
|
110
|
+
rerender(<SearchBox />);
|
|
111
|
+
expect(input).toHaveValue("foo");
|
|
112
|
+
|
|
113
|
+
// Now a genuine external navigation changes q (e.g. browser Back).
|
|
114
|
+
navState.q = "bar";
|
|
115
|
+
rerender(<SearchBox />);
|
|
116
|
+
|
|
117
|
+
// typingAhead is false, so the sync must apply.
|
|
118
|
+
expect(input).toHaveValue("bar");
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4
|
-
import { useEffect, useState } from "react";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
5
|
|
|
6
6
|
const Q_DEBOUNCE_MS = 300;
|
|
7
7
|
|
|
@@ -18,18 +18,31 @@ export function SearchBox({
|
|
|
18
18
|
|
|
19
19
|
const urlQ = searchParams.get("q") ?? "";
|
|
20
20
|
const [q, setQ] = useState(urlQ);
|
|
21
|
+
// Invariant: true iff local input is ahead of the last URL write.
|
|
22
|
+
// Written in three places by the debounce effect (cleared on catch-up at
|
|
23
|
+
// the early-return, set when a new timer arms, cleared when the timer
|
|
24
|
+
// fires). Read by the sync effect to decide whether to accept a URL change.
|
|
25
|
+
const typingAhead = useRef(false);
|
|
21
26
|
|
|
22
27
|
// Sync local state when the URL changes externally (back/forward, link
|
|
23
|
-
// clicks).
|
|
24
|
-
//
|
|
28
|
+
// clicks). Skipped while the user is ahead of the URL to avoid clobbering
|
|
29
|
+
// in-progress input with a stale value from a just-resolved navigation.
|
|
30
|
+
// Note: external q changes that arrive during an active debounce window are
|
|
31
|
+
// intentionally deferred — the user's in-progress typing takes priority.
|
|
25
32
|
useEffect(() => {
|
|
33
|
+
if (typingAhead.current) return;
|
|
26
34
|
setQ((prev) => (prev.trim() === urlQ ? prev : urlQ));
|
|
27
35
|
}, [urlQ]);
|
|
28
36
|
|
|
29
37
|
useEffect(() => {
|
|
30
38
|
const trimmed = q.trim();
|
|
31
|
-
if (trimmed === urlQ)
|
|
39
|
+
if (trimmed === urlQ) {
|
|
40
|
+
typingAhead.current = false;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
typingAhead.current = true;
|
|
32
44
|
const timer = setTimeout(() => {
|
|
45
|
+
typingAhead.current = false;
|
|
33
46
|
// Read the live URL at fire time so a concurrent write (e.g. a
|
|
34
47
|
// tag click that landed during the debounce) isn't clobbered.
|
|
35
48
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -40,6 +53,9 @@ export function SearchBox({
|
|
|
40
53
|
scroll: false,
|
|
41
54
|
});
|
|
42
55
|
}, Q_DEBOUNCE_MS);
|
|
56
|
+
// Don't reset typingAhead in cleanup — cleanup fires on any dep change
|
|
57
|
+
// (q, urlQ, pathname, router). The effect body re-run re-establishes
|
|
58
|
+
// the correct value: false on catch-up, true when a new timer arms.
|
|
43
59
|
return () => clearTimeout(timer);
|
|
44
60
|
}, [q, urlQ, pathname, router]);
|
|
45
61
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
experiment_id: early-stop-ab
|
|
2
|
+
description: |
|
|
3
|
+
Smoke vs. e2e flavors from ONE task file via opt-in early-stop. Both variants
|
|
4
|
+
share the same tasks, criteria, and max_turns; they differ only in the
|
|
5
|
+
run_limits.stop_early boolean (field-merged, so neither replaces the task's
|
|
6
|
+
run_limits block). The task's armed criteria (those carrying `stop_when`)
|
|
7
|
+
decide when the `smoke` variant cuts off — as soon as the designated criteria
|
|
8
|
+
are decided — while `e2e` runs every task to completion.
|
|
9
|
+
|
|
10
|
+
Expect identical pass/fail verdicts between the two variants (the armed subset
|
|
11
|
+
gates an early-stopped run; other criteria are advisory and clearly marked),
|
|
12
|
+
with the `smoke` variant significantly lower on turns, duration, and tokens.
|
|
13
|
+
|
|
14
|
+
variants:
|
|
15
|
+
- variant_id: e2e
|
|
16
|
+
description: "Full run to completion — no early stop (the reference flavor)."
|
|
17
|
+
run_limits:
|
|
18
|
+
stop_early: false
|
|
19
|
+
|
|
20
|
+
- variant_id: smoke
|
|
21
|
+
description: "Opt-in early stop — cut off once the armed criteria are decided."
|
|
22
|
+
run_limits:
|
|
23
|
+
stop_early: true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "coder-eval"
|
|
3
|
-
version = "0.8.
|
|
3
|
+
version = "0.8.4"
|
|
4
4
|
description = "Evaluate, benchmark, and A/B-test AI coding agents (Claude Code, Codex, Gemini/Antigravity) with sandboxed, reproducible YAML task suites."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -30,6 +30,7 @@ dependencies = [
|
|
|
30
30
|
"pydantic-settings>=2.14.2",
|
|
31
31
|
"pyyaml>=6.0.3",
|
|
32
32
|
"typer>=0.24.1",
|
|
33
|
+
"click>=8.3.3",
|
|
33
34
|
"rich>=14.3.3",
|
|
34
35
|
"python-dotenv>=1.2.2",
|
|
35
36
|
"anthropic>=0.86.0",
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
|
-
from
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from typing import Any, ClassVar, NoReturn, Protocol
|
|
9
10
|
|
|
10
11
|
from .errors import AgentCrashError, TurnTimeoutError
|
|
11
12
|
from .errors.agent import format_timeout_reason, truncate_crash_message
|
|
@@ -71,6 +72,13 @@ class Agent[ConfigT: BaseAgentConfig](ABC):
|
|
|
71
72
|
_iteration: int = 0
|
|
72
73
|
_iteration_was_incremented: bool = False
|
|
73
74
|
|
|
75
|
+
# Capability flag: whether this agent honors the cooperative ``should_stop``
|
|
76
|
+
# interrupt threaded through ``communicate()`` (early-stop-on-criterion).
|
|
77
|
+
# Default False — arming early-stop on an agent that does not set this True
|
|
78
|
+
# is rejected at resolution time. Concrete agents that check ``should_stop``
|
|
79
|
+
# between messages override it to True.
|
|
80
|
+
supports_cooperative_stop: ClassVar[bool] = False
|
|
81
|
+
|
|
74
82
|
def _begin_turn(self) -> None:
|
|
75
83
|
"""Mark the start of a ``communicate()`` turn: reset the pending slot and
|
|
76
84
|
bump the iteration counter so a mid-turn failure can be rolled back.
|
|
@@ -183,6 +191,7 @@ class Agent[ConfigT: BaseAgentConfig](ABC):
|
|
|
183
191
|
stream_callback: StreamCallback | None = None,
|
|
184
192
|
timeout: float | None = None,
|
|
185
193
|
max_turns: int | None = None,
|
|
194
|
+
should_stop: Callable[[], bool] | None = None,
|
|
186
195
|
) -> TurnRecord:
|
|
187
196
|
"""Send a message to the agent and receive its response.
|
|
188
197
|
|
|
@@ -198,6 +207,15 @@ class Agent[ConfigT: BaseAgentConfig](ABC):
|
|
|
198
207
|
``communicate()`` call. When the agent would exceed it, the
|
|
199
208
|
returned ``TurnRecord`` has ``max_turns_exhausted=True``.
|
|
200
209
|
None defers to the underlying SDK default.
|
|
210
|
+
should_stop: Cooperative early-stop poll for early-stop-on-criterion.
|
|
211
|
+
When provided, an implementation that supports cooperative
|
|
212
|
+
stopping (``supports_cooperative_stop=True``) should call it at
|
|
213
|
+
each safe message boundary and, when it returns True, stop
|
|
214
|
+
pulling further work and finalize the turn cleanly
|
|
215
|
+
(``crashed=False``, no raise). ``None`` (default) preserves the
|
|
216
|
+
pre-existing behavior exactly. Agents that do not support it
|
|
217
|
+
accept the argument and ignore it (the orchestrator only passes
|
|
218
|
+
it to a capable agent).
|
|
201
219
|
|
|
202
220
|
Returns:
|
|
203
221
|
TurnRecord containing the complete interaction
|
|
@@ -23,7 +23,7 @@ import contextlib
|
|
|
23
23
|
import logging
|
|
24
24
|
import os
|
|
25
25
|
import time
|
|
26
|
-
from collections.abc import AsyncIterator
|
|
26
|
+
from collections.abc import AsyncIterator, Callable
|
|
27
27
|
from contextlib import AsyncExitStack
|
|
28
28
|
from datetime import datetime
|
|
29
29
|
from pathlib import Path
|
|
@@ -409,9 +409,15 @@ class AntigravityAgent(Agent[AntigravityAgentConfig]):
|
|
|
409
409
|
stream_callback: StreamCallback | None = None,
|
|
410
410
|
timeout: float | None = None,
|
|
411
411
|
max_turns: int | None = None,
|
|
412
|
+
should_stop: Callable[[], bool] | None = None,
|
|
412
413
|
) -> TurnRecord:
|
|
413
414
|
"""Send a message to the Antigravity agent and receive its response.
|
|
414
415
|
|
|
416
|
+
``should_stop`` is accepted for ``Agent.communicate`` override
|
|
417
|
+
compatibility and ignored — Antigravity does not support cooperative
|
|
418
|
+
early-stop (``supports_cooperative_stop`` is False), so the orchestrator
|
|
419
|
+
never passes it.
|
|
420
|
+
|
|
415
421
|
Drives one logical turn: ``conversation.send(prompt)`` then iterate
|
|
416
422
|
``receive_steps()`` until the turn goes idle, mapping the Gemini step
|
|
417
423
|
stream onto the standardized event protocol.
|