bantamkit 0.27.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.
- bantamkit-0.27.0/.gitignore +11 -0
- bantamkit-0.27.0/PKG-INFO +207 -0
- bantamkit-0.27.0/README.md +190 -0
- bantamkit-0.27.0/_assets/contracts/default.yaml +90 -0
- bantamkit-0.27.0/_assets/evals/devteam/manifest.yaml +351 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/HISTORY.md +18 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/README.md +12 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/docs/architecture.md +17 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/docs/runbook.md +10 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/issues/142-settlement-timeout.md +23 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/patches/0009-retry-budget.patch +38 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/__init__.py +3 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/config.py +35 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/errors.py +13 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/posting.py +12 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/registry.py +7 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/report.py +9 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/retry.py +17 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/settle.py +16 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/src/ledger/validate.py +14 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/tests/test_posting.py +13 -0
- bantamkit-0.27.0/_assets/evals/devteam/repo/tests/test_settle.py +9 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-error-contract.yaml +186 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-handler-map.yaml +183 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-patch-before-after.yaml +182 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-retry-attempts.yaml +181 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-settlement-config.yaml +185 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-symbol-home.yaml +181 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-trace-blame.yaml +182 -0
- bantamkit-0.27.0/_assets/evals/devteam/tasks/dt-unread-key.yaml +180 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-in-137.yaml +38 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-in-359.yaml +44 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-in-372.yaml +38 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-out-11764.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-out-4137.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-large-out-8022.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-small-137.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-small-261.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/document/tasks/doc-small-388.yaml +37 -0
- bantamkit-0.27.0/_assets/evals/fixtures/.gitkeep +0 -0
- bantamkit-0.27.0/_assets/evals/fixtures/catalog.json +6 -0
- bantamkit-0.27.0/_assets/evals/perturbations/task-completion.yaml +576 -0
- bantamkit-0.27.0/_assets/evals/tasks/.gitkeep +0 -0
- bantamkit-0.27.0/_assets/evals/tasks/extract-contact.yaml +14 -0
- bantamkit-0.27.0/_assets/evals/tasks/extract-invoice.yaml +14 -0
- bantamkit-0.27.0/_assets/evals/tasks/extract-order.yaml +15 -0
- bantamkit-0.27.0/_assets/evals/tasks/extract-schedule.yaml +14 -0
- bantamkit-0.27.0/_assets/evals/tasks/extract-versions.yaml +17 -0
- bantamkit-0.27.0/_assets/evals/tasks/nav-prod-port.yaml +84 -0
- bantamkit-0.27.0/_assets/evals/tasks/nav-release-bundle.yaml +87 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-audit-retention.yaml +17 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-cache-ttl.yaml +13 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-db-port.yaml +17 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-deploy.yaml +13 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-env-endpoint.yaml +18 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-oncall-rotation.yaml +21 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-oncall.yaml +13 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-org-quota.yaml +18 -0
- bantamkit-0.27.0/_assets/evals/tasks/recall-owner.yaml +13 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-basket-total.yaml +10 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-cheapest.yaml +9 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-compare.yaml +9 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-gadget-value.yaml +9 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-stock-total.yaml +9 -0
- bantamkit-0.27.0/_assets/evals/tasks/shop-total.yaml +9 -0
- bantamkit-0.27.0/_assets/profiles/default.yaml +31 -0
- bantamkit-0.27.0/_assets/profiles/patient.yaml +31 -0
- bantamkit-0.27.0/_assets/rubrics/.gitkeep +0 -0
- bantamkit-0.27.0/_assets/rubrics/code-quality.yaml +20 -0
- bantamkit-0.27.0/_assets/rubrics/grounded-completion.yaml +37 -0
- bantamkit-0.27.0/_assets/rubrics/task-completion.yaml +28 -0
- bantamkit-0.27.0/_assets/schemas/shiftwork-checkpoint.json +188 -0
- bantamkit-0.27.0/_assets/skills/.gitkeep +0 -0
- bantamkit-0.27.0/_assets/skills/file-graph.md +7 -0
- bantamkit-0.27.0/_assets/skills/memory.md +35 -0
- bantamkit-0.27.0/_assets/tools/.gitkeep +0 -0
- bantamkit-0.27.0/_assets/tools/bantamkit_read.json +48 -0
- bantamkit-0.27.0/_assets/tools/bantamkit_status.json +25 -0
- bantamkit-0.27.0/_assets/tools/build_identity.json +17 -0
- bantamkit-0.27.0/_assets/tools/document_list.json +12 -0
- bantamkit-0.27.0/_assets/tools/document_read.json +31 -0
- bantamkit-0.27.0/_assets/tools/file_graph.json +12 -0
- bantamkit-0.27.0/_assets/tools/memory_compact.json +31 -0
- bantamkit-0.27.0/_assets/tools/memory_recall.json +38 -0
- bantamkit-0.27.0/_assets/tools/memory_save.json +61 -0
- bantamkit-0.27.0/_assets/tools/shiftwork_clock_in.json +25 -0
- bantamkit-0.27.0/_assets/tools/shiftwork_clock_out.json +60 -0
- bantamkit-0.27.0/_assets/tools/shiftwork_status.json +25 -0
- bantamkit-0.27.0/_assets/tools/skill_audit.json +70 -0
- bantamkit-0.27.0/_assets/tools/validate_json.json +31 -0
- bantamkit-0.27.0/hatch_build.py +77 -0
- bantamkit-0.27.0/pyproject.toml +186 -0
- bantamkit-0.27.0/src/bantamkit/__init__.py +32 -0
- bantamkit-0.27.0/src/bantamkit/agent.py +458 -0
- bantamkit-0.27.0/src/bantamkit/assets.py +67 -0
- bantamkit-0.27.0/src/bantamkit/budget.py +114 -0
- bantamkit-0.27.0/src/bantamkit/client.py +329 -0
- bantamkit-0.27.0/src/bantamkit/contract.py +522 -0
- bantamkit-0.27.0/src/bantamkit/criticreplay.py +3241 -0
- bantamkit-0.27.0/src/bantamkit/critique.py +301 -0
- bantamkit-0.27.0/src/bantamkit/docread.py +1744 -0
- bantamkit-0.27.0/src/bantamkit/evalrun.py +2003 -0
- bantamkit-0.27.0/src/bantamkit/eventlog.py +282 -0
- bantamkit-0.27.0/src/bantamkit/filegraph.py +218 -0
- bantamkit-0.27.0/src/bantamkit/loopguard.py +101 -0
- bantamkit-0.27.0/src/bantamkit/mcpreport.py +763 -0
- bantamkit-0.27.0/src/bantamkit/mcpserver.py +1334 -0
- bantamkit-0.27.0/src/bantamkit/memory/__init__.py +28 -0
- bantamkit-0.27.0/src/bantamkit/memory/__main__.py +291 -0
- bantamkit-0.27.0/src/bantamkit/memory/component.py +569 -0
- bantamkit-0.27.0/src/bantamkit/memory/divergence.py +744 -0
- bantamkit-0.27.0/src/bantamkit/memory/layers.py +257 -0
- bantamkit-0.27.0/src/bantamkit/memory/store.py +940 -0
- bantamkit-0.27.0/src/bantamkit/pdfread.py +1402 -0
- bantamkit-0.27.0/src/bantamkit/profile.py +46 -0
- bantamkit-0.27.0/src/bantamkit/shiftwork.py +212 -0
- bantamkit-0.27.0/src/bantamkit/skillaudit.py +853 -0
- bantamkit-0.27.0/src/bantamkit/statusline.py +313 -0
- bantamkit-0.27.0/src/bantamkit/structured.py +125 -0
- bantamkit-0.27.0/src/bantamkit/textutil.py +30 -0
- bantamkit-0.27.0/tests/cli_exit_status_probe.py +51 -0
- bantamkit-0.27.0/tests/conftest.py +131 -0
- bantamkit-0.27.0/tests/data/docread/bad-crc.docx +0 -0
- bantamkit-0.27.0/tests/data/docread/charref-4301-digits.html +1 -0
- bantamkit-0.27.0/tests/data/docread/charset-table.json +42 -0
- bantamkit-0.27.0/tests/data/docread/compression-method-9.docx +0 -0
- bantamkit-0.27.0/tests/data/docread/corrupt-deflate.docx +0 -0
- bantamkit-0.27.0/tests/data/docread/encrypted-member.docx +0 -0
- bantamkit-0.27.0/tests/data/docread/encrypted-mimetype.odt +0 -0
- bantamkit-0.27.0/tests/data/docread/eszett-cell-ref.xlsx +0 -0
- bantamkit-0.27.0/tests/data/docread/internal-dtd-entity.docx +0 -0
- bantamkit-0.27.0/tests/data/docread/rfc2231-charset.eml +7 -0
- bantamkit-0.27.0/tests/data/docread/rfc822-nested-twice.eml +30 -0
- bantamkit-0.27.0/tests/data/docread/unicode-digit-shared-string.xlsx +0 -0
- bantamkit-0.27.0/tests/data/docread/x-uuencode.eml +10 -0
- bantamkit-0.27.0/tests/data/f8404ab-perturbation-baseline.json +3964 -0
- bantamkit-0.27.0/tests/data/served-tool-surface.json +401 -0
- bantamkit-0.27.0/tests/docread_fixtures.py +430 -0
- bantamkit-0.27.0/tests/perturbation_baseline_harness.py +367 -0
- bantamkit-0.27.0/tests/rbp16_effect_probe.py +58 -0
- bantamkit-0.27.0/tests/rbp18_payload_probe.py +84 -0
- bantamkit-0.27.0/tests/test_adapter.py +204 -0
- bantamkit-0.27.0/tests/test_agent.py +905 -0
- bantamkit-0.27.0/tests/test_amendguard.py +582 -0
- bantamkit-0.27.0/tests/test_bantamkit_read_tool.py +477 -0
- bantamkit-0.27.0/tests/test_budget.py +285 -0
- bantamkit-0.27.0/tests/test_build_identity.py +460 -0
- bantamkit-0.27.0/tests/test_client.py +420 -0
- bantamkit-0.27.0/tests/test_compaction_corpus_survey.py +580 -0
- bantamkit-0.27.0/tests/test_conformance.py +158 -0
- bantamkit-0.27.0/tests/test_contract_fanout.py +364 -0
- bantamkit-0.27.0/tests/test_criticreplay.py +7243 -0
- bantamkit-0.27.0/tests/test_critique.py +663 -0
- bantamkit-0.27.0/tests/test_doc_commands_gate.py +207 -0
- bantamkit-0.27.0/tests/test_docread.py +2050 -0
- bantamkit-0.27.0/tests/test_document_setup.py +951 -0
- bantamkit-0.27.0/tests/test_document_tasks.py +271 -0
- bantamkit-0.27.0/tests/test_document_tools.py +1129 -0
- bantamkit-0.27.0/tests/test_encoding_gate.py +448 -0
- bantamkit-0.27.0/tests/test_evalrun.py +2511 -0
- bantamkit-0.27.0/tests/test_eventlog.py +750 -0
- bantamkit-0.27.0/tests/test_field_program_gates.py +114 -0
- bantamkit-0.27.0/tests/test_field_programs.py +226 -0
- bantamkit-0.27.0/tests/test_filegraph.py +302 -0
- bantamkit-0.27.0/tests/test_ladder_statistics.py +381 -0
- bantamkit-0.27.0/tests/test_launcher_which.py +181 -0
- bantamkit-0.27.0/tests/test_layers.py +733 -0
- bantamkit-0.27.0/tests/test_loopguard.py +308 -0
- bantamkit-0.27.0/tests/test_mcp_endpoint.py +484 -0
- bantamkit-0.27.0/tests/test_mcpdrift.py +497 -0
- bantamkit-0.27.0/tests/test_mcpreport.py +727 -0
- bantamkit-0.27.0/tests/test_mcpserver.py +719 -0
- bantamkit-0.27.0/tests/test_memory.py +2323 -0
- bantamkit-0.27.0/tests/test_memory_compact_tool.py +267 -0
- bantamkit-0.27.0/tests/test_memory_component.py +880 -0
- bantamkit-0.27.0/tests/test_memory_divergence.py +801 -0
- bantamkit-0.27.0/tests/test_memory_layers.py +684 -0
- bantamkit-0.27.0/tests/test_memory_store_tripwire.py +444 -0
- bantamkit-0.27.0/tests/test_mutmatrix.py +236 -0
- bantamkit-0.27.0/tests/test_newline_gate.py +358 -0
- bantamkit-0.27.0/tests/test_packaging.py +214 -0
- bantamkit-0.27.0/tests/test_pdfread.py +820 -0
- bantamkit-0.27.0/tests/test_pinharness_ledger.py +96 -0
- bantamkit-0.27.0/tests/test_served_tool_count_records.py +232 -0
- bantamkit-0.27.0/tests/test_shiftwork.py +920 -0
- bantamkit-0.27.0/tests/test_skillaudit.py +1492 -0
- bantamkit-0.27.0/tests/test_status_surface.py +542 -0
- bantamkit-0.27.0/tests/test_statusline.py +539 -0
- bantamkit-0.27.0/tests/test_structured.py +277 -0
- bantamkit-0.27.0/tests/test_thread_exception_gate.py +202 -0
- bantamkit-0.27.0/tests/test_tool_manifest.py +419 -0
- bantamkit-0.27.0/tests/test_version_agreement.py +94 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: bantamkit
|
|
3
|
+
Version: 0.27.0
|
|
4
|
+
Summary: bantamweight tooling — harness primitives that lift small-model agents
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: httpx>=0.27
|
|
8
|
+
Requires-Dist: jsonschema>=4.21
|
|
9
|
+
Requires-Dist: pyyaml>=6.0
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: hatchling>=1.24; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
13
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
14
|
+
Provides-Extra: mcp
|
|
15
|
+
Requires-Dist: mcp<3,>=2.0; extra == 'mcp'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# bantamkit
|
|
19
|
+
|
|
20
|
+
Harness primitives that lift small-model agents: a per-person memory store, JSON
|
|
21
|
+
validation, shift-work accounting, a document reader, and a skill-catalogue
|
|
22
|
+
auditor — served to any MCP host over stdio.
|
|
23
|
+
|
|
24
|
+
This is the **Python** distribution. There is a second, independent
|
|
25
|
+
implementation of the same surface on npm as
|
|
26
|
+
[`bantamkit-mcp`](https://www.npmjs.com/package/bantamkit-mcp), written in pure
|
|
27
|
+
Node. The two share a memory store on disk and are held to the same answers by a
|
|
28
|
+
conformance suite, so you can install whichever one your host makes easy. What
|
|
29
|
+
the two do *not* agree on is written down in
|
|
30
|
+
[`docs/porting.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/porting.md)
|
|
31
|
+
and summarised at the bottom of this page.
|
|
32
|
+
|
|
33
|
+
## Install and run
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pipx run --spec "bantamkit[mcp]" bantamkit-mcp --assets-root
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
or into an environment you keep:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install "bantamkit[mcp]"
|
|
43
|
+
bantamkit-mcp --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The `[mcp]` extra pulls the MCP SDK. Without it you still get the library and the
|
|
47
|
+
operator CLI, but not the server.
|
|
48
|
+
|
|
49
|
+
The uv equivalent is `uvx --from "bantamkit[mcp]" bantamkit-mcp`. uv is not
|
|
50
|
+
installed on the machine this README was measured on, so unlike every other
|
|
51
|
+
command here that one is the documented form rather than a measured one.
|
|
52
|
+
|
|
53
|
+
### Connect it to a host
|
|
54
|
+
|
|
55
|
+
Every host below runs the same command; only the file and the key around it change. If
|
|
56
|
+
you installed with `pip` into an environment you keep, replace the `command`/`args` pair
|
|
57
|
+
with the absolute path to the `bantamkit-mcp` console script in that environment.
|
|
58
|
+
|
|
59
|
+
**Claude Code** — one command, no file to edit. `-s user` makes it available in every
|
|
60
|
+
project; drop it for this project only.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
claude mcp add bantamkit -s user -- pipx run --spec "bantamkit[mcp]" bantamkit-mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
67
|
+
on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows. Top-level key
|
|
68
|
+
`mcpServers`; each entry takes `command`, `args` and an optional `env`.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{"mcpServers": {"bantamkit": {"command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**GitHub Copilot in VS Code** — `.vscode/mcp.json` for one workspace, or the user
|
|
75
|
+
profile via the **MCP: Open User Configuration** command. Note the top-level key is
|
|
76
|
+
`servers`, not `mcpServers`.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{"servers": {"bantamkit": {"type": "stdio", "command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Cursor** — `.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` globally. Back
|
|
83
|
+
to `mcpServers`.
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{"mcpServers": {"bantamkit": {"command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Anything else that speaks MCP over stdio** runs the console script and talks JSON-RPC
|
|
90
|
+
on its stdin and stdout. Nothing about this package is host-specific.
|
|
91
|
+
|
|
92
|
+
The Claude Code and Claude Desktop forms were taken from this machine — `claude mcp add
|
|
93
|
+
--help` and an existing config file. The VS Code and Cursor forms are from those
|
|
94
|
+
projects' own documentation, not from a host installed here.
|
|
95
|
+
|
|
96
|
+
Point `--start` at a directory to choose where project-store discovery begins, or
|
|
97
|
+
`--store` at a single path to disable layering entirely. Do not reach for
|
|
98
|
+
`--store` by reflex: the default is layered, and the layering is most of the
|
|
99
|
+
value.
|
|
100
|
+
|
|
101
|
+
## What it serves
|
|
102
|
+
|
|
103
|
+
Eleven tools, measured off a wheel installed into an empty virtualenv:
|
|
104
|
+
|
|
105
|
+
| tool | what it does |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `memory_save` | store one durable fact, deduped and budgeted |
|
|
108
|
+
| `memory_recall` | retrieve facts matching a query |
|
|
109
|
+
| `memory_compact` | archive the stalest facts to fit the index budget |
|
|
110
|
+
| `validate_json` | validate a document against a JSON Schema |
|
|
111
|
+
| `bantamkit_read` | read a document — text, office formats, pdf |
|
|
112
|
+
| `skill_audit` | audit a skill catalogue for findings |
|
|
113
|
+
| `shiftwork_clock_in` | open a unit of work and get its brief |
|
|
114
|
+
| `shiftwork_clock_out` | close a unit with status and accounting |
|
|
115
|
+
| `shiftwork_status` | report the open cursor |
|
|
116
|
+
| `bantamkit_status` | report store health against its budget |
|
|
117
|
+
| `build_identity` | report the fingerprint of the source on disk |
|
|
118
|
+
|
|
119
|
+
`build_identity` describes the tree on disk, not the code currently executing —
|
|
120
|
+
useful precisely when a machine carries two installs under one name.
|
|
121
|
+
|
|
122
|
+
## Requirements
|
|
123
|
+
|
|
124
|
+
Python 3.11 or newer. Three runtime dependencies — `httpx`, `jsonschema`,
|
|
125
|
+
`pyyaml` — plus `mcp` under the `[mcp]` extra.
|
|
126
|
+
|
|
127
|
+
## The asset pack
|
|
128
|
+
|
|
129
|
+
Contracts, schemas, eval tasks, rubrics and tool manifests ship inside the
|
|
130
|
+
package and are located at import time:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
bantamkit-mcp --assets-root
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
It prints the resolved directory and its file count. A build that cannot find the
|
|
137
|
+
pack fails rather than producing an artifact without it — that refusal is
|
|
138
|
+
deliberate, because the silent version of it shipped once.
|
|
139
|
+
|
|
140
|
+
`BANTAMKIT_ASSETS` overrides the location.
|
|
141
|
+
|
|
142
|
+
## The operator CLI
|
|
143
|
+
|
|
144
|
+
Memory-store maintenance is a separate surface from the agent-facing tools, and
|
|
145
|
+
it is not served over MCP:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
python -m bantamkit.memory status # index size, budget, headroom, archives
|
|
149
|
+
python -m bantamkit.memory lint # exit 1 if malformed or over budget
|
|
150
|
+
python -m bantamkit.memory compact # archive the stalest facts
|
|
151
|
+
python -m bantamkit.memory archive <name>
|
|
152
|
+
python -m bantamkit.memory restore <name>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`archive` moves a fact out of the store without deleting it; `restore` brings it
|
|
156
|
+
back by name.
|
|
157
|
+
|
|
158
|
+
## Sharing a store with the Node server
|
|
159
|
+
|
|
160
|
+
Both distributions read and write the same on-disk format, so one store can be
|
|
161
|
+
served by either. That is also why a surface present in one and absent from the
|
|
162
|
+
other is not merely a coverage gap — it is a way for two servers to disagree
|
|
163
|
+
about one person's data. Every feature lands in both implementations in the same
|
|
164
|
+
change, and a conformance case compares the two answers before it counts as
|
|
165
|
+
ported.
|
|
166
|
+
|
|
167
|
+
## Where the two implementations differ, on purpose
|
|
168
|
+
|
|
169
|
+
- **This side reads pdf, `.doc` and `.rtf`; the Node side refuses them by name.**
|
|
170
|
+
PDF is read by a stdlib reader written for this project; real OLE2 `.doc` and
|
|
171
|
+
`.rtf` go through `/usr/bin/textutil`, a macOS built-in that is probed at every
|
|
172
|
+
call and refused by name where it is absent.
|
|
173
|
+
- **The operator CLI is spelled differently**, and it shows in help text and
|
|
174
|
+
error messages: `python -m bantamkit.memory` here against `bantamkit-memory`
|
|
175
|
+
there. There is no third spelling — a pure-npm install has no Python in it, and
|
|
176
|
+
CPython does not install that console script.
|
|
177
|
+
- **`build_id` hashes the executing tree**, and the two runtimes are two trees, so
|
|
178
|
+
it differs by construction. `assets_digest` is identical, and that is the one
|
|
179
|
+
that carries meaning.
|
|
180
|
+
|
|
181
|
+
Each of these is recorded in the divergence table with a conformance case pinning
|
|
182
|
+
the wording, so the difference cannot drift unnoticed.
|
|
183
|
+
|
|
184
|
+
## Development
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
git clone https://github.com/Ink01101011/bantamkit
|
|
188
|
+
cd bantamkit
|
|
189
|
+
python -m venv .venv && .venv/bin/pip install -e "runtime-py[dev,mcp]"
|
|
190
|
+
.venv/bin/python -m pytest runtime-py/tests -q
|
|
191
|
+
.venv/bin/ruff check runtime-py
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The cross-runtime gate needs Node:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
node tools/conformance/run.mjs --all
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Links
|
|
201
|
+
|
|
202
|
+
- Source: https://github.com/Ink01101011/bantamkit
|
|
203
|
+
- The Node distribution: https://www.npmjs.com/package/bantamkit-mcp
|
|
204
|
+
- Install notes: [`docs/install.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/install.md)
|
|
205
|
+
- What the two runtimes disagree about: [`docs/porting.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/porting.md)
|
|
206
|
+
|
|
207
|
+
MIT.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# bantamkit
|
|
2
|
+
|
|
3
|
+
Harness primitives that lift small-model agents: a per-person memory store, JSON
|
|
4
|
+
validation, shift-work accounting, a document reader, and a skill-catalogue
|
|
5
|
+
auditor — served to any MCP host over stdio.
|
|
6
|
+
|
|
7
|
+
This is the **Python** distribution. There is a second, independent
|
|
8
|
+
implementation of the same surface on npm as
|
|
9
|
+
[`bantamkit-mcp`](https://www.npmjs.com/package/bantamkit-mcp), written in pure
|
|
10
|
+
Node. The two share a memory store on disk and are held to the same answers by a
|
|
11
|
+
conformance suite, so you can install whichever one your host makes easy. What
|
|
12
|
+
the two do *not* agree on is written down in
|
|
13
|
+
[`docs/porting.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/porting.md)
|
|
14
|
+
and summarised at the bottom of this page.
|
|
15
|
+
|
|
16
|
+
## Install and run
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pipx run --spec "bantamkit[mcp]" bantamkit-mcp --assets-root
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
or into an environment you keep:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install "bantamkit[mcp]"
|
|
26
|
+
bantamkit-mcp --help
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The `[mcp]` extra pulls the MCP SDK. Without it you still get the library and the
|
|
30
|
+
operator CLI, but not the server.
|
|
31
|
+
|
|
32
|
+
The uv equivalent is `uvx --from "bantamkit[mcp]" bantamkit-mcp`. uv is not
|
|
33
|
+
installed on the machine this README was measured on, so unlike every other
|
|
34
|
+
command here that one is the documented form rather than a measured one.
|
|
35
|
+
|
|
36
|
+
### Connect it to a host
|
|
37
|
+
|
|
38
|
+
Every host below runs the same command; only the file and the key around it change. If
|
|
39
|
+
you installed with `pip` into an environment you keep, replace the `command`/`args` pair
|
|
40
|
+
with the absolute path to the `bantamkit-mcp` console script in that environment.
|
|
41
|
+
|
|
42
|
+
**Claude Code** — one command, no file to edit. `-s user` makes it available in every
|
|
43
|
+
project; drop it for this project only.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
claude mcp add bantamkit -s user -- pipx run --spec "bantamkit[mcp]" bantamkit-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
50
|
+
on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows. Top-level key
|
|
51
|
+
`mcpServers`; each entry takes `command`, `args` and an optional `env`.
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{"mcpServers": {"bantamkit": {"command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**GitHub Copilot in VS Code** — `.vscode/mcp.json` for one workspace, or the user
|
|
58
|
+
profile via the **MCP: Open User Configuration** command. Note the top-level key is
|
|
59
|
+
`servers`, not `mcpServers`.
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{"servers": {"bantamkit": {"type": "stdio", "command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Cursor** — `.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` globally. Back
|
|
66
|
+
to `mcpServers`.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{"mcpServers": {"bantamkit": {"command": "pipx", "args": ["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]}}}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Anything else that speaks MCP over stdio** runs the console script and talks JSON-RPC
|
|
73
|
+
on its stdin and stdout. Nothing about this package is host-specific.
|
|
74
|
+
|
|
75
|
+
The Claude Code and Claude Desktop forms were taken from this machine — `claude mcp add
|
|
76
|
+
--help` and an existing config file. The VS Code and Cursor forms are from those
|
|
77
|
+
projects' own documentation, not from a host installed here.
|
|
78
|
+
|
|
79
|
+
Point `--start` at a directory to choose where project-store discovery begins, or
|
|
80
|
+
`--store` at a single path to disable layering entirely. Do not reach for
|
|
81
|
+
`--store` by reflex: the default is layered, and the layering is most of the
|
|
82
|
+
value.
|
|
83
|
+
|
|
84
|
+
## What it serves
|
|
85
|
+
|
|
86
|
+
Eleven tools, measured off a wheel installed into an empty virtualenv:
|
|
87
|
+
|
|
88
|
+
| tool | what it does |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `memory_save` | store one durable fact, deduped and budgeted |
|
|
91
|
+
| `memory_recall` | retrieve facts matching a query |
|
|
92
|
+
| `memory_compact` | archive the stalest facts to fit the index budget |
|
|
93
|
+
| `validate_json` | validate a document against a JSON Schema |
|
|
94
|
+
| `bantamkit_read` | read a document — text, office formats, pdf |
|
|
95
|
+
| `skill_audit` | audit a skill catalogue for findings |
|
|
96
|
+
| `shiftwork_clock_in` | open a unit of work and get its brief |
|
|
97
|
+
| `shiftwork_clock_out` | close a unit with status and accounting |
|
|
98
|
+
| `shiftwork_status` | report the open cursor |
|
|
99
|
+
| `bantamkit_status` | report store health against its budget |
|
|
100
|
+
| `build_identity` | report the fingerprint of the source on disk |
|
|
101
|
+
|
|
102
|
+
`build_identity` describes the tree on disk, not the code currently executing —
|
|
103
|
+
useful precisely when a machine carries two installs under one name.
|
|
104
|
+
|
|
105
|
+
## Requirements
|
|
106
|
+
|
|
107
|
+
Python 3.11 or newer. Three runtime dependencies — `httpx`, `jsonschema`,
|
|
108
|
+
`pyyaml` — plus `mcp` under the `[mcp]` extra.
|
|
109
|
+
|
|
110
|
+
## The asset pack
|
|
111
|
+
|
|
112
|
+
Contracts, schemas, eval tasks, rubrics and tool manifests ship inside the
|
|
113
|
+
package and are located at import time:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bantamkit-mcp --assets-root
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
It prints the resolved directory and its file count. A build that cannot find the
|
|
120
|
+
pack fails rather than producing an artifact without it — that refusal is
|
|
121
|
+
deliberate, because the silent version of it shipped once.
|
|
122
|
+
|
|
123
|
+
`BANTAMKIT_ASSETS` overrides the location.
|
|
124
|
+
|
|
125
|
+
## The operator CLI
|
|
126
|
+
|
|
127
|
+
Memory-store maintenance is a separate surface from the agent-facing tools, and
|
|
128
|
+
it is not served over MCP:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
python -m bantamkit.memory status # index size, budget, headroom, archives
|
|
132
|
+
python -m bantamkit.memory lint # exit 1 if malformed or over budget
|
|
133
|
+
python -m bantamkit.memory compact # archive the stalest facts
|
|
134
|
+
python -m bantamkit.memory archive <name>
|
|
135
|
+
python -m bantamkit.memory restore <name>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`archive` moves a fact out of the store without deleting it; `restore` brings it
|
|
139
|
+
back by name.
|
|
140
|
+
|
|
141
|
+
## Sharing a store with the Node server
|
|
142
|
+
|
|
143
|
+
Both distributions read and write the same on-disk format, so one store can be
|
|
144
|
+
served by either. That is also why a surface present in one and absent from the
|
|
145
|
+
other is not merely a coverage gap — it is a way for two servers to disagree
|
|
146
|
+
about one person's data. Every feature lands in both implementations in the same
|
|
147
|
+
change, and a conformance case compares the two answers before it counts as
|
|
148
|
+
ported.
|
|
149
|
+
|
|
150
|
+
## Where the two implementations differ, on purpose
|
|
151
|
+
|
|
152
|
+
- **This side reads pdf, `.doc` and `.rtf`; the Node side refuses them by name.**
|
|
153
|
+
PDF is read by a stdlib reader written for this project; real OLE2 `.doc` and
|
|
154
|
+
`.rtf` go through `/usr/bin/textutil`, a macOS built-in that is probed at every
|
|
155
|
+
call and refused by name where it is absent.
|
|
156
|
+
- **The operator CLI is spelled differently**, and it shows in help text and
|
|
157
|
+
error messages: `python -m bantamkit.memory` here against `bantamkit-memory`
|
|
158
|
+
there. There is no third spelling — a pure-npm install has no Python in it, and
|
|
159
|
+
CPython does not install that console script.
|
|
160
|
+
- **`build_id` hashes the executing tree**, and the two runtimes are two trees, so
|
|
161
|
+
it differs by construction. `assets_digest` is identical, and that is the one
|
|
162
|
+
that carries meaning.
|
|
163
|
+
|
|
164
|
+
Each of these is recorded in the divergence table with a conformance case pinning
|
|
165
|
+
the wording, so the difference cannot drift unnoticed.
|
|
166
|
+
|
|
167
|
+
## Development
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
git clone https://github.com/Ink01101011/bantamkit
|
|
171
|
+
cd bantamkit
|
|
172
|
+
python -m venv .venv && .venv/bin/pip install -e "runtime-py[dev,mcp]"
|
|
173
|
+
.venv/bin/python -m pytest runtime-py/tests -q
|
|
174
|
+
.venv/bin/ruff check runtime-py
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The cross-runtime gate needs Node:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
node tools/conformance/run.mjs --all
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Links
|
|
184
|
+
|
|
185
|
+
- Source: https://github.com/Ink01101011/bantamkit
|
|
186
|
+
- The Node distribution: https://www.npmjs.com/package/bantamkit-mcp
|
|
187
|
+
- Install notes: [`docs/install.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/install.md)
|
|
188
|
+
- What the two runtimes disagree about: [`docs/porting.md`](https://github.com/Ink01101011/bantamkit/blob/main/docs/porting.md)
|
|
189
|
+
|
|
190
|
+
MIT.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
name: default
|
|
2
|
+
schema_instruction: "Return ONLY a JSON object matching this JSON Schema. No prose.\n"
|
|
3
|
+
schema_retry: "{error}\nReturn ONLY a JSON object matching the schema."
|
|
4
|
+
critique_feedback: "A reviewer scored your answer {score}/10 (needs >= {threshold}). Feedback: {feedback}\nIf the feedback says a value is missing, unverified, or absent from your evidence, that is a fact you never looked up: call your tools and read the source that has it. Do not reword, generalise, or hedge the previous answer to work around the gap. Then answer again."
|
|
5
|
+
parse_error: "output was not parseable JSON: {detail}"
|
|
6
|
+
validation_error: "JSON does not match schema at '{where}': {detail}"
|
|
7
|
+
json_answer_retry: "Your answer contains no JSON. Restate your final answer as ONLY the JSON requested by the task, with no prose around it."
|
|
8
|
+
loop_note: "(you have now received this exact result {count} times; it will not change. Do something different or give your final answer now)"
|
|
9
|
+
loop_warn: "(STOP calling tools. Give your final answer now, in exactly the format the task asked for.)"
|
|
10
|
+
evidence_line: "{name}({arguments}) -> {observation}"
|
|
11
|
+
evidence_no_observation: "(no observation)"
|
|
12
|
+
evidence_empty: "(no tool calls were made)"
|
|
13
|
+
# The document reader pair's observations (`document_list`, `document_read`). Every string a
|
|
14
|
+
# reader hands back to the model lives here and not in the harness, for the reason the layer
|
|
15
|
+
# rule gives: the mechanics measured in `docread.py` transfer across models, this wording is
|
|
16
|
+
# exactly what does not.
|
|
17
|
+
document_manifest_empty: "no documents are attached to this task"
|
|
18
|
+
document_manifest_part: "{document} ({kind}) part {index} \"{part}\": {rows} rows, numbered 0 to {last}"
|
|
19
|
+
document_manifest_header_row: " row 0 is the header: {row}"
|
|
20
|
+
document_manifest_first_row: " row 1 is the first data row: {row}"
|
|
21
|
+
document_manifest_last_row: " row {index} is the last data row: {row}"
|
|
22
|
+
# What the rendering left out, stated in the one place that says what exists. Measured need
|
|
23
|
+
# (J25, the user's real ~/Downloads, 2026-08-20): `step test.xlsx` is 18.62 MB and the manifest
|
|
24
|
+
# said `4 parts, 28 rows` — all 28 of those rows are empty lines and the file's actual content
|
|
25
|
+
# is 56 embedded PNGs. Every line here is a COUNT: an adjective ("some images") tells a model
|
|
26
|
+
# nothing it can decide with, and silence tells it something false.
|
|
27
|
+
document_manifest_package_media: "{document}: the file also holds {count} embedded file(s) ({what}) totalling {bytes} bytes, which no row can carry — this reader renders no image or embedded object"
|
|
28
|
+
document_manifest_omitted_media: " NOT in those rows: {count} embedded file(s), {bytes} bytes, anchored to this part"
|
|
29
|
+
document_manifest_omitted_blank: " {count} of those {rows} rows carry no cell value at all and render as an empty line"
|
|
30
|
+
document_manifest_omitted_format: " column(s) {where}: {count} cell(s) store a NUMBER under the date/time format {what} — this reader renders the stored serial number verbatim and does not convert it to a date; convert it with that format code if you need one"
|
|
31
|
+
# J25-D3, the PDF reader. Two silences a page-addressable reader can produce that a
|
|
32
|
+
# spreadsheet cannot: a page that rendered no row (a scan, or glyphs no font maps), and
|
|
33
|
+
# characters dropped because the file states no mapping for them. An empty page and a page
|
|
34
|
+
# nobody could read are different facts and the model must be able to tell them apart.
|
|
35
|
+
document_manifest_omitted_unread_page: " this part rendered NO row: {why}. It draws {count} image(s), {bytes} bytes, that no row can carry — no row means this reader recovered no text from the page, which is NOT the same as the page being empty, and there is no OCR here"
|
|
36
|
+
document_manifest_unread_no_operator: "the page ran no text-showing operator at all, so nothing on it was ever text"
|
|
37
|
+
document_manifest_unread_unmapped: "the page ran {show_ops} text-showing operator(s) and every one of the {unmapped} character(s) they showed came through a font that declares no character map, so this reader dropped them rather than guess at them"
|
|
38
|
+
document_manifest_unread_whitespace: "the page ran {show_ops} text-showing operator(s) and this reader mapped every one of the {vouched} character(s) they showed, and every one of those characters is WHITESPACE — the text was recovered and it carries nothing, which is a fact about the page and not a failure of this reader"
|
|
39
|
+
document_manifest_unread_no_character: "the page ran {show_ops} text-showing operator(s) that put no character on the page at all, neither one this reader could map nor one it had to drop"
|
|
40
|
+
document_manifest_omitted_unmapped: " {count} character(s) shown on this part are NOT in those rows: their codes came from font(s) with no /ToUnicode map ({what}), so the file stores indices into a font's own glyphs and says nowhere which character each glyph draws — this reader drops them rather than guess, because a guess here is indistinguishable from content"
|
|
41
|
+
document_manifest_omitted_other: " NOT in those rows: {count} {subject} ({what})"
|
|
42
|
+
document_page_header: "{document} \"{part}\" rows {start}-{end} of {rows}; each line below begins with its own row number"
|
|
43
|
+
document_page_next: "more rows follow: call document_read again with offset={next_offset}"
|
|
44
|
+
document_page_end: "that was the last row of \"{part}\""
|
|
45
|
+
document_page_truncated: "row {index} was too long for one page and was cut: {dropped} bytes dropped"
|
|
46
|
+
document_unknown: "error: no document named {name}; this task has: {available}"
|
|
47
|
+
document_offset_past_end: "error: offset {offset} is past the end of \"{part}\", which has {rows} rows numbered 0 to {last}"
|
|
48
|
+
document_error: "error: {detail}"
|
|
49
|
+
# `bantamkit_read` (the MCP reader, job43) reuses every `document_*` sentence above with the
|
|
50
|
+
# path standing in for `{document}`. Two sentences are genuinely its own: its continuation
|
|
51
|
+
# line names ITS tool, and a part it does not have is a fact about the file, not the task.
|
|
52
|
+
bantamkit_read_page_next: "more rows follow: call bantamkit_read again with offset={next_offset}"
|
|
53
|
+
bantamkit_read_unknown_part: "error: no part named \"{part}\" in {path}; it has: {available}"
|
|
54
|
+
# The `paste` arm's system message (`docs/eval-data/2026-08-20-document-read-bar.md` §10.2,
|
|
55
|
+
# PASTE_MAX_BYTES = 8621 under Amendment 1, 2026-08-20). The arm registers NO tools, so these four lines are the whole of
|
|
56
|
+
# what the model is told ABOUT the corpus; the rows themselves are docread's own rendering,
|
|
57
|
+
# unprefixed and unreformatted, so `paste` and `document_read` differ in DELIVERY and not in
|
|
58
|
+
# content. Clause 4 makes stating the paste's own completeness part of the contract, and
|
|
59
|
+
# `paste_truncated` says the missing rows are unreachable rather than leaving the model to
|
|
60
|
+
# hunt for a tool that is not there: a paste that lets a truncated head read as the whole
|
|
61
|
+
# sheet is a different, worse arm than the one the bar pre-registered.
|
|
62
|
+
document_paste_preamble: "The following document content is attached to this task. Fields in a row are separated by tabs, rows are given in order, and row 0 of each part is its header."
|
|
63
|
+
document_paste_part: "{document} ({kind}) part {index} \"{part}\": {rows} rows, numbered 0 to {last}; {shown} of them are shown below."
|
|
64
|
+
document_paste_complete: " rows 0 to {last_shown} are shown, which is every row of \"{part}\": this copy is COMPLETE."
|
|
65
|
+
document_paste_truncated: " rows 0 to {last_shown} are shown; rows {first_missing} to {last} of \"{part}\" are NOT shown and no tool is attached that can fetch them. This copy is PARTIAL."
|
|
66
|
+
document_paste_none: " no rows of \"{part}\" are shown and no tool is attached that can fetch them."
|
|
67
|
+
# What the model is told when a tool CALL cannot be made or fails, rather than when a tool
|
|
68
|
+
# answers with its own error (`document_unknown` and friends above are that). It lives here
|
|
69
|
+
# for the reason the layer rule gives and for one measured reason: before 2026-08-20 the
|
|
70
|
+
# dispatcher formatted this sentence itself and interpolated the raw exception, so a model
|
|
71
|
+
# that sent one extra argument was handed
|
|
72
|
+
# `_document_tools.<locals>.list_documents() got an unexpected keyword argument 'document'`
|
|
73
|
+
# — a Python qualname, model-facing, owned by no asset and pinned by no golden. The
|
|
74
|
+
# argument-shaped failures are intercepted before the handler is called now, so `{detail}`
|
|
75
|
+
# carries a handler's OWN sentence and no longer a signature fragment.
|
|
76
|
+
tool_failed: "error: {tool} failed: {detail}. fix the arguments and retry."
|
|
77
|
+
tool_arguments: "error: {tool} does not take the arguments it was given. it takes: {accepts}. fix the arguments and retry."
|
|
78
|
+
tool_arguments_none: "error: {tool} takes no arguments at all. call it with none and retry."
|
|
79
|
+
# 2026-08-20, `RB-P86`. The sibling of the two above, one layer in. `select_declared_arguments`
|
|
80
|
+
# drops keys the schema does not declare and type-checks nothing, so `llama3.2:3b` — which
|
|
81
|
+
# emits a JSON-Schema FRAGMENT as the value of a declared parameter,
|
|
82
|
+
# `{"document": {"description": "stock", "type": "string"}}` — got its dict straight through to
|
|
83
|
+
# `docs.get(name)` and the model read `unhashable type: 'dict'`, thirteen times over 432 graded
|
|
84
|
+
# runs. That is CPython's sentence about a hash table, not a tool's sentence about its own
|
|
85
|
+
# arguments, and a 3b that receives it stops calling tools and answers that it cannot access
|
|
86
|
+
# the workbook. What it is told now names the argument, the type the tool declares and the type
|
|
87
|
+
# it was sent, so the next turn has something to correct. One frame for one or many, because
|
|
88
|
+
# the count is not the thing the model has to act on.
|
|
89
|
+
tool_argument_types: "error: {tool} was called with the wrong type of argument. {problems}. fix the arguments and retry."
|
|
90
|
+
tool_argument_type: "{argument} must be type {expected}, not type {actual}"
|