callprobe 0.5.0__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.
- callprobe-0.5.0/.github/ISSUE_TEMPLATE/new-model-run.md +32 -0
- callprobe-0.5.0/.github/ISSUE_TEMPLATE/new-task.md +25 -0
- callprobe-0.5.0/.github/workflows/ci.yml +38 -0
- callprobe-0.5.0/.github/workflows/release.yml +34 -0
- callprobe-0.5.0/.gitignore +8 -0
- callprobe-0.5.0/CHANGELOG.md +48 -0
- callprobe-0.5.0/CONTRIBUTING.md +80 -0
- callprobe-0.5.0/LEADERBOARD.md +22 -0
- callprobe-0.5.0/LICENSE +21 -0
- callprobe-0.5.0/PKG-INFO +515 -0
- callprobe-0.5.0/README.md +485 -0
- callprobe-0.5.0/action.yml +114 -0
- callprobe-0.5.0/examples/ci-policy.yaml +11 -0
- callprobe-0.5.0/pyproject.toml +58 -0
- callprobe-0.5.0/results/archive/qwen3-8b-q4.json +2095 -0
- callprobe-0.5.0/results/command-r7b.json +25588 -0
- callprobe-0.5.0/results/granite3.3-8b.json +25340 -0
- callprobe-0.5.0/results/hermes3-8b.json +25366 -0
- callprobe-0.5.0/results/llama3.1-8b.json +10701 -0
- callprobe-0.5.0/results/llama3.2-3b.json +26304 -0
- callprobe-0.5.0/results/mistral-nemo.json +25011 -0
- callprobe-0.5.0/results/phi4-mini.json +25628 -0
- callprobe-0.5.0/results/qwen2.5-7b.json +24687 -0
- callprobe-0.5.0/results/qwen3-8b.json +9932 -0
- callprobe-0.5.0/results/v0.5.0/README.md +126 -0
- callprobe-0.5.0/results/v0.5.0/qwen2.5-7b-baseline.json +5748 -0
- callprobe-0.5.0/results/v0.5.0/qwen2.5-7b-candidate.json +5748 -0
- callprobe-0.5.0/results/v0.5.0/validation-summary.json +268 -0
- callprobe-0.5.0/scripts/overnight.sh +42 -0
- callprobe-0.5.0/src/callprobe/__init__.py +10 -0
- callprobe-0.5.0/src/callprobe/bootstrap.py +49 -0
- callprobe-0.5.0/src/callprobe/cli.py +346 -0
- callprobe-0.5.0/src/callprobe/client.py +196 -0
- callprobe-0.5.0/src/callprobe/coerce.py +62 -0
- callprobe-0.5.0/src/callprobe/compare.py +95 -0
- callprobe-0.5.0/src/callprobe/gates.py +137 -0
- callprobe-0.5.0/src/callprobe/init.py +101 -0
- callprobe-0.5.0/src/callprobe/loader.py +105 -0
- callprobe-0.5.0/src/callprobe/models.py +164 -0
- callprobe-0.5.0/src/callprobe/report.py +223 -0
- callprobe-0.5.0/src/callprobe/runner.py +188 -0
- callprobe-0.5.0/src/callprobe/scoring.py +248 -0
- callprobe-0.5.0/src/callprobe/suites/core/distractors.yaml +160 -0
- callprobe-0.5.0/src/callprobe/suites/core/suite.yaml +2 -0
- callprobe-0.5.0/src/callprobe/suites/core/tasks.yaml +808 -0
- callprobe-0.5.0/src/callprobe/suites/core/tools.yaml +223 -0
- callprobe-0.5.0/src/callprobe/validate.py +37 -0
- callprobe-0.5.0/tests/test_action.py +51 -0
- callprobe-0.5.0/tests/test_bootstrap.py +53 -0
- callprobe-0.5.0/tests/test_cli.py +114 -0
- callprobe-0.5.0/tests/test_client.py +91 -0
- callprobe-0.5.0/tests/test_compare.py +115 -0
- callprobe-0.5.0/tests/test_gates.py +134 -0
- callprobe-0.5.0/tests/test_init.py +109 -0
- callprobe-0.5.0/tests/test_report.py +93 -0
- callprobe-0.5.0/tests/test_runner.py +162 -0
- callprobe-0.5.0/tests/test_scoring.py +248 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New model run
|
|
3
|
+
about: Report a run against a model not yet on the leaderboard
|
|
4
|
+
title: "[run] "
|
|
5
|
+
labels: run
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Model**
|
|
9
|
+
Name and tag, e.g. `qwen2.5:7b`. Quantization if relevant.
|
|
10
|
+
|
|
11
|
+
**Endpoint**
|
|
12
|
+
Ollama, LM Studio, llama.cpp server, vLLM, or a hosted provider, and the
|
|
13
|
+
`--endpoint` value used.
|
|
14
|
+
|
|
15
|
+
**Command**
|
|
16
|
+
The exact `callprobe run` invocation. The recommended flags are:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
callprobe run --model your-model --pad 0,8,16,24 --repeats 3 \
|
|
20
|
+
--max-tokens 4096 --out results/your-model.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If you used different flags, say why (context window too small for
|
|
24
|
+
`--max-tokens 4096`, fewer repeats to keep the run short, etc).
|
|
25
|
+
|
|
26
|
+
**Results file**
|
|
27
|
+
Attach or link the JSON file written by `--out`. This is what a
|
|
28
|
+
maintainer will run `callprobe leaderboard` on to add the row.
|
|
29
|
+
|
|
30
|
+
**Anything surprising**
|
|
31
|
+
Truncation, errors, a category that fell apart, anything in the failure
|
|
32
|
+
digest worth flagging before it becomes a leaderboard row.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New task
|
|
3
|
+
about: Propose a new task for the core suite
|
|
4
|
+
title: "[task] "
|
|
5
|
+
labels: task
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Category**
|
|
9
|
+
Which of `select`, `abstain`, `args`, `depth`, `sequence`, and why that one.
|
|
10
|
+
|
|
11
|
+
**Bundle**
|
|
12
|
+
Which existing bundle (`support`, `scheduling`, `files`), or a new one.
|
|
13
|
+
If new, what tools does it need?
|
|
14
|
+
|
|
15
|
+
**The scenario**
|
|
16
|
+
The conversation (or a sketch of it) and what a model should do with it.
|
|
17
|
+
|
|
18
|
+
**Why this is worth testing**
|
|
19
|
+
What specifically would this catch that the existing tasks don't? A near
|
|
20
|
+
miss, an argument that's easy to get subtly wrong, a distractor that
|
|
21
|
+
could invalidate an abstain task, etc.
|
|
22
|
+
|
|
23
|
+
**`callprobe validate` output**
|
|
24
|
+
Paste the output if you already have a draft task written. If not, that's
|
|
25
|
+
fine, just flag that it still needs writing and validating.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- run: pip install -e ".[dev]"
|
|
21
|
+
- run: pytest -q
|
|
22
|
+
|
|
23
|
+
wheel-install:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
- run: pip install build
|
|
31
|
+
- run: python -m build --wheel
|
|
32
|
+
- run: python -m venv /tmp/callprobe-wheel-env
|
|
33
|
+
- run: /tmp/callprobe-wheel-env/bin/pip install dist/*.whl
|
|
34
|
+
- name: run from outside the checkout
|
|
35
|
+
working-directory: /tmp
|
|
36
|
+
run: |
|
|
37
|
+
/tmp/callprobe-wheel-env/bin/callprobe --version
|
|
38
|
+
/tmp/callprobe-wheel-env/bin/callprobe validate
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
- run: pip install build
|
|
17
|
+
- run: python -m build
|
|
18
|
+
- uses: actions/upload-artifact@v4
|
|
19
|
+
with:
|
|
20
|
+
name: dist
|
|
21
|
+
path: dist/
|
|
22
|
+
|
|
23
|
+
publish:
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
environment: pypi
|
|
27
|
+
permissions:
|
|
28
|
+
id-token: write
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/download-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
- Scoring version 2 requires exactly one call for call expectations and
|
|
6
|
+
rejects truncated responses, including apparent abstentions. Lenient
|
|
7
|
+
coercion cannot rescue either failure.
|
|
8
|
+
- Preserve all structured calls, IDs, raw arguments, parse errors, and
|
|
9
|
+
finish reasons in result files.
|
|
10
|
+
- Reject incompatible or missing resume files; preserve the original start
|
|
11
|
+
time, retry request errors, and write checkpoints atomically.
|
|
12
|
+
- Add `compare --fail-on-regression`, YAML `--policy`, and JSON comparison
|
|
13
|
+
output. Gates require complete matched coverage and compatible suite and
|
|
14
|
+
scoring provenance. Policies cover critical tasks, overall/category
|
|
15
|
+
minimums, maximum success drops, and request error limits.
|
|
16
|
+
- Fail `run --fail-under` on request errors and incomplete runs. Reject
|
|
17
|
+
mixed scoring versions in leaderboards by default.
|
|
18
|
+
- Add GitHub Action baseline/policy and run-configuration inputs; install
|
|
19
|
+
the selected action revision instead of an unrelated PyPI version.
|
|
20
|
+
- Include two fresh 150-request Qwen 2.5 7B validation runs, an example CI
|
|
21
|
+
policy, and a report of the six false passes prevented per run. Both
|
|
22
|
+
runs scored 78.7% with no matched-case regressions.
|
|
23
|
+
|
|
24
|
+
Older results remain readable for informational comparison. Rerun them
|
|
25
|
+
before resuming or using them as CI baselines with this rubric.
|
|
26
|
+
|
|
27
|
+
## 0.4.0
|
|
28
|
+
|
|
29
|
+
First public release.
|
|
30
|
+
|
|
31
|
+
- Package the default suite inside the wheel, so `pip install callprobe`
|
|
32
|
+
works outside a git checkout. Previously the packaged CLI could not find
|
|
33
|
+
`suites/core` at all.
|
|
34
|
+
- Add `callprobe validate [--suite PATH]`, which checks task expectations
|
|
35
|
+
against tool schemas without needing a model.
|
|
36
|
+
- Add CI: pytest on Python 3.10 through 3.13, plus a wheel-install smoke
|
|
37
|
+
test that would have caught the packaging bug above.
|
|
38
|
+
- Retry request errors (429, 5xx, connection and timeout errors) with
|
|
39
|
+
exponential backoff and jitter instead of scoring them as model failures.
|
|
40
|
+
Configurable with `--retries` (default 3). Reports honor `Retry-After`.
|
|
41
|
+
- Reports now exclude errored requests from every success/selection/schema
|
|
42
|
+
/args rate, and warn when errors exceed 2% of requests. Error counts are
|
|
43
|
+
still shown.
|
|
44
|
+
- Stop tracking log files and the overnight sweep log in git.
|
|
45
|
+
- Add `__version__` and `callprobe --version`.
|
|
46
|
+
- `--api-key` falls back to `API_KEY`, then `OPENAI_API_KEY`.
|
|
47
|
+
- Add PyPI packaging metadata (urls, keywords, classifiers, authors) and a
|
|
48
|
+
trusted-publishing release workflow.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Writing a task
|
|
4
|
+
|
|
5
|
+
A task lives in `tasks.yaml` and asserts what a model should do for one
|
|
6
|
+
conversation. Pick the category that matches what would actually break if
|
|
7
|
+
a model got it wrong:
|
|
8
|
+
|
|
9
|
+
- `select` picked the right tool, or correctly called nothing, when the
|
|
10
|
+
choice between tools is the interesting part
|
|
11
|
+
- `abstain` no tool applies and the correct behavior is to say so or ask
|
|
12
|
+
a question, not to guess
|
|
13
|
+
- `args` the right tool was the obvious choice, but the argument values
|
|
14
|
+
are where a model can still get it wrong (arithmetic, units, enums,
|
|
15
|
+
omitted optional fields, normalization)
|
|
16
|
+
- `depth` the conversation has multiple turns and the answer depends on
|
|
17
|
+
something said earlier
|
|
18
|
+
- `sequence` several actions are implied, and the task checks which one
|
|
19
|
+
is the correct first call, not the whole chain
|
|
20
|
+
|
|
21
|
+
Every task needs `id`, `category`, `bundle`, `messages`, and `expect`.
|
|
22
|
+
`expect.type` is `call` or `no_call`. For a call, `args` is exact match on
|
|
23
|
+
whichever keys you list (extra keys are judged by the tool's schema
|
|
24
|
+
instead), and `arg_checks` covers everything else you want to assert
|
|
25
|
+
about a value, at a dotted path like `address.postal_code` or
|
|
26
|
+
`attendees.0`.
|
|
27
|
+
|
|
28
|
+
`call` expects exactly one tool call; extra calls fail even when one is
|
|
29
|
+
correct. A truncated response cannot pass either expectation. Full call
|
|
30
|
+
evidence is retained in result JSON. Changes to these scoring semantics
|
|
31
|
+
must increment `SCORING_VERSION` in `scoring.py` and add regression tests,
|
|
32
|
+
so old and new observations are not silently combined.
|
|
33
|
+
|
|
34
|
+
| op | checks |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `eq` / `neq` | equals / does not equal |
|
|
37
|
+
| `in` | value is one of a list |
|
|
38
|
+
| `contains` | value contains a substring or element |
|
|
39
|
+
| `gte` / `lte` | numeric comparison |
|
|
40
|
+
| `matches` | value matches a regex |
|
|
41
|
+
| `exists` / `absent` | the key is present / is not present |
|
|
42
|
+
|
|
43
|
+
Add `exclude_distractors: [tool_name]` when padding could hand the model
|
|
44
|
+
a distractor tool that would make your expected answer wrong, most often
|
|
45
|
+
on `abstain` tasks. See `abstain-policy-question` in
|
|
46
|
+
`suites/core/tasks.yaml` for the pattern: the distractor
|
|
47
|
+
`search_knowledge_base` would genuinely answer the question, so it's
|
|
48
|
+
excluded from padding for that task specifically.
|
|
49
|
+
|
|
50
|
+
Once you've written a task, run:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
callprobe validate
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
It checks that every key you asserted in `args` or `arg_checks` actually
|
|
57
|
+
exists in the tool's schema, and that every value you asserted is legal
|
|
58
|
+
for that schema. It runs with no model and exits nonzero on any problem.
|
|
59
|
+
A typo here fails every model silently, so this is not optional.
|
|
60
|
+
|
|
61
|
+
## Submitting a run
|
|
62
|
+
|
|
63
|
+
Runs against models not yet in the leaderboard are welcome. Use the same
|
|
64
|
+
flags the existing runs used, so the numbers are comparable:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
callprobe run --model your-model --pad 0,8,16,24 --repeats 3 \
|
|
68
|
+
--max-tokens 4096 --out results/your-model.json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Include the results JSON file in your PR. Don't hand-edit it or the
|
|
72
|
+
leaderboard, both are generated:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
callprobe leaderboard results/your-model.json results/other-model.json \
|
|
76
|
+
> LEADERBOARD.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Say what endpoint and quantization you ran against in the PR description
|
|
80
|
+
if `--quant` doesn't already capture it.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
suite: core v2
|
|
2
|
+
|
|
3
|
+
| model | success | 95% CI | type-lenient | selection | schema | args | abstain | success @ +24 tools | tokens per success |
|
|
4
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
5
|
+
| command-r7b | 22.0% | 12.0-34.0% | 22.0% | 22.0% | 22.0% | 22.0% | 100.0% | 22.0% | 9392 |
|
|
6
|
+
| granite3.3:8b | 56.9% | 46.2-67.9% | 56.9% | 68.1% | 66.1% | 59.1% | 38.6% | 55.2% | 2066 |
|
|
7
|
+
| hermes3:8b | 52.3% | 41.5-63.4% | 52.3% | 71.7% | 67.8% | 62.8% | 56.4% | 48.8% | 2173 |
|
|
8
|
+
| llama3.2:3b | 28.4% | 18.3-39.1% | 40.9% | 61.3% | 36.7% | 40.4% | 4.1% | 25.2% | 3864 |
|
|
9
|
+
| mistral-nemo | 63.8% | 52.7-74.3% | 63.8% | 68.7% | 75.2% | 64.4% | 59.5% | 63.6% | 1699 |
|
|
10
|
+
| phi4-mini | 21.8% | 11.7-33.8% | 21.8% | 23.1% | 21.8% | 21.8% | 98.6% | 22.0% | 2992 |
|
|
11
|
+
| qwen2.5:7b | 77.1% | 67.9-86.1% | 77.1% | 88.9% | 91.0% | 80.3% | 83.2% | 75.6% | 1408 |
|
|
12
|
+
|
|
13
|
+
## Pending rerun against suite v2
|
|
14
|
+
|
|
15
|
+
These two ran against suite v1 (34 tasks, no `files` bundle) and are not
|
|
16
|
+
comparable to the table above. `callprobe leaderboard` refuses to mix
|
|
17
|
+
them in automatically; they'll move up once rerun.
|
|
18
|
+
|
|
19
|
+
| model | success | 95% CI | type-lenient | selection | schema | args | abstain | success @ +24 tools | tokens per success |
|
|
20
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
21
|
+
| llama3.1:8b | 32.1% | 19.4-46.1% | 51.2% | 66.9% | 33.6% | 36.8% | 9.8% | 34.3% | 3441 |
|
|
22
|
+
| qwen3:8b | 88.7% | 78.9-96.6% | 88.7% | 93.1% | 93.6% | 89.0% | 88.6% | 88.2% | 1568 |
|
callprobe-0.5.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Elad Hirsh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|