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.
Files changed (57) hide show
  1. callprobe-0.5.0/.github/ISSUE_TEMPLATE/new-model-run.md +32 -0
  2. callprobe-0.5.0/.github/ISSUE_TEMPLATE/new-task.md +25 -0
  3. callprobe-0.5.0/.github/workflows/ci.yml +38 -0
  4. callprobe-0.5.0/.github/workflows/release.yml +34 -0
  5. callprobe-0.5.0/.gitignore +8 -0
  6. callprobe-0.5.0/CHANGELOG.md +48 -0
  7. callprobe-0.5.0/CONTRIBUTING.md +80 -0
  8. callprobe-0.5.0/LEADERBOARD.md +22 -0
  9. callprobe-0.5.0/LICENSE +21 -0
  10. callprobe-0.5.0/PKG-INFO +515 -0
  11. callprobe-0.5.0/README.md +485 -0
  12. callprobe-0.5.0/action.yml +114 -0
  13. callprobe-0.5.0/examples/ci-policy.yaml +11 -0
  14. callprobe-0.5.0/pyproject.toml +58 -0
  15. callprobe-0.5.0/results/archive/qwen3-8b-q4.json +2095 -0
  16. callprobe-0.5.0/results/command-r7b.json +25588 -0
  17. callprobe-0.5.0/results/granite3.3-8b.json +25340 -0
  18. callprobe-0.5.0/results/hermes3-8b.json +25366 -0
  19. callprobe-0.5.0/results/llama3.1-8b.json +10701 -0
  20. callprobe-0.5.0/results/llama3.2-3b.json +26304 -0
  21. callprobe-0.5.0/results/mistral-nemo.json +25011 -0
  22. callprobe-0.5.0/results/phi4-mini.json +25628 -0
  23. callprobe-0.5.0/results/qwen2.5-7b.json +24687 -0
  24. callprobe-0.5.0/results/qwen3-8b.json +9932 -0
  25. callprobe-0.5.0/results/v0.5.0/README.md +126 -0
  26. callprobe-0.5.0/results/v0.5.0/qwen2.5-7b-baseline.json +5748 -0
  27. callprobe-0.5.0/results/v0.5.0/qwen2.5-7b-candidate.json +5748 -0
  28. callprobe-0.5.0/results/v0.5.0/validation-summary.json +268 -0
  29. callprobe-0.5.0/scripts/overnight.sh +42 -0
  30. callprobe-0.5.0/src/callprobe/__init__.py +10 -0
  31. callprobe-0.5.0/src/callprobe/bootstrap.py +49 -0
  32. callprobe-0.5.0/src/callprobe/cli.py +346 -0
  33. callprobe-0.5.0/src/callprobe/client.py +196 -0
  34. callprobe-0.5.0/src/callprobe/coerce.py +62 -0
  35. callprobe-0.5.0/src/callprobe/compare.py +95 -0
  36. callprobe-0.5.0/src/callprobe/gates.py +137 -0
  37. callprobe-0.5.0/src/callprobe/init.py +101 -0
  38. callprobe-0.5.0/src/callprobe/loader.py +105 -0
  39. callprobe-0.5.0/src/callprobe/models.py +164 -0
  40. callprobe-0.5.0/src/callprobe/report.py +223 -0
  41. callprobe-0.5.0/src/callprobe/runner.py +188 -0
  42. callprobe-0.5.0/src/callprobe/scoring.py +248 -0
  43. callprobe-0.5.0/src/callprobe/suites/core/distractors.yaml +160 -0
  44. callprobe-0.5.0/src/callprobe/suites/core/suite.yaml +2 -0
  45. callprobe-0.5.0/src/callprobe/suites/core/tasks.yaml +808 -0
  46. callprobe-0.5.0/src/callprobe/suites/core/tools.yaml +223 -0
  47. callprobe-0.5.0/src/callprobe/validate.py +37 -0
  48. callprobe-0.5.0/tests/test_action.py +51 -0
  49. callprobe-0.5.0/tests/test_bootstrap.py +53 -0
  50. callprobe-0.5.0/tests/test_cli.py +114 -0
  51. callprobe-0.5.0/tests/test_client.py +91 -0
  52. callprobe-0.5.0/tests/test_compare.py +115 -0
  53. callprobe-0.5.0/tests/test_gates.py +134 -0
  54. callprobe-0.5.0/tests/test_init.py +109 -0
  55. callprobe-0.5.0/tests/test_report.py +93 -0
  56. callprobe-0.5.0/tests/test_runner.py +162 -0
  57. 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,8 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ overnight.log
8
+ logs/
@@ -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 |
@@ -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.