Repository navigation
133 lines (117 loc) · 5.69 KB
/
Copy pathbenchmark.yml
File metadata and controls
133 lines (117 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
name: Benchmark Contract
on:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: benchmark-contract-${{ github.sha }}
cancel-in-progress: false
jobs:
benchmark:
name: Live MCP benchmark (200/500/200)
runs-on: ubuntu-latest
timeout-minutes: 300
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
# The benchmark server runs under an isolated HOME, so patchright cannot
# see the default ~/.cache/ms-playwright browsers. Pin the browser path
# via env: it flows through wet_server_env's `**os.environ` into the
# spawned server regardless of the isolated home.
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.ms-playwright
steps:
- name: Harden Runner
uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
- name: Checkout exact dispatch SHA
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
- name: Setup Python 3.13
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"
- name: Install dependencies
run: uv sync --group dev
- name: Install headless browser binaries
# The extract suite's `headless` fallback (patchright/chromium) is
# exercised by anti-bot fixture URLs; browser binaries are not part
# of `uv sync` and must be fetched once per job.
run: uv run python -m patchright install chromium
- name: Require a real provider credential
shell: bash
run: |
if [ -z "${OPENROUTER_API_KEY}" ]; then
echo "::error::No real wet provider credential is projected into this run. Sync it from skret; the benchmark never mocks credentials."
exit 1
fi
- name: Resolve benchmark model
shell: bash
env:
VAR_MODEL: ${{ vars.OPENROUTER_MODEL }}
run: |
# Precedence: explicit repo variable first, then the model-sync pin
# file. Both unset stays fail-closed — the benchmark never picks a
# paid model silently.
model="${VAR_MODEL}"
src="vars.OPENROUTER_MODEL"
if [ -z "${model}" ] && [ -f bench/model.txt ]; then
pin="$(tr -d ' \t\r\n' < bench/model.txt)"
if [ -n "${pin}" ]; then
model="${pin}"
src="bench/model.txt"
fi
fi
if [ -z "${model}" ]; then
echo "::error::No benchmark model resolved: vars.OPENROUTER_MODEL is unset and bench/model.txt is empty. The benchmark never picks a paid model silently — set the repo variable or merge a [model-sync] pin PR before dispatching."
exit 1
fi
echo "OPENROUTER_MODEL=${model}" >> "${GITHUB_ENV}"
echo "Resolved benchmark model ${model} from ${src}"
- name: Pre-flight provider spend gate
shell: bash
env:
OPENROUTER_SPEND_CAP_USD: ${{ vars.OPENROUTER_SPEND_CAP_USD }}
run: |
cap="${OPENROUTER_SPEND_CAP_USD:-5}"
if [ -z "${OPENROUTER_SPEND_CAP_USD}" ]; then
echo "NOTE: no vars.OPENROUTER_SPEND_CAP_USD set — using DEFAULT cap ${cap} USD. Set the variable to make the bound an explicit user decision."
fi
resp="$(curl -sf -H "Authorization: Bearer ${OPENROUTER_API_KEY}" https://openrouter.ai/api/v1/credits)" || {
echo "::error::Cannot read OpenRouter credits endpoint — failing closed before spending."
exit 1
}
avail="$(printf '%s' "$resp" | python3 -c 'import json,sys;d=json.load(sys.stdin)["data"];print(round(d["total_credits"]-d["total_usage"],2))')"
echo "Pre-flight: available credit ${avail} USD; run cap ${cap} USD; model ${OPENROUTER_MODEL}"
awk -v a="$avail" -v c="$cap" 'BEGIN{exit (a>=c)?0:1}' || {
echo "::error::Available OpenRouter credit (${avail} USD) is below this run's cap (${cap} USD). Top up or raise vars.OPENROUTER_SPEND_CAP_USD consciously."
exit 1
}
- name: Validate immutable fixtures
run: uv run python tests/search_quality/run_contract.py validate-fixtures
- name: Execute live MCP benchmark
env:
BENCHMARK_ARTIFACT: ${{ runner.temp }}/wet-benchmark-contract.json
run: uv run python tests/search_quality/run_contract.py run --output "${BENCHMARK_ARTIFACT}"
- name: Upload exact-SHA benchmark artifact
# Runs before the gate (and unconditionally) so a failed gate still
# leaves the measured artifact downloadable — diagnosing the next
# failure must not require scraping job logs.
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wet-benchmark-contract-${{ github.sha }}
path: ${{ runner.temp }}/wet-benchmark-contract.json
# ignore, not error: with `if: always()` this step also runs on a
# pre-flight abort (no model / no credit) where no artifact exists —
# a second failure line there would mask the real error.
if-no-files-found: ignore
retention-days: 90
- name: Gate measured artifact against exact SHA
env:
BENCHMARK_ARTIFACT: ${{ runner.temp }}/wet-benchmark-contract.json
GIT_SHA: ${{ github.sha }}
run: uv run python tests/search_quality/run_contract.py gate --artifact "${BENCHMARK_ARTIFACT}" --expected-commit "${GIT_SHA}"