|
reload: pick up the new code, and drop MCP tools that are gone
reload_tools reported success while three separate things kept it from doing what it says. The bytecode cache is keyed on (mtime in whole seconds, file size), so a tool edited to the same length inside the same second as its previous load re-ran the OLD code — the reload was real, the new version was not live. The loader now compiles the source itself instead of consulting __pycache__ (importlib.invalidate_caches() does not help here). MCP registrations only ever grew: register_mcp_tools called register_external, and unregister_external was used in one place, so a server removed from the config or a tool a server stopped exposing stayed in the registry and failed only when the model called it. Reload now clears external tools and rebuilds them. enabled.json naming a tool that failed to load (the gmail/html2text case) was visible only as a log line. It is now part of the report. The reload itself moves to navi/core/reload.py, one implementation shared by the tool and the admin route, so the two cannot leave different toolsets behind. list_tools.py also read enabled.json through its own cwd-relative path, which made it disagree with the real toolset, and the class-based loader rejected execute(self, params, ctx=None) — the shape every built-in uses. |
|---|
|
|
| navi/core/registry.py |
|---|
| navi/core/reload.py 0 → 100644 |
|---|
| navi/tools/_internal/loader.py |
|---|
| navi/tools/list_tools.py |
|---|
| navi/tools/reload_tools.py |
|---|
| tests/unit/core/test_reload.py 0 → 100644 |
|---|
| tests/unit/tools/test_loader.py 0 → 100644 |
|---|
| tests/unit/tools/test_reload_tools.py 0 → 100644 |
|---|