agentic-mcp-solver 4.2.0__tar.gz → 4.3.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.
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/CHANGELOG.md +57 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/INSTALL.md +3 -4
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/PKG-INFO +7 -7
- agentic_mcp_solver-4.3.0/minion/CHANGELOG.md +109 -0
- agentic_mcp_solver-4.3.0/minion/README.md +136 -0
- agentic_mcp_solver-4.3.0/minion/e2e_tests/runs/multi_step/config.json +10 -0
- agentic_mcp_solver-4.3.0/minion/e2e_tests/runs/no_tools/config.json +10 -0
- agentic_mcp_solver-4.3.0/minion/e2e_tests/runs/simple_add/config.json +10 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/test_e2e.py +1 -1
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/pyproject.toml +2 -2
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/__init__.py +7 -3
- agentic_mcp_solver-4.3.0/minion/src/mcp_minion/agent.py +948 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/artifacts.py +44 -17
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/cli.py +118 -67
- agentic_mcp_solver-4.3.0/minion/src/mcp_minion/env.py +37 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/logging.py +31 -1
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/mcp_client.py +133 -61
- agentic_mcp_solver-4.3.0/minion/src/mcp_minion/test_mcp_server.py +148 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/src/mcp_minion/tools.py +15 -4
- agentic_mcp_solver-4.3.0/minion/tests/test_agent.py +1060 -0
- agentic_mcp_solver-4.3.0/minion/tests/test_artifacts.py +242 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/tests/test_cli.py +358 -62
- agentic_mcp_solver-4.3.0/minion/tests/test_kernel.py +320 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/tests/test_logging.py +9 -0
- agentic_mcp_solver-4.3.0/minion/tests/test_mcp_client.py +321 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/tests/test_tools.py +16 -17
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/pyproject.toml +32 -4
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/agent/cli.py +241 -152
- agentic_mcp_solver-4.3.0/src/mcp_solver/agent/engine.py +263 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/agent/harness.py +99 -23
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/agent/mcp_server.py +45 -67
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/agent/runfolder.py +67 -16
- agentic_mcp_solver-4.3.0/tests/unit/test_cli.py +840 -0
- agentic_mcp_solver-4.3.0/tests/unit/test_engine.py +187 -0
- agentic_mcp_solver-4.3.0/tests/unit/test_engine_contract.py +175 -0
- agentic_mcp_solver-4.3.0/tests/unit/test_harness.py +176 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/unit/test_mcp_server.py +78 -41
- agentic_mcp_solver-4.3.0/tests/unit/test_runfolder.py +153 -0
- agentic_mcp_solver-4.2.0/minion/CHANGELOG.md +0 -34
- agentic_mcp_solver-4.2.0/minion/README.md +0 -143
- agentic_mcp_solver-4.2.0/minion/e2e_tests/runs/multi_step/config.json +0 -6
- agentic_mcp_solver-4.2.0/minion/e2e_tests/runs/no_tools/config.json +0 -6
- agentic_mcp_solver-4.2.0/minion/e2e_tests/runs/simple_add/config.json +0 -6
- agentic_mcp_solver-4.2.0/minion/src/mcp_minion/agent.py +0 -593
- agentic_mcp_solver-4.2.0/minion/src/mcp_minion/test_mcp_server.py +0 -133
- agentic_mcp_solver-4.2.0/minion/tests/test_agent.py +0 -312
- agentic_mcp_solver-4.2.0/minion/tests/test_artifacts.py +0 -81
- agentic_mcp_solver-4.2.0/minion/tests/test_kernel.py +0 -124
- agentic_mcp_solver-4.2.0/minion/tests/test_mcp_client.py +0 -170
- agentic_mcp_solver-4.2.0/tests/unit/test_cli.py +0 -411
- agentic_mcp_solver-4.2.0/tests/unit/test_runfolder.py +0 -57
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/.gitignore +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/LICENSE +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/README.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/.gitignore +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/LICENSE +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/runs/mcp_ipython/config.json +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/runs/mcp_ipython/task.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/runs/multi_step/task.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/runs/no_tools/task.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/runs/simple_add/task.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/e2e_tests/test_problems_e2e.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/tests/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/minion/tests/test_system_prompt.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/agent/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/helpers/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/helpers/maxsat.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/helpers/pysat.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/helpers/z3.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/clingo.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/cpmpy.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/didp.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/maxsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/pysat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/src/mcp_solver/templates/z3.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/README.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/__init__.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/birds_fly.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/birds_fly_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/company_controls.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/company_controls_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/package_status_unsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/package_status_unsat_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/party_invitation.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/party_invitation_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/shift_assignment.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/shift_assignment_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/clingo/test.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/carpet_cutting.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/carpet_cutting_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/tsp.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/tsp_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/university_scheduling.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/university_scheduling_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/university_scheduling_unsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/university_scheduling_unsat_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/zebra.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/cpmpy/zebra_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/knapsack.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/knapsack_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/talent_scheduling.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/talent_scheduling_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/tardiness.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/tardiness_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/tsptw.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/didp/tsptw_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/equipment_purchase.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/equipment_purchase_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/network_monitoring.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/network_monitoring_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/package_selection.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/package_selection_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/task_assignment.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/task_assignment_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/test.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/workshop_scheduling_unsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/maxsat/workshop_scheduling_unsat_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/equitable_coloring_hajos.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/equitable_coloring_hajos_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/furniture_arrangement.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/furniture_arrangement_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/n_queens.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/n_queens_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/no_three_in_line_5x5.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/no_three_in_line_5x5_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/petersen_12_coloring_unsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/petersen_12_coloring_unsat_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/sudoku_16x16.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/sudoku_16x16_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/pysat/test.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/array_property_verifier.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/array_property_verifier_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/bounded_sum_unsat.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/bounded_sum_unsat_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/cryptarithmetic.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/cryptarithmetic_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/processor_verification.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/processor_verification_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/sos_induction.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/sos_induction_ground_truth.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/problems/z3/test.md +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/unit/test_didp_backend.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/unit/test_helpers_maxsat.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/unit/test_helpers_pysat.py +0 -0
- {agentic_mcp_solver-4.2.0 → agentic_mcp_solver-4.3.0}/tests/unit/test_helpers_z3.py +0 -0
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
### [4.3.0] - 2026-11-14
|
|
4
|
+
|
|
5
|
+
- **Behavior Change:** Requires the MCP Python SDK 2.x (`mcp>=2,<3`; 1.x is no
|
|
6
|
+
longer supported), agentic-python-coder 3.5.0 and mcp-minion 0.3.0.
|
|
7
|
+
- **Behavior Change:** `mcp-solver` caps a run at 2,000,000 total (input +
|
|
8
|
+
output) tokens by default, checked after each step; `--token-limit N`
|
|
9
|
+
changes the cap (`0` = no limit). A run stopped by the cap without an
|
|
10
|
+
accepted submission exits with code 3; the stats JSON reports
|
|
11
|
+
`token_limit_reached` and `token_limit`. `mcp-solver-bench --token-limit`
|
|
12
|
+
passes the value to each solve.
|
|
13
|
+
- **Behavior Change:** New exit code 4: the agent stopped early with an error
|
|
14
|
+
(for example an LLM API failure) after an accepted submission. That
|
|
15
|
+
submission is saved and re-executed, and exit 4 replaces 0 when it runs
|
|
16
|
+
cleanly, since it may not be the agent's final, verified program. Such an
|
|
17
|
+
error before any accepted submission, a failed kernel setup, or an
|
|
18
|
+
exception during the solve exits with 1 and a one-line message instead of
|
|
19
|
+
a traceback.
|
|
20
|
+
- **Behavior Change:** The engine, its kernels and the CLI's re-execution of
|
|
21
|
+
the submitted program (in `mcp-solver` and `mcp-solver-serve`) get a
|
|
22
|
+
filtered environment: the mcp library's default whitelist (`PATH`, `HOME`,
|
|
23
|
+
...), locale, temp-dir, proxy, CA-bundle and native-build variables, and
|
|
24
|
+
variables starting with `UV_`, `CODER_`, `MCP_SOLVER_`, `XDG_` or `LC_`
|
|
25
|
+
unless the name contains `KEY`, `TOKEN`, `SECRET`, `PASSWORD` or
|
|
26
|
+
`CREDENTIAL` (`UV_ENV_FILE` is dropped too). Other variables no longer
|
|
27
|
+
reach the kernel. This keeps API keys out of model-written code; it is
|
|
28
|
+
hygiene, not a sandbox.
|
|
29
|
+
- **Behavior Change:** `submit_code` on the toolkit server returns an MCP
|
|
30
|
+
error result (`isError`) carrying the engine's reason for a rejected
|
|
31
|
+
program, instead of a normal result with `{"ok": false, ...}`.
|
|
32
|
+
- **New Feature:** `--model` accepts a model config file
|
|
33
|
+
(`--model my_model.json`) in the engine's format, and aliases resolve
|
|
34
|
+
through the engine's `load_model_config`, so a local `<alias>.json`
|
|
35
|
+
overrides a bundled one. A model config may set `base_url` and
|
|
36
|
+
`api_key_env` (another OpenAI-compatible endpoint and the variable that
|
|
37
|
+
holds its key). Its `reasoning`, `provider`, `top_k` and `request_timeout`
|
|
38
|
+
settings are now sent; before they were dropped.
|
|
39
|
+
- **Behavior Change:** `mcp-solver-runfolder --model` resolves aliases and
|
|
40
|
+
model files like the CLI. A full OpenRouter ID gets no sampling settings
|
|
41
|
+
(it used to get `temperature 0` and `max_tokens 8192`), a model with
|
|
42
|
+
`base_url` or `api_key_env` is rejected, and the generated config sets
|
|
43
|
+
`agent.max_tool_result_chars` to at least twice the backend template's
|
|
44
|
+
length (minimum 64,000).
|
|
45
|
+
- **Improvement:** `mcp-solver-bench` runs each solve with its own run
|
|
46
|
+
directory as working directory (path arguments made absolute), saves the
|
|
47
|
+
solve's stderr to `cli_stderr.txt` there, and copies its last 20 lines
|
|
48
|
+
into the result row (`stderr_tail`) of a failed or invalid run.
|
|
49
|
+
- **Improvement:** The CLI and the toolkit server check that the engine
|
|
50
|
+
offers all five tools they use (`python_exec`, `python_reset`,
|
|
51
|
+
`python_status`, `python_interrupt`, `submit_code`) and name the missing
|
|
52
|
+
ones together with the required engine version.
|
|
53
|
+
- **Fix:** The pysat and maxsat kernels install `python-sat[pb]` instead of
|
|
54
|
+
`python-sat` and `pypblib`. The `[pb]` extra installs pindakaas, without
|
|
55
|
+
which every `pysat.pb.PBEnc` encoding call raises.
|
|
56
|
+
- **Fix:** In dev mode, newly started kernels pick up edits to the helper
|
|
57
|
+
sources (the uv build cache is keyed on `src/**/*.py`, not only on
|
|
58
|
+
`pyproject.toml`).
|
|
59
|
+
|
|
3
60
|
### [4.2.0] - 2026-11-13
|
|
4
61
|
|
|
5
62
|
- **Major Change:** Published on PyPI as `agentic-mcp-solver`, since the name
|
|
@@ -186,11 +186,10 @@ You installed the bare package without the product layer. Install the `[agent]`
|
|
|
186
186
|
extra: `uv pip install "agentic-mcp-solver[agent]"`, or
|
|
187
187
|
`uv pip install -e ".[agent]"` from a checkout (see [Install](#install)).
|
|
188
188
|
|
|
189
|
-
**`the ipython_mcp
|
|
190
|
-
|
|
191
|
-
Your installed `agentic-python-coder` is older than 3.4.3, or missing from
|
|
189
|
+
**`the ipython_mcp engine lacks the tools ...`** (CLI and server)
|
|
190
|
+
Your installed `agentic-python-coder` is older than 3.5.0, or missing from
|
|
192
191
|
the environment the server runs in. Upgrade it:
|
|
193
|
-
`uv pip install "agentic-python-coder>=3.
|
|
192
|
+
`uv pip install "agentic-python-coder>=3.5.0"` (or `-e` from a checkout).
|
|
194
193
|
|
|
195
194
|
**`uv: command not found` (or the solve fails to start a kernel).**
|
|
196
195
|
uv is missing from your PATH. Install it (see Prerequisites) and make sure its
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentic-mcp-solver
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: LLM-driven constraint solving (SAT, MaxSAT, SMT, CP, ASP) on top of agentic-python-coder
|
|
5
5
|
Author-email: Stefan Szeider <stefan@szeider.net>
|
|
6
6
|
License: MIT
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: <3.15,>=3.13
|
|
9
9
|
Provides-Extra: agent
|
|
10
|
-
Requires-Dist: agentic-python-coder>=3.
|
|
11
|
-
Requires-Dist: mcp-minion>=0.
|
|
12
|
-
Requires-Dist: mcp<3,>=
|
|
10
|
+
Requires-Dist: agentic-python-coder>=3.5.0; extra == 'agent'
|
|
11
|
+
Requires-Dist: mcp-minion>=0.3.0; extra == 'agent'
|
|
12
|
+
Requires-Dist: mcp<3,>=2; extra == 'agent'
|
|
13
13
|
Requires-Dist: python-dotenv>=1.0.0; extra == 'agent'
|
|
14
14
|
Provides-Extra: all
|
|
15
|
-
Requires-Dist: agentic-python-coder>=3.
|
|
15
|
+
Requires-Dist: agentic-python-coder>=3.5.0; extra == 'all'
|
|
16
16
|
Requires-Dist: clingo>=5.8.0; extra == 'all'
|
|
17
17
|
Requires-Dist: cpmpy>=0.9.24; extra == 'all'
|
|
18
18
|
Requires-Dist: didppy<0.12,>=0.11.1; extra == 'all'
|
|
19
|
-
Requires-Dist: mcp-minion>=0.
|
|
20
|
-
Requires-Dist: mcp<3,>=
|
|
19
|
+
Requires-Dist: mcp-minion>=0.3.0; extra == 'all'
|
|
20
|
+
Requires-Dist: mcp<3,>=2; extra == 'all'
|
|
21
21
|
Requires-Dist: pytest-asyncio>=0.26; extra == 'all'
|
|
22
22
|
Requires-Dist: pytest>=8.3.5; extra == 'all'
|
|
23
23
|
Requires-Dist: python-dotenv>=1.0.0; extra == 'all'
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Changes to the `mcp-minion` package. The monorepo's root `CHANGELOG.md`
|
|
4
|
+
tracks `mcp-solver` releases, which version independently of this package.
|
|
5
|
+
|
|
6
|
+
### [0.3.0] - 2026-11-14
|
|
7
|
+
|
|
8
|
+
- **Behavior Change:** `MCPManager.call_tool` returns a `ToolOutcome`
|
|
9
|
+
(`text`, `is_error`, `links`) instead of a JSON string `{"result": ...}` or
|
|
10
|
+
`{"error": ...}`. An MCP `isError` result and client-side failures (unknown
|
|
11
|
+
tool, non-object arguments, server not connected, timeout, transport
|
|
12
|
+
error) come back with `is_error` set; nothing is raised for them.
|
|
13
|
+
`Tool.execute` returns a `ToolOutcome` too (a string return value is the
|
|
14
|
+
text, other values are JSON-encoded). The model sees the text, prefixed
|
|
15
|
+
with `ERROR: ` for an error outcome.
|
|
16
|
+
- **Behavior Change:** Step records (`AgentResult.steps` and the run log)
|
|
17
|
+
hold each tool call as `{"name", "arguments", "result", "is_error"}`, where
|
|
18
|
+
`result` is the plain tool text, no longer a JSON envelope. Steps carry
|
|
19
|
+
`reasoning_details` or `reasoning` when the model returns them, and a step
|
|
20
|
+
cut off at `max_tokens` carries `truncated: true`. The run log also
|
|
21
|
+
records `system_prompt` and `kernel_setup`. `extract_last_submission`
|
|
22
|
+
reads the new records and run logs of 0.2.x.
|
|
23
|
+
- **Behavior Change:** An LLM API failure no longer raises out of
|
|
24
|
+
`run_async`. The run ends with `AgentResult.error` set (one line with the
|
|
25
|
+
exception type), the steps and token totals so far, and the answer
|
|
26
|
+
`[Agent stopped: LLM call failed: ...]`; the CLI then exits with 1. Error
|
|
27
|
+
responses the SDK parses without raising (HTTP 200 with an error body,
|
|
28
|
+
`finish_reason: "error"`, malformed or non-JSON bodies) are retried 3
|
|
29
|
+
times, after 5, 10 and 15 seconds, before the run ends this way.
|
|
30
|
+
- **Behavior Change:** The flat `config.json` format (`modelstring`,
|
|
31
|
+
top-level `max_steps`, `temperature`, ...) is no longer read; a flat
|
|
32
|
+
config or any unknown top-level key is an error. New keys in the nested
|
|
33
|
+
format: `model.reasoning`, `model.provider`, `model.top_k` and
|
|
34
|
+
`model.extra_body` (sent in the request body), `model.request_timeout`,
|
|
35
|
+
`agent.max_tool_result_chars`, and `cwd` for an MCP server.
|
|
36
|
+
- **Behavior Change:** Requires the MCP Python SDK 2.x (`mcp>=2,<3`); 1.x
|
|
37
|
+
is no longer supported.
|
|
38
|
+
- **Behavior Change:** A server's `env` in `mcpServers` is merged over the
|
|
39
|
+
mcp library's default environment whitelist (`PATH`, `HOME`, ...) instead
|
|
40
|
+
of over the full parent environment, so other variables (API keys, for
|
|
41
|
+
instance) reach the server only when listed. A server without `env` gets
|
|
42
|
+
the whitelist, as before.
|
|
43
|
+
- **Behavior Change:** Tool results longer than
|
|
44
|
+
`agent.max_tool_result_chars` (default 64,000; `0` disables the cut) reach
|
|
45
|
+
the model as head and tail around a marker line; step records and the run
|
|
46
|
+
log keep the full text.
|
|
47
|
+
- **Behavior Change:** With `packages` configured and a server offering
|
|
48
|
+
`python_reset`, the kernel is set up with those packages at the start of
|
|
49
|
+
the run, before the first LLM call (previously before the first
|
|
50
|
+
`python_exec`), and a failed setup ends the run with `AgentResult.error`.
|
|
51
|
+
The tracked `kernel_id` is added to every kernel tool call that lacks one
|
|
52
|
+
(`python_exec`, `python_reset`, `python_status`, `python_interrupt`), so a
|
|
53
|
+
`python_reset` from the model restarts the same kernel; a model reset
|
|
54
|
+
with its own `packages` list keeps the configured packages.
|
|
55
|
+
- **Behavior Change:** The `reasoning_details` (or `reasoning`) of each
|
|
56
|
+
assistant message are replayed unmodified in the conversation history, as
|
|
57
|
+
OpenRouter requires for reasoning models.
|
|
58
|
+
- **Behavior Change:** The agent calls the API through `AsyncOpenAI`, with
|
|
59
|
+
one client created per run and closed when the run ends, so one `Agent`
|
|
60
|
+
can run several times and LLM calls no longer block the event loop. A
|
|
61
|
+
client set on `agent.client` is used for every run and not closed; it
|
|
62
|
+
must provide an async `chat.completions.create`. The
|
|
63
|
+
`Agent.SYSTEM_PROMPT_BASE` class attribute is gone; use the module-level
|
|
64
|
+
`SYSTEM_PROMPT_BASE`.
|
|
65
|
+
- **Behavior Change:** The CLI offers its arithmetic demo tools only when
|
|
66
|
+
no MCP server is configured.
|
|
67
|
+
- **New Feature:** Server instructions from the MCP `initialize` result
|
|
68
|
+
appear in the system prompt. Image, audio and blob content renders as a
|
|
69
|
+
one-line note (type, MIME type, size) instead of base64 or an object repr.
|
|
70
|
+
- **New Feature:** `mcp_minion.find_api_key()` looks the key up in the
|
|
71
|
+
environment, a run folder's `.env`, extra dotenv files and
|
|
72
|
+
`~/.mcp-minion`, without loading the files into `os.environ`; the CLI uses
|
|
73
|
+
it.
|
|
74
|
+
- **Fix:** A rejected `submit_code` call (`{"ok": false, ...}`) is no longer
|
|
75
|
+
taken as the last submission. A reply cut off at `max_tokens` without
|
|
76
|
+
tool calls is no longer accepted as the final answer; the model is asked
|
|
77
|
+
to continue. Missing or empty tool arguments count as `{}`, arguments
|
|
78
|
+
that are not a JSON object give an error result, and the history echoes
|
|
79
|
+
valid JSON arguments back to the API.
|
|
80
|
+
|
|
81
|
+
### [0.2.2] - 2026-11-13
|
|
82
|
+
|
|
83
|
+
- **New Feature:** Supports the MCP Python SDK 2.x alongside 1.x
|
|
84
|
+
(`mcp>=1.25.0,<3`): paginated listing through `PaginatedRequestParams`,
|
|
85
|
+
protocol fields read under both the 2.x snake_case and the 1.x camelCase
|
|
86
|
+
names, and `read_resource` called with a plain string URI.
|
|
87
|
+
- **Behavior Change:** Requires Python 3.13 or 3.14 (`>=3.13,<3.15`).
|
|
88
|
+
|
|
89
|
+
### [0.2.1] - 2026-08-04
|
|
90
|
+
|
|
91
|
+
- **Fix:** Pin `mcp>=1.25.0,<2`. The `mcp` 2.0.0 SDK changed the client API
|
|
92
|
+
(`ClientSession.list_tools` no longer takes `cursor`), so fresh installs of
|
|
93
|
+
0.1.0 and 0.2.0 failed to connect to any MCP server. The workspace lockfile
|
|
94
|
+
masked this by resolving `mcp` 1.28.1.
|
|
95
|
+
|
|
96
|
+
### [0.2.0] - 2026-08-04
|
|
97
|
+
|
|
98
|
+
- **New Feature:** Per-run token cap, `agent.max_total_tokens` in
|
|
99
|
+
`config.json` (absent or `0` = unlimited). The cumulative input+output
|
|
100
|
+
tokens are checked after each completed step; once they exceed the cap the
|
|
101
|
+
loop stops, the answer becomes `[Agent stopped: per-run token cap of N
|
|
102
|
+
exceeded (cumulative M)]`, and the run log records `token_cap_reached`
|
|
103
|
+
(on the last step and in the result). `max_steps` alone does not bound
|
|
104
|
+
spending, since one step can be arbitrarily expensive.
|
|
105
|
+
- **Behavior Change:** A configured MCP server that fails to start now aborts
|
|
106
|
+
the run with a `RuntimeError` naming the server and the underlying error,
|
|
107
|
+
after closing any servers already started. Previously the failure was a
|
|
108
|
+
warning on stderr and the agent continued with a reduced tool set, which
|
|
109
|
+
produced plausible-looking but unusable runs.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# mcp-minion
|
|
2
|
+
|
|
3
|
+
A minimal ReAct agent that drives one or more [MCP](https://modelcontextprotocol.io)
|
|
4
|
+
servers through an OpenAI-compatible API (OpenRouter by default). It reads a
|
|
5
|
+
task from a *run folder*, loops "think → call tool → observe" until the model
|
|
6
|
+
produces a final answer, and writes a complete JSON log of the run.
|
|
7
|
+
|
|
8
|
+
`mcp-minion` is developed in the [mcp-solver](https://github.com/szeider/mcp-solver)
|
|
9
|
+
monorepo, where it runs solver templates over code-execution MCP servers, but
|
|
10
|
+
it has no dependency on the solver and works with any MCP server. It requires
|
|
11
|
+
Python 3.13 or 3.14 and the MCP Python SDK 2.x.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv tool install mcp-minion # the mcp-minion command
|
|
17
|
+
uv add mcp-minion # as a library in a uv project
|
|
18
|
+
uv sync --package mcp-minion # inside the monorepo (workspace member)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The OpenRouter API key is looked up in this order: the `OPENROUTER_API_KEY`
|
|
22
|
+
environment variable, the run folder's `.env`, then `~/.mcp-minion`
|
|
23
|
+
(`OPENROUTER_API_KEY=sk-...`). The files are read, not loaded into the process
|
|
24
|
+
environment; `mcp_minion.find_api_key()` does the same lookup for library users.
|
|
25
|
+
|
|
26
|
+
## Run folder
|
|
27
|
+
|
|
28
|
+
| File | Purpose |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `config.json` | Model, agent, MCP server and kernel settings (required) |
|
|
31
|
+
| `task.md` | The task for this run (required) |
|
|
32
|
+
| `project.md` | Shared instructions prepended to the task (optional) |
|
|
33
|
+
| `files.system` target | System-prompt body (optional, see below) |
|
|
34
|
+
| `run_*.json` | Per-run JSON log, including the system prompt sent (written automatically) |
|
|
35
|
+
| `submission.py` | Code of the last accepted `submit_code` call, if any |
|
|
36
|
+
| `server.log` | stderr of the MCP servers and their children |
|
|
37
|
+
|
|
38
|
+
`config.json` uses the nested format; the pre-0.3 flat format
|
|
39
|
+
(`modelstring`, top-level `max_steps`, ...) is rejected with an error:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"model": {
|
|
44
|
+
"name": "google/gemini-3.1-flash-lite-preview",
|
|
45
|
+
"temperature": 0,
|
|
46
|
+
"max_tokens": 2048,
|
|
47
|
+
"reasoning": { "effort": "low" },
|
|
48
|
+
"request_timeout": 120
|
|
49
|
+
},
|
|
50
|
+
"agent": { "max_steps": 10, "max_total_tokens": 500000 },
|
|
51
|
+
"files": { "system": "system.md" },
|
|
52
|
+
"packages": ["z3-solver"],
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"ipython": { "command": "ipython_mcp", "args": [], "env": {}, "cwd": "." }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- **`model.*`** — `name` is the OpenRouter model id. `reasoning`, `provider`,
|
|
60
|
+
`top_k` and the entries of an optional `extra_body` object go into the
|
|
61
|
+
request body (`AgentConfig.extra_body`; OpenRouter usage accounting stays
|
|
62
|
+
on). `request_timeout` is the per-request timeout in seconds. Every other
|
|
63
|
+
key (`temperature`, `max_tokens`, ...) is passed to the API call as is.
|
|
64
|
+
- **`agent.max_total_tokens`** — cap on the cumulative input+output tokens of
|
|
65
|
+
a run, checked after each step; the run then stops with
|
|
66
|
+
`[Agent stopped: per-run token cap of N exceeded (cumulative M)]` and the
|
|
67
|
+
log records `token_cap_reached`. Absent or `0` means no cap.
|
|
68
|
+
- **`agent.max_tool_result_chars`** — tool results longer than this are cut
|
|
69
|
+
for the model (see Tool results); default 64000, `0` disables.
|
|
70
|
+
- **`files.system`** — markdown file (relative to the run folder) used as the
|
|
71
|
+
system prompt. A literal `{tool_sections}` placeholder is replaced by the
|
|
72
|
+
generated tool list (other braces are left alone); without it the list is
|
|
73
|
+
appended. Absent: a built-in default prompt.
|
|
74
|
+
- **`mcpServers`** — servers to start, each with `command` and optional
|
|
75
|
+
`args`, `env` (merged by the mcp library over its default environment
|
|
76
|
+
whitelist) and `cwd`. A server that fails to start aborts the run. Each
|
|
77
|
+
server's `instructions` from its initialize result appear in the system
|
|
78
|
+
prompt under that server's heading. Without any server, the CLI offers four
|
|
79
|
+
arithmetic demo tools (`add`, `subtract`, `multiply`, `divide`).
|
|
80
|
+
- **`packages`** — for the kernel server
|
|
81
|
+
[`ipython_mcp`](https://pypi.org/project/agentic-python-coder/) (PyPI
|
|
82
|
+
package `agentic-python-coder`): before the first LLM call, `mcp-minion`
|
|
83
|
+
calls `python_reset` with these packages; if that fails the run ends with an
|
|
84
|
+
error. The returned `kernel_id` is added to every `python_exec`,
|
|
85
|
+
`python_reset`, `python_status` and `python_interrupt` call that lacks one,
|
|
86
|
+
so a `python_reset` by the model restarts the same kernel with its packages.
|
|
87
|
+
If the model's `python_reset` passes its own `packages` list, the configured
|
|
88
|
+
packages are sent first, followed by the model's entries they do not already
|
|
89
|
+
cover (same distribution name, ignoring extras, versions and case).
|
|
90
|
+
|
|
91
|
+
## Tool results
|
|
92
|
+
|
|
93
|
+
`MCPManager.call_tool` returns a `ToolOutcome(text, is_error, links)`. The
|
|
94
|
+
model sees `text` unchanged (prefixed with `ERROR: ` for errors), cut to
|
|
95
|
+
`agent.max_tool_result_chars` in config.json (`AgentConfig.max_tool_result_chars`,
|
|
96
|
+
default 64000; head and tail kept, `0` disables); the step records and the run log keep the full text as
|
|
97
|
+
`"result"` plus `"is_error"`. Images, audio and blobs appear as one line such
|
|
98
|
+
as `[image mime=image/png bytes=1234]`. A `resource_link` appears as a
|
|
99
|
+
`[resource_link] URI (name)` line; the built-in `read_resource` tool fetches
|
|
100
|
+
it, or any resource a server announced, from its origin server only.
|
|
101
|
+
Reasoning that the model returns (`reasoning_details`, or a plain
|
|
102
|
+
`reasoning` string) is passed back unmodified on the next request and kept in
|
|
103
|
+
the step records and log.
|
|
104
|
+
|
|
105
|
+
`mcp_minion.extract_last_submission(log_or_steps, tool_name="submit_code")`
|
|
106
|
+
returns the `code` argument of the last accepted submission: one without
|
|
107
|
+
`is_error` whose text is not a JSON object with `"ok": false`. Run logs of
|
|
108
|
+
mcp-minion 0.2 and earlier are read too.
|
|
109
|
+
|
|
110
|
+
## Example
|
|
111
|
+
|
|
112
|
+
The package ships a small MCP test server (`echo`, `add`, a resource and
|
|
113
|
+
instructions):
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"model": { "name": "google/gemini-3.1-flash-lite-preview", "temperature": 0 },
|
|
118
|
+
"agent": { "max_steps": 5 },
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"test": { "command": "python", "args": ["-m", "mcp_minion.test_mcp_server"] }
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
mcp-minion path/to/run_folder -v
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Tests
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cd minion && uv run pytest -q
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The end-to-end tests under `minion/e2e_tests/` make real API calls and are
|
|
136
|
+
skipped unless `OPENROUTER_API_KEY` is set.
|
|
@@ -129,7 +129,7 @@ class TestLogIntegrity:
|
|
|
129
129
|
|
|
130
130
|
def test_log_has_all_fields(self) -> None:
|
|
131
131
|
folder = E2E_RUNS / "simple_add"
|
|
132
|
-
|
|
132
|
+
_result, logger = run_agent_from_folder(folder)
|
|
133
133
|
|
|
134
134
|
log_data = json.loads(logger.log_path.read_text())
|
|
135
135
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mcp-minion"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "A minimal ReAct agent over MCP servers via OpenRouter"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -15,7 +15,7 @@ requires-python = ">=3.13,<3.15"
|
|
|
15
15
|
dependencies = [
|
|
16
16
|
"openai>=1.0.0",
|
|
17
17
|
"python-dotenv>=1.0.0",
|
|
18
|
-
"mcp>=
|
|
18
|
+
"mcp>=2,<3",
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
[project.optional-dependencies]
|
|
@@ -4,14 +4,16 @@ from importlib.metadata import PackageNotFoundError, version
|
|
|
4
4
|
|
|
5
5
|
from mcp_minion.agent import Agent, AgentConfig, AgentResult
|
|
6
6
|
from mcp_minion.artifacts import extract_last_submission
|
|
7
|
+
from mcp_minion.env import find_api_key
|
|
7
8
|
from mcp_minion.logging import RunLogger
|
|
8
|
-
from mcp_minion.mcp_client import MCPManager, MCPResourceInfo, MCPToolInfo
|
|
9
|
+
from mcp_minion.mcp_client import MCPManager, MCPResourceInfo, MCPToolInfo, ToolOutcome
|
|
9
10
|
from mcp_minion.tools import Tool, ToolRegistry, create_default_registry
|
|
10
11
|
|
|
11
12
|
try:
|
|
12
13
|
__version__ = version("mcp-minion")
|
|
13
|
-
except PackageNotFoundError: # pragma: no cover - source
|
|
14
|
-
|
|
14
|
+
except PackageNotFoundError: # pragma: no cover - source tree without install
|
|
15
|
+
# A sentinel, not a release number, so it cannot go stale.
|
|
16
|
+
__version__ = "0+unknown"
|
|
15
17
|
|
|
16
18
|
__all__ = [
|
|
17
19
|
"Agent",
|
|
@@ -22,8 +24,10 @@ __all__ = [
|
|
|
22
24
|
"MCPToolInfo",
|
|
23
25
|
"RunLogger",
|
|
24
26
|
"Tool",
|
|
27
|
+
"ToolOutcome",
|
|
25
28
|
"ToolRegistry",
|
|
26
29
|
"__version__",
|
|
27
30
|
"create_default_registry",
|
|
28
31
|
"extract_last_submission",
|
|
32
|
+
"find_api_key",
|
|
29
33
|
]
|