npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eval-harness

v0.2.18

Published

Evaluation harness for configurable runner work packages

Readme

Eval Harness

English documentation

Release: v0.2.18

可配置的 runner work/ 包评测框架。

Eval Harness 不绑定 OpenCode。它是面向 CodeX/Codex CLI、OpenCode、MiMo Code、Claude Code,以及后续更多 runner adapter 的评测平台。runner 抽象和扩展方式见 Runner Adapters

默认配置是通用模板,不绑定具体赛题。你可以通过 config/eval.local.json、 Jenkins 参数,或者生成的 eval.effective.json,把它指向任意题目 Git 仓库 和任意 submitted work Git 仓库。

Jenkins 配置入口:

这个项目把一次性的 runner 运行,变成可复现、可比较、可持续优化的证据闭环。它不只看模型在控制台里“看起来聪明不聪明”,而是检查整个 Agent 系统是否能稳定完成以下工作:

  • 理解动态题目目录和 work/INSTRUCTION.md
  • 修改题目工程中的代码
  • 输出 work/resultwork/reportswork/logs/trace 等交付物
  • 运行验证并记录证据
  • 汇总评分、失败原因和下一轮 Skill/Agent/Instruction 优化建议

工作流

准备干净题目工程
-> 使用 submitted work/INSTRUCTION.md 启动选中的 runner
-> 收集 result、reports、trace、验证日志、代码 diff
-> 确定性评分
-> 给出 ACCEPT / INVESTIGATE / REJECT 决策
-> 生成 recommendations 和 next-action
-> CodeX/Codex 或人工据此优化一个小的 Skill/Agent/Instruction
-> 重新运行并比较

当前仓库提供确定性 runner/evaluator 和 Jenkins pipeline。它会给出下一轮优化输入,但不会自动修改 Skills。

你需要配置什么

框架把评测拆成三个独立输入,方便分享给其他团队或同学:

| 配置项 | Jenkins 参数 | JSON 配置字段 | 说明 | | --- | --- | --- | --- | | 题目仓库 | TASK_REPO_* | source_repo | 原始题目、工程或待修复项目。每个 worker 会复制为 workspace/project。 | | work 仓库 | WORK_REPO_* | submission_repo | 参赛或实验用的 work 包,包含 INSTRUCTION.md、Skills、Agents、helper scripts。 | | 执行矩阵 | MODEL_MATRIXCONCURRENCYTIMEOUT_MINUTES 等 | execution | 控制模型、并发、超时、provider 容错、验证、容器等。 |

每次 Jenkins 构建都会生成实际生效配置:

<external-runs>/eval.effective.json
runs/eval.effective.json

这个文件记录本轮使用的 task/work 仓库 URL、SSH URL、ref、work 目录和 fallback URL,方便复现。

输入契约

为了换题后仍然可用,建议输入满足下面的契约:

| 输入 | 要求 | 说明 | | --- | --- | --- | | Task repository | 一个 Git 仓库,包含需要被 agent 修复的题目工程。 | Git 元数据会尽量保留,用于生成代码 diff;没有 .git 时会 fallback 到文件树比较。 | | Work repository | 一个 Git 仓库,里面有提交的 work 包。 | submission_repo.work_dir 或 Jenkins WORK_REPO_WORK_DIR 必须指向包含 INSTRUCTION.md 的目录。 | | Work assets | Skills、Agents、helper scripts、结果和日志约定。 | 默认支持 work/work/skills/*work/skills/* 两种布局。 | | Result artifacts | work/result/output.mdwork/reports/FINAL_RESULT.jsonwork/reports/FINAL_RESULT.mdwork/reports/final-consistency-report.mdwork/logs/trace/**。 | 缺失会被当成证据缺口评分,而不是被控制台日志掩盖。 |

本地调试时也可以不用 Git 仓库,直接传:

PROJECT_SOURCE=<本地题目目录>
WORK_SOURCE=<本地 work 目录>

共享 Jenkins job 时更推荐使用 Git URL 参数。

当前默认值

  • 题目仓库:config/eval.example.json 中的占位 URL
  • work 仓库:config/eval.example.json 中的占位 URL
  • work 目录:work
  • 默认模型:不写死;使用所选 runner 当前默认,或通过配置/Jenkins MODEL_MATRIX 指定
  • 默认 reasoning variant:high
  • 默认 worker 超时:90 分钟
  • 默认执行契约:runner 会通过 prompt/env 告知 worker AGENT_EVAL_TIMEOUT_MINUTES、预留 AGENT_EVAL_FINALIZE_BEFORE_MINUTES=5 分钟收尾,并要求即使失败或部分完成也写出 work/result/output.mdwork/reports/FINAL_RESULT.jsonwork/reports/FINAL_RESULT.mdwork/reports/final-consistency-report.md
  • 默认 idle timeout:10 分钟无 agent 输出或 artifact 活动
  • 默认 fetch timeout:15 分钟
  • Jenkins 并发:默认 1,可配置 1~5
  • Jenkins runner matrix:逗号或换行分隔的 runner adapter,按 worker 顺序分配;留空则所有 worker 使用 config 中的 agent.type
  • Jenkins 配置文件:EVAL_CONFIG 可留空;会优先用本地 OEVAL_CONFIG,再 fallback 到 config/eval.example.json
  • Jenkins 定时运行:仓库默认不注册 cron;需要时在 Jenkins 环境中自行配置 timer
  • work 版本检查:默认 REQUIRE_WORK_VERSION=true,简单接入时可设为 false

这些只是默认值,不是框架限制。

快速开始

平台无关。推荐 Python 3.10+,真实评分环境已经按 Python 3.12 兼容。外部工具需要在 PATH 或 Jenkins EXTRA_PATHS / OEVAL_EXTRA_PATHS 中可用:

  • git
  • node
  • 选中的 agent CLI:opencodemimocodexclaude
  • agent-inspector
  • mvn 和 Java,启用验证时需要

Ubuntu 评测基线示例:

Ubuntu 24.04.4
Python 3.12
Node v24.13.0
OpenJDK 21
Maven 3.9.11
Maven home: /usr/local/maven3

Linux/macOS:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e .
eval-harness --help

Windows PowerShell:

python -m venv .venv
.\.venv\Scripts\python -m pip install -e .
.\.venv\Scripts\eval-harness --help

NPM 包装入口:

npx eval-harness --help
npx eval-harness runner-presets

npm 包是一个很薄的 Node.js 启动器,会调用包内自带的 Python 源码。 运行机器仍然需要 PATH 中有 Python 3.10+,也可以通过 EVAL_HARNESS_PYTHON 指定 Python 可执行文件。从仓库外运行时,它会 fallback 到 npm 包内置的 config/eval.example.jsonschemas/

不安装包也可以运行:

PYTHONPATH=src python -m eval --help
$env:PYTHONPATH = "src"
python -m eval --help

配置自己的题目仓库和 work 仓库

复制配置文件:

cp config/eval.example.json config/eval.local.json
Copy-Item config/eval.example.json config/eval.local.json

修改 config/eval.local.json

{
  "source_repo": {
    "url": "https://example.com/course/task.git",
    "ssh_url": "[email protected]:course/task.git",
    "ref": "main",
    "fallback_urls": []
  },
  "submission_repo": {
    "url": "https://example.com/team/work.git",
    "ssh_url": "[email protected]:team/work.git",
    "ref": "main",
    "work_dir": "work",
    "fallback_urls": []
  }
}

也可以不修改文件,临时生成 effective config:

PYTHONPATH=src python -m eval write-effective-config \
  --config config/eval.example.json \
  --output /tmp/oeval/eval.effective.json \
  --task-repo-url https://example.com/course/task.git \
  --task-repo-ref main \
  --work-repo-url https://example.com/team/work.git \
  --work-repo-ref main \
  --work-repo-work-dir work

生成后按普通配置使用:

PYTHONPATH=src python -m eval fetch-task --config /tmp/oeval/eval.effective.json --output /tmp/oeval/inputs/task --replace-existing
PYTHONPATH=src python -m eval fetch-work --config /tmp/oeval/eval.effective.json --output /tmp/oeval/inputs/work --replace-existing
PYTHONPATH=src python -m eval prepare --config /tmp/oeval/eval.effective.json --run-id demo-01 --project-source /tmp/oeval/inputs/task --work-source /tmp/oeval/inputs/work --replace-existing

本地运行

准备:

python -m eval prepare --config config/eval.local.json

执行配置的 agent runner:

python -m eval execute --run runs/<run-id>

评分:

python -m eval score --run runs/<run-id>

一条命令跑完整生命周期:

python -m eval run --config config/eval.local.json

并发运行:

python -m eval batch --config config/eval.local.json --count 5 --parallel 5

本地一次性运行 Jenkins 类似流程。该入口会生成有效配置、拉取 task/work 输入、并行执行 worker、汇总批次、导出产物,并可选校验导出的 JSON:

python -m eval run-once `
  --config config/eval.local.json `
  --batch-id local-three-model `
  --count 3 `
  --parallel 3 `
  --prefer-ssh `
  --model agent-inspector/MiniMax-M3 `
  --model agent-inspector/deepseek-v4-pro `
  --model agent-inspector/glm-5.2 `
  --timeout-minutes 90 `
  --idle-timeout-minutes deepseek-v4-pro=30,default=10 `
  --variant high `
  --replace-existing `
  --validate-artifacts

可以用 --task-repo-url--task-repo-ref--work-repo-url--work-repo-ref--work-repo-work-dir 覆盖本轮 task/work 仓库参数,私有配置不用提交到仓库。首次验证流程时可加 --dry-run

短链路真实调度可以使用 --smoke。它会强制 DRY_RUN=falsetimeout=5idle_timeout=2,并关闭 validation、work version 和发布门禁,适合先确认 runner、模型路由和 Agent Inspector 链路:

python -m eval run-once `
  --config config/eval.local.json `
  --smoke `
  --count 3 `
  --parallel 3 `
  --model agent-inspector/MiniMax-M3 `
  --model agent-inspector/deepseek-v4-pro `
  --model agent-inspector/glm-5.2

Agent Runner

当前支持的 agent.type

  • codexcodex-cli:CodeX/Codex CLI runner
  • opencode:OpenCode CLI runner
  • mimocodemimo:MiMo Code runner
  • claudeclaude-code:Claude Code runner

每个 runner 都有自己的默认命令、日志目录、隔离运行时 profile 和 work asset 安装目录。需要覆盖命令时,可使用 execution.agent.commandexecution.<runner>.commandexecution.<runner>_command

查看 runner 默认参数:

python -m eval runner-presets
python -m eval runner-presets --format json
python -m eval runner-version-check --config config/eval.local.json --markdown-output runs/preflight/runner-version-check.md

CodeX/Codex CLI 示例:

{
  "agent": {
    "type": "codex"
  },
  "execution": {
    "codex_command": [
      "{agent_executable}",
      "exec",
      "--json",
      "--skip-git-repo-check",
      "--dangerously-bypass-approvals-and-sandbox",
      "--cd",
      "{workspace}",
      "Read and execute work/INSTRUCTION.md. Work autonomously, do not ask for human input, and write all required result artifacts."
    ]
  }
}

Windows Jenkins 服务账号下,Codex CLI 会先使用 agent.executablecodex.executableexecution.codex_executableexecution.codex.executableOEVAL_CODEX_EXECUTABLE,然后自动发现当前用户的 %LOCALAPPDATA%\OpenAI\Codex\bin\*\codex.exe,最后才回退到 PATH 中的 codex。本机路径建议放在未提交的 local config 或 Jenkins 全局环境变量中,不要写入共享配置。

CodeX/Codex CLI 同样支持通用 --model 覆盖:

python -m eval execute --run runs/<run-id> --model gpt-5

Claude Code 示例:

{
  "agent": {
    "type": "claude-code",
    "executable": "claude"
  },
  "execution": {
    "claude_command": [
      "{agent_executable}",
      "-p",
      "--output-format",
      "stream-json",
      "--verbose",
      "--dangerously-skip-permissions",
      "Read and execute work/INSTRUCTION.md. Work autonomously, do not ask for human input, and write all required result artifacts."
    ]
  }
}

使用 Agent Inspector 路由时,agent-inspector/MiniMax-M3 会传给 Claude Code 为 --model MiniMax-M3;runner 会在隔离 worker 环境中注入 ANTHROPIC_BASE_URLANTHROPIC_API_KEY

Codex CLI 也会去掉 agent-inspector/ 前缀,并会把 agent-inspector/MiniMax M3 这类显示名规范化成 --model MiniMax-M3

使用 agent-inspector/* 模型路由时,先确认 Agent Inspector 已经启动:

agent-inspector
Invoke-RestMethod http://127.0.0.1:25947/api/health

健康检查期望返回 {"status":"ok"}http://127.0.0.1:25947/proxy 是注入给 OpenCode/MiMo 类 runner 的 LLM_BASE_URL,也是注入给 Claude Code 的 ANTHROPIC_BASE_URL,不是浏览器页面;浏览器 UI 使用 http://127.0.0.1:25947/。真实调度成功后,可以在选中 runner 的日志目录里查看,例如 runs/<run-id>/<agent-log-dir>/opencode.log

选中的 agent CLI 不可用时,可以先 dry-run 验证调度:

python -m eval batch --config config/eval.local.json --count 5 --parallel 5 --dry-run

Jenkins 使用

配置参考:

Jenkinsfile 暴露了可配置参数。核心参数:

EVAL_CONFIG=
CONCURRENCY=1
TIMEOUT_MINUTES=90
IDLE_TIMEOUT_MINUTES=10
DRY_RUN=false
SMOKE_MODE=false
ISOLATED_ENV=true
STREAM_OUTPUT=true
CONSOLE_LOG_MODE=important
RUNNER_MATRIX=
MODEL_MATRIX=
REASONING_VARIANT=high
PROVIDER_API_FAILURE_GRACE=5
REQUIRE_WORK_VERSION=true
TASK_REPO_URL=<题目仓库 HTTPS URL>
TASK_REPO_SSH_URL=<题目仓库 SSH URL,可选>
TASK_REPO_REF=main
WORK_REPO_URL=<work 仓库 HTTPS URL>
WORK_REPO_SSH_URL=<work 仓库 SSH URL,可选>
WORK_REPO_REF=main
WORK_REPO_WORK_DIR=work

DeepSeek 这类模型在子代理或子进程阶段可能长时间没有输出,建议只给 DeepSeek worker 放宽 idle timeout,其他模型仍保持默认 10 分钟:

IDLE_TIMEOUT_MINUTES=deepseek-v4-pro=30,default=10

一个 Jenkins 任务也可以同时跑多个 runner adapter。RUNNER_MATRIX 控制每个 worker 使用哪个 runner,MODEL_MATRIX 控制每个 worker 使用哪个模型,二者都按 worker 顺序对齐,数量不足时复用最后一个值:

CONCURRENCY=4
RUNNER_MATRIX=codex,opencode,mimocode,claude
MODEL_MATRIX=agent-inspector/MiniMax-M3,agent-inspector/deepseek-v4-pro,agent-inspector/glm-5.2,agent-inspector/MiniMax-M3
DRY_RUN=false

混合 runner 模式下,task/work 输入仍然只拉取一次;每个 worker 会在 <external-runs>/configs/ 下生成自己的 runner-specific effective config,再进入 prepare/execute/score。

Jenkins 执行时会先生成本轮有效配置:

python -m eval write-effective-config --config <EVAL_CONFIG> --output <external-runs>/eval.effective.json [repo overrides]
python -m eval fetch-task --config <external-runs>/eval.effective.json --output <external-runs>/inputs/task --replace-existing
python -m eval fetch-work --config <external-runs>/eval.effective.json --output <external-runs>/inputs/work --replace-existing

然后每个 worker 进入独立空间:

<external-runs>/<run-id>/
  inputs/task/
  inputs/work/
  workspace/project/
  workspace/work/
  runtime/home/
  runtime/tmp/
  runtime/cache/
  runtime/config/
  runtime/m2-repository/
  control/timeout.json

每个 worker 仍然作为 Jenkins parallel 分支运行,分支名称包含 worker 序号、runner 和模型短名,例如 01 codex MiniMax-M3。分支内部的 config、准备、Inspector create/attach/complete、资产安装、执行和打分会作为日志段打印,不再拆成一堆 Jenkins 子节点:

worker 01 codex MiniMax-M3: effective config
worker 01 codex MiniMax-M3: prepare
worker 01 codex MiniMax-M3: inspector create
worker 01 codex MiniMax-M3: install agent assets
worker 01 codex MiniMax-M3: execute
worker 01 codex MiniMax-M3: inspector attach
worker 01 codex MiniMax-M3: score
worker 01 codex MiniMax-M3: inspector complete

Agent Asset 安装

默认安装规则由 runner adapter 决定。OpenCode 的默认安装规则示例:

work/work/skills/*         -> .opencode/skills
work/work/skills/*.md      -> .opencode/agents
work/work/skills/versions.json -> .opencode/skills
work/skills/*              -> .opencode/skills
work/skills/*.md           -> .opencode/agents

这样可以兼容嵌套布局和扁平布局,且不依赖用户机器上的全局 runner 配置目录。其他 runner 会使用各自的默认目录,例如 MiMo Code 使用 .mimocode/*,Codex CLI 使用 .codex/*,Claude Code 使用 .claude/*

如果需要额外安装目录,可以使用 Jenkins AGENT_ASSET_INSTALLS,目标目录需要匹配当前 runner:

work/commands=>.opencode/command
work/references=>.opencode/references

评分与产物

确定性评分总分 100:

  • artifacts /30:必需结果文件、trace、final marker、报告产物
  • boundary /20:保护路径没有被修改
  • validation /30:验证摘要和 pass 证据
  • final_status /20:最终状态和 finality marker

验证摘要支持两种 helper schema:命令维度的 results[],以及阶段维度的 phases[] 加顶层 status。如果 phases[] 中所有阶段都是 PASS,harness 会把它当作正式的机器可读验证证据;只写在 work/result/output.md 里的成功描述仍然只是弱证据,不能替代 work/logs/trace/validation/**/summary.json

最终报告也会被检查。work/reports/final-consistency-report.md 如果仍然是 helper 自动创建的 placeholder,score 会记录 final-artifact finding,并在 evaluation.json / judge-input.md 中输出 final_report_evidence,不会因为一个 PASS marker 就把它当成完整交付。

每个 run 会输出:

runs/<run-id>/evaluation/evaluation.json
runs/<run-id>/evaluation/changed-files.md
runs/<run-id>/evaluation/judge-input.md
runs/<run-id>/evaluation/recommendations.md
runs/<run-id>/evaluation/next-action.json
runs/<run-id>/evaluation/skill-improvement-input.json
runs/<run-id>/<agent-log-dir>/opencode.log
runs/<run-id>/workspace/work/result/output.md
runs/<run-id>/workspace/work/reports/**

skill-improvement-input.json is the machine-readable input for the next Skill/Agent/helper/Instruction optimization. It includes the primary failure category, failure taxonomy, target candidates, evidence paths, final report evidence, and recommended change scope.

<agent-log-dir> 由当前 runner 决定,例如 opencodemimocodecodexclaude。每个 run 会写入 <agent-log-dir>/sessions.json.md;启用 Agent Inspector 时,如果 agent 日志没有解析出足够 session 信息,平台会尝试从 Inspector /api/logs 回填 evidence 链接。批次 summary.md 和 HTML 报告会包含 Root Cause Digest,集中展示失败原因、诊断文件、Inspector 证据和下一步建议。

批次汇总会输出:

runs/batches/<batch-id>/summary.json
runs/batches/<batch-id>/summary.md
runs/batches/<batch-id>/model-report.json
runs/batches/<batch-id>/model-report.md
runs/batches/<batch-id>/experiment.json
runs/batches/<batch-id>/comparison.json
runs/batches/<batch-id>/comparison.md
runs/history/**
runs/eval.effective.json

校验归档 JSON:

python -m eval validate-artifacts --root runs --batch-id <batch-id> --count <count>

常用运维命令:

python -m eval runner-presets
python -m eval runner-version-check --config config/eval.local.json --markdown-output runs/preflight/runner-version-check.md
python -m eval clean-runs --config config/eval.local.json --keep 10 --dry-run
python -m eval release-notes --from-ref <previous-tag> --to-ref HEAD --output docs/release-notes-draft.md

Provider 与超时容错

框架会尽早识别并分类以下问题:

  • provider/model 配置错误
  • provider 不可达
  • invalid credentials
  • rate limit
  • provider API stream error
  • agent idle timeout
  • worker 总超时

PROVIDER_API_FAILURE_GRACE 默认是 5,表示普通 provider API stream error 可以容忍 5 次再终止。rate limit、鉴权错误、未知模型等 fatal 问题会提前终止,并保留部分产物供分析。

Provider failure 检测现在按 runner 做结构化识别。对于 JSON/JSONL 日志,harness 只扫描明确的错误载体,例如顶层 errorrequest/response/session/turn failed、Claude result.is_error=true 或 error subtype、system API error、level=ERROR/FATAL/CRITICAL、以及明确的 runtime error payload。assistant/model 分析、user tool result、tool-use 事件、Codex command_execution 输出和 agent message 会被忽略,所以业务域里的 401403FORBIDDENUNAUTHORIZED/api/v1errorCode 等内容会被当作任务证据,而不会误判为 provider outage。普通 stderr/stdout 仍会扫描真实 provider token,例如连接失败、无效凭据、rate limit、未知模型和 retry exhaustion。

当 worker 因 idle timeout、总 timeout、provider fail-fast 或手动中断被清理时,runner 会先写入 <agent-log-dir>/process-diagnostics-*.json.md。诊断文件包含进程树、命令行、elapsed/idle 时间、监听的 artifact 路径、最近日志尾部等信息;Jenkins 归档 runs/** 后可以直接查看,用来定位 DeepSeek 这类子代理/子进程静默时到底卡在哪个进程或阶段。

如果 worker 在写完验证日志或修改代码后超时,但没有写完最终产物,score 阶段会先尝试 execution.final_result_recovery_helpers 中的 work helper,并兼容旧版 helper 参数;如果 helper 不存在或不兼容,harness 会内置生成 PARTIALoutput.mdFINAL_RESULT.jsonFINAL_RESULT.md,同时保留失败原因和原始输出备份。这样 Jenkins 仍能 aggregate/export Evidence,但不会把失败验证掩盖成成功。

测试

python -m unittest

可选开发工具:

python -m pip install -e ".[dev]"
python -m pytest
python -m coverage run -m unittest
python -m ruff check .

测试覆盖:

  • clone URL 顺序和 fallback
  • task/work 输入物化
  • agent worker 执行包装
  • provider failure 分类
  • timeout control
  • artifact export
  • schema validation
  • model report 和 batch summary

演进策略

推荐的优化粒度:

  1. runs/batches/<batch-id>/summary.mdmodel-report.md
  2. 找到最小的 Skill、Agent、知识包、helper 或 Instruction 问题
  3. 修改并做版本控制
  4. 重新运行同一 task/work 输入
  5. 通过 comparison.md 和 history 判断是否接受

这个仓库的目标不是让一次模型运行偶然成功,而是让 Agent 系统可以持续进化、可审计、可复盘。