bantamkit 0.35.3__tar.gz → 0.35.4__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.35.3 → bantamkit-0.35.4}/PKG-INFO +106 -4
- {bantamkit-0.35.3 → bantamkit-0.35.4}/README.md +104 -3
- bantamkit-0.35.4/_assets/tools/shiftwork_clock_in.json +37 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/shiftwork_clock_out.json +2 -2
- bantamkit-0.35.4/_assets/tools/shiftwork_plan.json +25 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/pyproject.toml +4 -1
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/__init__.py +1 -1
- bantamkit-0.35.4/src/bantamkit/hookadapter.py +2084 -0
- bantamkit-0.35.4/src/bantamkit/hostinstall.py +722 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/mcpserver.py +309 -2
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/dream.py +5 -5
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/store.py +23 -7
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/selfupdate.py +22 -2
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/shiftwork.py +172 -61
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/updatecheck.py +78 -16
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/served-tool-surface.json +16 -4
- bantamkit-0.35.4/tests/test_hookadapter.py +1262 -0
- bantamkit-0.35.4/tests/test_hostinstall_hooks.py +1033 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory.py +1 -1
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_dream.py +3 -3
- bantamkit-0.35.4/tests/test_nativeexport.py +830 -0
- bantamkit-0.35.4/tests/test_readme_separation.py +331 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_selfupdate.py +36 -10
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_shiftwork.py +330 -2
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_updatecheck.py +86 -4
- bantamkit-0.35.3/_assets/tools/shiftwork_clock_in.json +0 -25
- bantamkit-0.35.3/_assets/tools/shiftwork_plan.json +0 -25
- bantamkit-0.35.3/src/bantamkit/hostinstall.py +0 -296
- {bantamkit-0.35.3 → bantamkit-0.35.4}/.gitignore +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/contracts/default.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/manifest.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/HISTORY.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/README.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/docs/architecture.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/docs/runbook.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/issues/142-settlement-timeout.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/patches/0009-retry-budget.patch +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/__init__.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/config.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/errors.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/posting.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/registry.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/report.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/retry.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/settle.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/src/ledger/validate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/tests/test_posting.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/repo/tests/test_settle.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-error-contract.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-handler-map.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-patch-before-after.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-retry-attempts.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-settlement-config.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-symbol-home.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-trace-blame.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/devteam/tasks/dt-unread-key.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-in-137.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-in-359.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-in-372.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-out-11764.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-out-4137.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-large-out-8022.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-small-137.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-small-261.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/document/tasks/doc-small-388.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/fixtures/.gitkeep +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/fixtures/catalog.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/perturbations/task-completion.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/.gitkeep +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/extract-contact.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/extract-invoice.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/extract-order.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/extract-schedule.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/extract-versions.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/nav-prod-port.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/nav-release-bundle.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-audit-retention.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-cache-ttl.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-db-port.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-deploy.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-env-endpoint.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-oncall-rotation.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-oncall.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-org-quota.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/recall-owner.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-basket-total.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-cheapest.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-compare.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-gadget-value.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-stock-total.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/evals/tasks/shop-total.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/pricing/default.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/profiles/default.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/profiles/patient.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/rubrics/.gitkeep +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/rubrics/code-quality.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/rubrics/grounded-completion.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/rubrics/task-completion.yaml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/schemas/shiftwork-checkpoint.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/skills/.gitkeep +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/skills/file-graph.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/skills/memory.md +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/.gitkeep +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/bantamkit_read.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/bantamkit_status.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/build_identity.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/document_list.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/document_read.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/file_graph.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/memory_compact.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/memory_dream.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/memory_recall.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/memory_save.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/repo_map.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/shiftwork_status.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/skill_audit.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/token_ledger.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/validate_json.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/_assets/tools/work_plan.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/hatch_build.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/agent.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/assets.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/budget.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/client.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/contract.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/criticreplay.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/critique.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/docmanifest.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/docread.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/evalrun.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/eventlog.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/filegraph.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/loopguard.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/mcpreport.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/__init__.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/__main__.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/component.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/divergence.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/memory/layers.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/pdfread.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/pricing.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/profile.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/repomap.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/skillaudit.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/statusline.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/structured.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/textutil.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/tokenledger.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/src/bantamkit/workplan.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/cli_exit_status_probe.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/conftest.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/bad-crc.docx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/charref-4301-digits.html +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/charset-table.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/compression-method-9.docx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/corrupt-deflate.docx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/encrypted-member.docx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/encrypted-mimetype.odt +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/eszett-cell-ref.xlsx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/internal-dtd-entity.docx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/rfc2231-charset.eml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/rfc822-nested-twice.eml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/unicode-digit-shared-string.xlsx +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/docread/x-uuencode.eml +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/f8404ab-perturbation-baseline.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/data/platform-assumption-baseline.json +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/docread_fixtures.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/perturbation_baseline_harness.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/rbp16_effect_probe.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/rbp18_payload_probe.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_adapter.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_agent.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_amendguard.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_bantamkit_gitignore.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_bantamkit_read_tool.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_budget.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_build_identity.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_client.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_compaction_corpus_survey.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_conformance.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_conformance_harness_resilience.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_conformance_suite_table_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_contract_fanout.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_criticreplay.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_critique.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_doc_commands_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_docread.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_docread_ceilings.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_document_manifest_parity.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_document_setup.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_document_tasks.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_document_tools.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_encoding_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_evalrun.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_eventlog.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_field_program_gates.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_field_programs.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_filegraph.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_hostinstall.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_install_shape.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_ladder_statistics.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_launcher_which.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_layers.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_loopguard.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_mcp_endpoint.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_mcpdrift.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_mcpreport.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_mcpserver.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_compact_tool.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_component.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_divergence.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_layers.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_memory_store_tripwire.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_mutmatrix.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_newline_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_packaging.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_pdfread.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_pinharness_ledger.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_platform_assumption_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_pricing.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_repo_map_tool.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_repomap.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_served_tool_count_records.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_skillaudit.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_status_surface.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_statusline.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_structured.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_thread_exception_gate.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_tokenledger.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_tool_manifest.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_version_agreement.py +0 -0
- {bantamkit-0.35.3 → bantamkit-0.35.4}/tests/test_workplan.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bantamkit
|
|
3
|
-
Version: 0.35.
|
|
3
|
+
Version: 0.35.4
|
|
4
4
|
Summary: Memory MCP server for Claude Code, Cursor, VS Code Copilot and Claude Desktop, plus a Python library that lifts small-model agents. Install once, run offline.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Ink01101011/bantamkit
|
|
6
6
|
Project-URL: Repository, https://github.com/Ink01101011/bantamkit
|
|
@@ -19,6 +19,7 @@ Requires-Dist: httpx>=0.27
|
|
|
19
19
|
Requires-Dist: jsonschema>=4.21
|
|
20
20
|
Requires-Dist: pyyaml>=6.0
|
|
21
21
|
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
22
23
|
Requires-Dist: hatchling>=1.24; extra == 'dev'
|
|
23
24
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
24
25
|
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
@@ -39,6 +40,10 @@ The same server in pure Node is on **npm** as
|
|
|
39
40
|
disk and a conformance suite holds them to the same answers, so install whichever your host makes
|
|
40
41
|
easy.
|
|
41
42
|
|
|
43
|
+
**This page is the PyPI package's.** Every command on it runs `bantamkit` from PyPI. The npm
|
|
44
|
+
package is named where the two differ, but its own install, update and CLI commands live on
|
|
45
|
+
[its page](https://www.npmjs.com/package/bantamkit-mcp); run them here and you get nothing.
|
|
46
|
+
|
|
42
47
|
## Contents
|
|
43
48
|
|
|
44
49
|
| Topic | What you'll find |
|
|
@@ -60,6 +65,7 @@ easy.
|
|
|
60
65
|
| [The asset pack](#the-asset-pack) | `--assets-root`, `BANTAMKIT_ASSETS` |
|
|
61
66
|
| [The operator CLI: `python -m bantamkit.memory`](#the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore |
|
|
62
67
|
| [Where the Python and Node servers differ](#where-the-python-and-node-servers-differ) | One store; pdf/.doc/.rtf, CLI name, `build_id` |
|
|
68
|
+
| [Module API](#module-api) | `import bantamkit`: the library half, measured from the wheel |
|
|
63
69
|
| [Development](#development) | Clone, test, lint, conformance |
|
|
64
70
|
| [Documentation](#documentation) | The full docs on GitHub |
|
|
65
71
|
|
|
@@ -97,9 +103,9 @@ CPU architecture and Python minor version** (some wheels, such as `pydantic_core
|
|
|
97
103
|
one platform only), copy `wheels/` across, and install from it:
|
|
98
104
|
|
|
99
105
|
```bash
|
|
100
|
-
python -m pip download "bantamkit[mcp]==0.35.
|
|
106
|
+
python -m pip download "bantamkit[mcp]==0.35.4" -d wheels
|
|
101
107
|
python -m venv <env>
|
|
102
|
-
<env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.35.
|
|
108
|
+
<env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.35.4"
|
|
103
109
|
<env>/bin/bantamkit-mcp --install cursor
|
|
104
110
|
```
|
|
105
111
|
|
|
@@ -132,7 +138,10 @@ or re-run. The entry's `command` and `args` depend on the install route:
|
|
|
132
138
|
|---|---|---|
|
|
133
139
|
| Python venv, install once | `/absolute/path/to/env/bin/bantamkit-mcp` | `[]` |
|
|
134
140
|
| pipx at every launch | `pipx` | `["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]` |
|
|
135
|
-
|
|
141
|
+
|
|
142
|
+
Both rows are PyPI installs. The npm package records a different `command` and `args`, written
|
|
143
|
+
on [its page](https://www.npmjs.com/package/bantamkit-mcp); the two shapes are not
|
|
144
|
+
interchangeable.
|
|
136
145
|
|
|
137
146
|
To check a recorded command, run it in a terminal: with nothing on stdin it prints
|
|
138
147
|
`usage: bantamkit-mcp …`.
|
|
@@ -338,6 +347,99 @@ a conformance case compares their answers. Three differences are deliberate, eac
|
|
|
338
347
|
- **`build_id`** hashes the executing tree, so it differs by construction; `assets_digest` is
|
|
339
348
|
identical, and that is the one that carries meaning.
|
|
340
349
|
|
|
350
|
+
## Module API
|
|
351
|
+
|
|
352
|
+
The package is a server first, but it is importable too: `import bantamkit` is a supported call,
|
|
353
|
+
and the names behind it are part of what is published.
|
|
354
|
+
|
|
355
|
+
Everything in this section was measured against the **wheel**, not the source tree: a
|
|
356
|
+
`bantamkit-0.35.3-py3-none-any.whl` built with `pip wheel --no-deps --no-build-isolation`,
|
|
357
|
+
installed into a throwaway venv with `--no-index --no-deps`, and imported from a working
|
|
358
|
+
directory outside the checkout (2026-09-21). A name that only exists in `src/` is not API; this
|
|
359
|
+
is what an importer gets.
|
|
360
|
+
|
|
361
|
+
**There is no `exports` map in Python, so nothing is sealed.** The wheel carries **31** modules
|
|
362
|
+
and every one is deep-importable — `from bantamkit.mcpserver import main` resolves, and so does
|
|
363
|
+
`from bantamkit.memory import MemoryStore`. That is the opposite of the npm package, which
|
|
364
|
+
declares a single `.` entry point and refuses every deep import with
|
|
365
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`. Only the names below are *intended* as API; the rest are
|
|
366
|
+
reachable because Python has no way to say otherwise.
|
|
367
|
+
|
|
368
|
+
**`import bantamkit` binds 45 names, of which 30 are values.** The other 15 are submodules bound
|
|
369
|
+
as a side effect of the package's own imports (`agent`, `assets`, `budget`, `client`, `contract`,
|
|
370
|
+
`critique`, `docmanifest`, `docread`, `evalrun`, `filegraph`, `loopguard`, `memory`, `pdfread`,
|
|
371
|
+
`profile`, `textutil`). There is no `__all__`, so `from bantamkit import *` takes all 45.
|
|
372
|
+
|
|
373
|
+
| Module behind it | What it is | Names |
|
|
374
|
+
| --- | --- | --- |
|
|
375
|
+
| `bantamkit.agent` | the tool-calling loop | `Agent`, `AgentResult`, `MaxTurnsExceeded`, `ToolDef` |
|
|
376
|
+
| `bantamkit.client` | the OpenAI-compatible transport and its wire types | `APIError`, `BantamError`, `Message`, `ModelClient`, `OpenAICompatible`, `Response`, `Tool`, `ToolCall`, `TransportError`, `Usage` |
|
|
377
|
+
| `bantamkit.critique` | the critique gate and its rubrics | `CritiqueExhausted`, `CritiqueGate`, `GroundedCritiqueGate`, `Rubric`, `load_rubric` |
|
|
378
|
+
| `bantamkit.evalrun` | the suite runner | `CONFIGS`, `format_report`, `run_suite` |
|
|
379
|
+
| `bantamkit.structured` | schema-constrained output | `StructuredOutputError`, `structured` |
|
|
380
|
+
| `bantamkit.contract` | JSON out of model prose, and evidence rendering | `extract_json`, `render_evidence` |
|
|
381
|
+
| `bantamkit.loopguard` | the repetition cut-off | `LoopGuard` |
|
|
382
|
+
| `bantamkit.filegraph` | the file-access graph | `FileAccessGraph` |
|
|
383
|
+
| `bantamkit.memory` | the memory store | `Memory`, `MemoryStore` |
|
|
384
|
+
| **9 modules** | | **30 values, no `__all__`** |
|
|
385
|
+
|
|
386
|
+
**This is not the npm package's export surface.** Both runtimes serve the same fourteen MCP
|
|
387
|
+
tools, but what each one exports *to an importer* is a different product: here it is the
|
|
388
|
+
agent/critique/eval library above; there it is the memory store, the asset pack, the event log,
|
|
389
|
+
the shift-work tools and a set of CPython-semantics shims — 139 values behind one entry point. Of
|
|
390
|
+
these 30 names exactly **three** are spelled the same on the npm side (`BantamError`, `Memory`,
|
|
391
|
+
`MemoryStore`), and a spelling is not a promise about behaviour. A parity claim about the MCP
|
|
392
|
+
tools is not a parity claim about these.
|
|
393
|
+
|
|
394
|
+
**A worked start.** Copy-paste examples:
|
|
395
|
+
[`examples/`](https://github.com/Ink01101011/bantamkit/tree/main/examples).
|
|
396
|
+
|
|
397
|
+
```python
|
|
398
|
+
from bantamkit import Agent, CritiqueGate, Memory, OpenAICompatible, Tool, ToolDef
|
|
399
|
+
|
|
400
|
+
client = OpenAICompatible(base_url="http://localhost:11434/v1", model="qwen2.5:7b-instruct")
|
|
401
|
+
|
|
402
|
+
price_lookup = ToolDef(
|
|
403
|
+
tool=Tool(
|
|
404
|
+
name="price_lookup",
|
|
405
|
+
description="Get the unit price of an item",
|
|
406
|
+
parameters={
|
|
407
|
+
"type": "object",
|
|
408
|
+
"required": ["item"],
|
|
409
|
+
"properties": {"item": {"type": "string"}},
|
|
410
|
+
},
|
|
411
|
+
),
|
|
412
|
+
handler=lambda item: f"{item} price: 25",
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
agent = Agent(client=client, tools=[price_lookup]).use(
|
|
416
|
+
Memory(store="./.bantam-memory"),
|
|
417
|
+
CritiqueGate("task-completion"),
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
result = agent.run("What does a widget cost? Remember it for next time.")
|
|
421
|
+
print(result.output, result.usage.total)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Which options are worth attaching, measured over 528 runs per model:
|
|
425
|
+
[docs/usage.md → Recommended defaults](https://github.com/Ink01101011/bantamkit/blob/main/docs/usage.md#recommended-defaults).
|
|
426
|
+
|
|
427
|
+
**Rerun the numbers.** Against the published wheel, in a throwaway venv:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
python -m venv /tmp/bk && /tmp/bk/bin/pip install bantamkit
|
|
431
|
+
/tmp/bk/bin/python -c "import bantamkit; print(len([n for n in dir(bantamkit) if not n.startswith('_')]))"
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
It prints `45`. The 30 values alone, without the submodules:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
/tmp/bk/bin/python -c "import bantamkit, types; print(sorted(n for n in dir(bantamkit) if not n.startswith('_') and not isinstance(getattr(bantamkit, n), types.ModuleType)))"
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Both numbers move whenever `src/bantamkit/__init__.py` does, which is why they are quoted with
|
|
441
|
+
the command that prints them rather than kept in prose.
|
|
442
|
+
|
|
341
443
|
## Development
|
|
342
444
|
|
|
343
445
|
```bash
|
|
@@ -11,6 +11,10 @@ The same server in pure Node is on **npm** as
|
|
|
11
11
|
disk and a conformance suite holds them to the same answers, so install whichever your host makes
|
|
12
12
|
easy.
|
|
13
13
|
|
|
14
|
+
**This page is the PyPI package's.** Every command on it runs `bantamkit` from PyPI. The npm
|
|
15
|
+
package is named where the two differ, but its own install, update and CLI commands live on
|
|
16
|
+
[its page](https://www.npmjs.com/package/bantamkit-mcp); run them here and you get nothing.
|
|
17
|
+
|
|
14
18
|
## Contents
|
|
15
19
|
|
|
16
20
|
| Topic | What you'll find |
|
|
@@ -32,6 +36,7 @@ easy.
|
|
|
32
36
|
| [The asset pack](#the-asset-pack) | `--assets-root`, `BANTAMKIT_ASSETS` |
|
|
33
37
|
| [The operator CLI: `python -m bantamkit.memory`](#the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore |
|
|
34
38
|
| [Where the Python and Node servers differ](#where-the-python-and-node-servers-differ) | One store; pdf/.doc/.rtf, CLI name, `build_id` |
|
|
39
|
+
| [Module API](#module-api) | `import bantamkit`: the library half, measured from the wheel |
|
|
35
40
|
| [Development](#development) | Clone, test, lint, conformance |
|
|
36
41
|
| [Documentation](#documentation) | The full docs on GitHub |
|
|
37
42
|
|
|
@@ -69,9 +74,9 @@ CPU architecture and Python minor version** (some wheels, such as `pydantic_core
|
|
|
69
74
|
one platform only), copy `wheels/` across, and install from it:
|
|
70
75
|
|
|
71
76
|
```bash
|
|
72
|
-
python -m pip download "bantamkit[mcp]==0.35.
|
|
77
|
+
python -m pip download "bantamkit[mcp]==0.35.4" -d wheels
|
|
73
78
|
python -m venv <env>
|
|
74
|
-
<env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.35.
|
|
79
|
+
<env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.35.4"
|
|
75
80
|
<env>/bin/bantamkit-mcp --install cursor
|
|
76
81
|
```
|
|
77
82
|
|
|
@@ -104,7 +109,10 @@ or re-run. The entry's `command` and `args` depend on the install route:
|
|
|
104
109
|
|---|---|---|
|
|
105
110
|
| Python venv, install once | `/absolute/path/to/env/bin/bantamkit-mcp` | `[]` |
|
|
106
111
|
| pipx at every launch | `pipx` | `["run", "--spec", "bantamkit[mcp]", "bantamkit-mcp"]` |
|
|
107
|
-
|
|
112
|
+
|
|
113
|
+
Both rows are PyPI installs. The npm package records a different `command` and `args`, written
|
|
114
|
+
on [its page](https://www.npmjs.com/package/bantamkit-mcp); the two shapes are not
|
|
115
|
+
interchangeable.
|
|
108
116
|
|
|
109
117
|
To check a recorded command, run it in a terminal: with nothing on stdin it prints
|
|
110
118
|
`usage: bantamkit-mcp …`.
|
|
@@ -310,6 +318,99 @@ a conformance case compares their answers. Three differences are deliberate, eac
|
|
|
310
318
|
- **`build_id`** hashes the executing tree, so it differs by construction; `assets_digest` is
|
|
311
319
|
identical, and that is the one that carries meaning.
|
|
312
320
|
|
|
321
|
+
## Module API
|
|
322
|
+
|
|
323
|
+
The package is a server first, but it is importable too: `import bantamkit` is a supported call,
|
|
324
|
+
and the names behind it are part of what is published.
|
|
325
|
+
|
|
326
|
+
Everything in this section was measured against the **wheel**, not the source tree: a
|
|
327
|
+
`bantamkit-0.35.3-py3-none-any.whl` built with `pip wheel --no-deps --no-build-isolation`,
|
|
328
|
+
installed into a throwaway venv with `--no-index --no-deps`, and imported from a working
|
|
329
|
+
directory outside the checkout (2026-09-21). A name that only exists in `src/` is not API; this
|
|
330
|
+
is what an importer gets.
|
|
331
|
+
|
|
332
|
+
**There is no `exports` map in Python, so nothing is sealed.** The wheel carries **31** modules
|
|
333
|
+
and every one is deep-importable — `from bantamkit.mcpserver import main` resolves, and so does
|
|
334
|
+
`from bantamkit.memory import MemoryStore`. That is the opposite of the npm package, which
|
|
335
|
+
declares a single `.` entry point and refuses every deep import with
|
|
336
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`. Only the names below are *intended* as API; the rest are
|
|
337
|
+
reachable because Python has no way to say otherwise.
|
|
338
|
+
|
|
339
|
+
**`import bantamkit` binds 45 names, of which 30 are values.** The other 15 are submodules bound
|
|
340
|
+
as a side effect of the package's own imports (`agent`, `assets`, `budget`, `client`, `contract`,
|
|
341
|
+
`critique`, `docmanifest`, `docread`, `evalrun`, `filegraph`, `loopguard`, `memory`, `pdfread`,
|
|
342
|
+
`profile`, `textutil`). There is no `__all__`, so `from bantamkit import *` takes all 45.
|
|
343
|
+
|
|
344
|
+
| Module behind it | What it is | Names |
|
|
345
|
+
| --- | --- | --- |
|
|
346
|
+
| `bantamkit.agent` | the tool-calling loop | `Agent`, `AgentResult`, `MaxTurnsExceeded`, `ToolDef` |
|
|
347
|
+
| `bantamkit.client` | the OpenAI-compatible transport and its wire types | `APIError`, `BantamError`, `Message`, `ModelClient`, `OpenAICompatible`, `Response`, `Tool`, `ToolCall`, `TransportError`, `Usage` |
|
|
348
|
+
| `bantamkit.critique` | the critique gate and its rubrics | `CritiqueExhausted`, `CritiqueGate`, `GroundedCritiqueGate`, `Rubric`, `load_rubric` |
|
|
349
|
+
| `bantamkit.evalrun` | the suite runner | `CONFIGS`, `format_report`, `run_suite` |
|
|
350
|
+
| `bantamkit.structured` | schema-constrained output | `StructuredOutputError`, `structured` |
|
|
351
|
+
| `bantamkit.contract` | JSON out of model prose, and evidence rendering | `extract_json`, `render_evidence` |
|
|
352
|
+
| `bantamkit.loopguard` | the repetition cut-off | `LoopGuard` |
|
|
353
|
+
| `bantamkit.filegraph` | the file-access graph | `FileAccessGraph` |
|
|
354
|
+
| `bantamkit.memory` | the memory store | `Memory`, `MemoryStore` |
|
|
355
|
+
| **9 modules** | | **30 values, no `__all__`** |
|
|
356
|
+
|
|
357
|
+
**This is not the npm package's export surface.** Both runtimes serve the same fourteen MCP
|
|
358
|
+
tools, but what each one exports *to an importer* is a different product: here it is the
|
|
359
|
+
agent/critique/eval library above; there it is the memory store, the asset pack, the event log,
|
|
360
|
+
the shift-work tools and a set of CPython-semantics shims — 139 values behind one entry point. Of
|
|
361
|
+
these 30 names exactly **three** are spelled the same on the npm side (`BantamError`, `Memory`,
|
|
362
|
+
`MemoryStore`), and a spelling is not a promise about behaviour. A parity claim about the MCP
|
|
363
|
+
tools is not a parity claim about these.
|
|
364
|
+
|
|
365
|
+
**A worked start.** Copy-paste examples:
|
|
366
|
+
[`examples/`](https://github.com/Ink01101011/bantamkit/tree/main/examples).
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
from bantamkit import Agent, CritiqueGate, Memory, OpenAICompatible, Tool, ToolDef
|
|
370
|
+
|
|
371
|
+
client = OpenAICompatible(base_url="http://localhost:11434/v1", model="qwen2.5:7b-instruct")
|
|
372
|
+
|
|
373
|
+
price_lookup = ToolDef(
|
|
374
|
+
tool=Tool(
|
|
375
|
+
name="price_lookup",
|
|
376
|
+
description="Get the unit price of an item",
|
|
377
|
+
parameters={
|
|
378
|
+
"type": "object",
|
|
379
|
+
"required": ["item"],
|
|
380
|
+
"properties": {"item": {"type": "string"}},
|
|
381
|
+
},
|
|
382
|
+
),
|
|
383
|
+
handler=lambda item: f"{item} price: 25",
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
agent = Agent(client=client, tools=[price_lookup]).use(
|
|
387
|
+
Memory(store="./.bantam-memory"),
|
|
388
|
+
CritiqueGate("task-completion"),
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
result = agent.run("What does a widget cost? Remember it for next time.")
|
|
392
|
+
print(result.output, result.usage.total)
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Which options are worth attaching, measured over 528 runs per model:
|
|
396
|
+
[docs/usage.md → Recommended defaults](https://github.com/Ink01101011/bantamkit/blob/main/docs/usage.md#recommended-defaults).
|
|
397
|
+
|
|
398
|
+
**Rerun the numbers.** Against the published wheel, in a throwaway venv:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
python -m venv /tmp/bk && /tmp/bk/bin/pip install bantamkit
|
|
402
|
+
/tmp/bk/bin/python -c "import bantamkit; print(len([n for n in dir(bantamkit) if not n.startswith('_')]))"
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
It prints `45`. The 30 values alone, without the submodules:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
/tmp/bk/bin/python -c "import bantamkit, types; print(sorted(n for n in dir(bantamkit) if not n.startswith('_') and not isinstance(getattr(bantamkit, n), types.ModuleType)))"
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Both numbers move whenever `src/bantamkit/__init__.py` does, which is why they are quoted with
|
|
412
|
+
the command that prints them rather than kept in prose.
|
|
413
|
+
|
|
313
414
|
## Development
|
|
314
415
|
|
|
315
416
|
```bash
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shiftwork_clock_in",
|
|
3
|
+
"description": "Shift-work clock-in: schema-validate the checkpoint file and return the brief for the unit at plan.cursor — {unit, role, invariants, handoff, do_not, files} — to hand to the spawned agent verbatim. The unit briefed is the one at plan.cursor, or, when unit_id is given, that unit — which must appear in shiftwork_plan's `ready`, the batch the dependency graph says may run now. A unit_id that is not ready, including one naming no unit, is refused with {\"result\": \"error\", \"reason\": \"unit <id> is not ready; ready is <a, b>\"}, and the refusals of the batch view itself (cycle, unknown dependency, unreadable checkpoint) pass through verbatim. Clock-in still never moves plan.cursor; clock_out does. Structured refusals, never exceptions: result=escalate when handoff.open_questions is non-empty, result=success when every unit is done or dropped, result=error when the checkpoint fails validation. Clock-in also WRITES: on result=brief, and only then, it appends one line {event: brief, ts, unit, role} to <checkpoint>.log.jsonl — best-effort: a log it cannot write costs the brief nothing (the brief still returns, no error, only the record is lost). clock_out reads those lines back to write `briefed` on every accounting line, so the ledger is no longer one line per clock-out; a brief line carries `event` and no `status`. See docs/shiftwork.md.",
|
|
4
|
+
"surfaces": [
|
|
5
|
+
"mcp"
|
|
6
|
+
],
|
|
7
|
+
"parameters": {
|
|
8
|
+
"properties": {
|
|
9
|
+
"checkpoint": {
|
|
10
|
+
"title": "Checkpoint",
|
|
11
|
+
"type": "string"
|
|
12
|
+
},
|
|
13
|
+
"unit_id": {
|
|
14
|
+
"anyOf": [
|
|
15
|
+
{
|
|
16
|
+
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "null"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"default": null,
|
|
23
|
+
"title": "Unit Id"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": [
|
|
27
|
+
"checkpoint"
|
|
28
|
+
],
|
|
29
|
+
"type": "object",
|
|
30
|
+
"title": "shiftwork_clock_inArguments"
|
|
31
|
+
},
|
|
32
|
+
"output_schema": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"additionalProperties": true,
|
|
35
|
+
"title": "shiftwork_clock_inDictOutput"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shiftwork_clock_out",
|
|
3
|
-
"description": "Shift-work clock-out: record a finished unit — set its status, advance plan.cursor, merge handoff_patch, push history_entry onto the 5-entry ring — validating the whole mutated document against the checkpoint schema BEFORE an atomic write (a failure writes nothing and returns result=error). `unit_id` must be `plan.cursor
|
|
3
|
+
"description": "Shift-work clock-out: record a finished unit — set its status, advance plan.cursor, merge handoff_patch, push history_entry onto the 5-entry ring — validating the whole mutated document against the checkpoint schema BEFORE an atomic write (a failure writes nothing and returns result=error). `unit_id` must be `plan.cursor` — which needs no brief, clocking out with briefed=false — OR a unit briefed since its own last clock-out; any other id keeps its refusal (`unit X is not the cursor unit Y`). plan.cursor then advances to the head of the ready batch recomputed on the mutated document, falling back to plan.units order over the remaining non-terminal units when the graph cannot batch (cycle or unknown dependency), and to unit_id when none remain. `handoff_patch` and `history_entry` are both required arguments: `handoff_patch` is shallow-merged into `handoff` and takes only its four keys (pass `{}` to leave it unchanged); `history_entry` needs `unit` and `outcome`; `status` is one of the five unit statuses — a value outside these shapes is refused by the schema check, nothing written. Every success appends one accounting line (unit, role, status, ts, briefed, plus your accounting fields, e.g. tokens/duration_ms/model) to <checkpoint>.log.jsonl, beside the brief lines clock_in writes (a brief line carries `event` and no `status`). `accounting` is optional: null, the default, logs a line with no cost figures at all; a non-null line must fit the accounting shape below. `briefed` is written by the runtime, never taken from you: true when a brief was issued for this unit since its LAST clock-out (not ever), so a unit re-run after a blocked clock-out reads false. If job.roles names this unit's role, accounting.model must be one of that role's model identifiers, spelled exactly, or nothing is written — see the `model` property below.",
|
|
4
4
|
"surfaces": [
|
|
5
5
|
"mcp"
|
|
6
6
|
],
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"unit_id": {
|
|
14
14
|
"title": "Unit Id",
|
|
15
15
|
"type": "string",
|
|
16
|
-
"description": "The unit being clocked out. Must
|
|
16
|
+
"description": "The unit being clocked out. Must be plan.cursor, or a unit briefed since its own last clock-out: clock_in briefs the cursor unit by default and, when its unit_id names one, any unit shiftwork_plan reports in `ready` — and that brief is what lets clock_out accept a unit the cursor is not on."
|
|
17
17
|
},
|
|
18
18
|
"status": {
|
|
19
19
|
"title": "Status",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shiftwork_plan",
|
|
3
|
+
"description": "Shift-work plan: read-only batch view of a checkpoint — which units its `depends_on` graph permits to run in parallel. Answers `{\"result\": \"plan\", \"batches\", \"ready\", \"sequence\", \"width\", \"cursor\"}`: `ready` is `batches[0]`, the units whose dependencies are all satisfied, and `width` is the largest batch length, the widest fan-out. A `ready` member beyond the cursor is clockable, but only in that order: shiftwork_clock_in briefs any unit in `ready` when `unit_id` names it, and shiftwork_clock_out then accepts that unit because it was briefed — an id that is neither the cursor nor briefed since its own last clock-out is still refused. Units with status `done` or `dropped` are satisfied — dropped from the graph, and edges pointing at them treated as already resolved; `todo`, `in_progress` and `blocked` stay in it. Every unit has priority 0, because the checkpoint schema has no priority field, so order inside a batch is `plan.units` order. Same refusal sentences as `work_plan` for a duplicate id, an unknown dependency or a cycle, and the same refusals `shiftwork_status` gives for a checkpoint it cannot read. It reports what the dependency graph permits; it does not move the cursor, which is echoed unchanged so the single-pointer contract and the batch view can be read side by side. An orchestrator stays responsible for what it actually dispatches: `depends_on` encodes logical order, not file contention. Never mutates.",
|
|
4
|
+
"surfaces": [
|
|
5
|
+
"mcp"
|
|
6
|
+
],
|
|
7
|
+
"parameters": {
|
|
8
|
+
"properties": {
|
|
9
|
+
"checkpoint": {
|
|
10
|
+
"title": "Checkpoint",
|
|
11
|
+
"type": "string"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": [
|
|
15
|
+
"checkpoint"
|
|
16
|
+
],
|
|
17
|
+
"type": "object",
|
|
18
|
+
"title": "shiftwork_planArguments"
|
|
19
|
+
},
|
|
20
|
+
"output_schema": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": true,
|
|
23
|
+
"title": "shiftwork_planDictOutput"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -68,7 +68,10 @@ dependencies = ["httpx>=0.27", "jsonschema>=4.21", "pyyaml>=6.0"]
|
|
|
68
68
|
# installs the backend into an isolated build env, never into the target env, so
|
|
69
69
|
# without this declaration the bar would silently skip in exactly the environment
|
|
70
70
|
# CI runs (`pip install -e "runtime-py[dev,mcp]"`). Declared here so it runs.
|
|
71
|
-
|
|
71
|
+
# `build` is here because `tools/release/publish.sh` hard-requires it (it refuses at
|
|
72
|
+
# preflight with "the repo venv cannot 'import build'") and nothing declared it, so every
|
|
73
|
+
# release hit the same refusal and fixed it by hand. Added 2026-09-21, J62-15.
|
|
74
|
+
dev = ["pytest>=8.0", "ruff>=0.4", "hatchling>=1.24", "build>=1.0"]
|
|
72
75
|
# Upper bound measured, not guessed: 2.0.0 and 2.0.1 wrap a tool crash as
|
|
73
76
|
# `Error executing tool <name>: <exc>`, which runtime-ts/src/mcp/server.ts mirrors.
|
|
74
77
|
# 2.1.0 added an UnexpectedToolError branch that drops the `: <exc>` suffix, so the
|
|
@@ -29,4 +29,4 @@ from bantamkit.structured import StructuredOutputError, extract_json, structured
|
|
|
29
29
|
# file as its dynamic version source, so the wheel's metadata and the string the MCP
|
|
30
30
|
# server advertises are the same committed bytes, and neither is a function of when
|
|
31
31
|
# someone last ran `pip`.
|
|
32
|
-
__version__ = "0.35.
|
|
32
|
+
__version__ = "0.35.4"
|