Implemented the next parity slice: prompt-budget preflight and context collapse.

Core changes:

  - Added claw-code/src/token_budget.py for projected prompt size, chat-framing overhead, output reserve, and soft/hard input limits.
  - Wired preflight prompt-length validation and auto-compact/context collapse into claw-code/src/agent_runtime.py.
  - Extended claw-code/src/compact.py so compaction reports usage back to the runtime.
  - Added inspection surfaces in claw-code/src/agent_slash_commands.py and claw-code/src/main.py:
      - /token-budget and /budget
      - token-budget
  - Hardened claw-code/src/tokenizer_runtime.py so arbitrary simple model names fall back cleanly instead of trying a slow Transformers
    lookup.
  - Exported the new helpers in claw-code/src/__init__.py.

  Docs and tracking:

  - Updated claw-code/PARITY_CHECKLIST.md to mark prompt-length validation, token-budget calculation, and auto-compact/context collapse as
    done.
  - Updated claw-code/README.md and claw-code/TESTING_GUIDE.md with the new commands and behavior.

  Tests:

  - Added claw-code/tests/test_token_budget.py.
  - Updated claw-code/tests/test_agent_runtime.py, claw-code/tests/test_agent_slash_commands.py, claw-code/tests/test_main.py, and claw-code/
    tests/test_agent_context_usage.py.
  - Verified with:
      - /data/fs201059/aa17626/miniconda3/bin/python3 -m compileall src tests
      - /data/fs201059/aa17626/miniconda3/bin/python3 -m unittest -v tests.test_token_budget
        tests.test_agent_runtime.AgentRuntimeTests.test_agent_rejects_prompt_before_backend_when_preflight_input_budget_is_exceeded
        tests.test_agent_runtime.AgentRuntimeTests.test_agent_auto_compacts_context_before_next_model_call tests.test_agent_slash_commands
        tests.test_main tests.test_compact tests.test_tokenizer_runtime tests.test_agent_context_usage
      - Result: 71 tests, OK
This commit is contained in:
Abdelrahman Abdallah
2026-04-11 01:38:19 +02:00
parent aacf0a212a
commit b5e5824a56
23 changed files with 2641 additions and 10 deletions
+36
View File
@@ -6,6 +6,7 @@ from pathlib import Path
from src.agent_tools import build_tool_context, default_tool_registry, execute_tool
from src.agent_types import AgentPermissions, AgentRuntimeConfig
from src.lsp_runtime import LSPRuntime
class ExtendedToolTests(unittest.TestCase):
@@ -101,3 +102,38 @@ class ExtendedToolTests(unittest.TestCase):
self.assertIn('updated notebook cell 0', result.content)
self.assertIn('print(2)', updated)
self.assertEqual(result.metadata.get('action'), 'notebook_edit')
def test_lsp_tool_returns_definition_report(self) -> None:
registry = default_tool_registry()
with tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
(workspace / 'sample.py').write_text(
'def helper(value):\n'
' return value * 2\n'
'\n'
'def run(item):\n'
' return helper(item)\n',
encoding='utf-8',
)
context = build_tool_context(
AgentRuntimeConfig(cwd=workspace),
tool_registry=registry,
lsp_runtime=LSPRuntime.from_workspace(workspace),
)
result = execute_tool(
registry,
'LSP',
{
'operation': 'goToDefinition',
'file_path': 'sample.py',
'line': 5,
'character': 12,
},
context,
)
self.assertTrue(result.ok)
self.assertIn('# LSP Definition', result.content)
self.assertIn('function helper', result.content)
self.assertEqual(result.metadata.get('action'), 'lsp_query')
self.assertEqual(result.metadata.get('operation'), 'goToDefinition')