first commit
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from src.agent_context import (
|
||||
build_context_snapshot,
|
||||
clear_context_caches,
|
||||
set_system_prompt_injection,
|
||||
)
|
||||
from src.agent_types import AgentRuntimeConfig
|
||||
|
||||
|
||||
class AgentContextTests(unittest.TestCase):
|
||||
def tearDown(self) -> None:
|
||||
set_system_prompt_injection(None)
|
||||
clear_context_caches()
|
||||
|
||||
def test_user_context_loads_project_claude_md_files(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
workspace = Path(tmp_dir) / 'repo' / 'nested'
|
||||
workspace.mkdir(parents=True)
|
||||
(workspace.parent / 'CLAUDE.md').write_text('root instructions\n', encoding='utf-8')
|
||||
(workspace / 'CLAUDE.local.md').write_text('local instructions\n', encoding='utf-8')
|
||||
|
||||
snapshot = build_context_snapshot(AgentRuntimeConfig(cwd=workspace))
|
||||
|
||||
self.assertIn('currentDate', snapshot.user_context)
|
||||
self.assertIn('claudeMd', snapshot.user_context)
|
||||
self.assertIn('root instructions', snapshot.user_context['claudeMd'])
|
||||
self.assertIn('local instructions', snapshot.user_context['claudeMd'])
|
||||
|
||||
def test_system_context_includes_cache_breaker(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
set_system_prompt_injection('debug-token')
|
||||
snapshot = build_context_snapshot(AgentRuntimeConfig(cwd=Path(tmp_dir)))
|
||||
|
||||
self.assertEqual(snapshot.system_context['cacheBreaker'], '[CACHE_BREAKER: debug-token]')
|
||||
|
||||
@unittest.skipIf(shutil.which('git') is None, 'git is required for git context tests')
|
||||
def test_git_status_snapshot_contains_branch_and_status(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
workspace = Path(tmp_dir)
|
||||
subprocess.run(['git', 'init', '-b', 'main'], cwd=workspace, check=True)
|
||||
subprocess.run(['git', 'config', 'user.name', 'Tester'], cwd=workspace, check=True)
|
||||
subprocess.run(['git', 'config', 'user.email', 'tester@example.com'], cwd=workspace, check=True)
|
||||
(workspace / 'tracked.txt').write_text('hello\n', encoding='utf-8')
|
||||
subprocess.run(['git', 'add', 'tracked.txt'], cwd=workspace, check=True)
|
||||
subprocess.run(['git', 'commit', '-m', 'initial'], cwd=workspace, check=True)
|
||||
(workspace / 'tracked.txt').write_text('changed\n', encoding='utf-8')
|
||||
|
||||
snapshot = build_context_snapshot(AgentRuntimeConfig(cwd=workspace))
|
||||
|
||||
git_status = snapshot.system_context.get('gitStatus', '')
|
||||
self.assertIn('Current branch: main', git_status)
|
||||
self.assertIn('Status:', git_status)
|
||||
self.assertIn('tracked.txt', git_status)
|
||||
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from src.agent_context_usage import collect_context_usage, format_context_usage
|
||||
from src.agent_session import AgentSessionState
|
||||
|
||||
|
||||
class AgentContextUsageTests(unittest.TestCase):
|
||||
def test_collect_context_usage_formats_breakdown(self) -> None:
|
||||
session = AgentSessionState.create(
|
||||
['# Intro\nhello', '# System\nworld'],
|
||||
'inspect repo',
|
||||
user_context={'currentDate': "Today's date is 2026-04-01."},
|
||||
system_context={'gitStatus': 'Current branch: main'},
|
||||
)
|
||||
session.append_assistant(
|
||||
'Reading files',
|
||||
(
|
||||
{
|
||||
'id': 'call_1',
|
||||
'type': 'function',
|
||||
'function': {'name': 'read_file', 'arguments': '{"path":"a.py"}'},
|
||||
},
|
||||
),
|
||||
)
|
||||
session.append_tool('read_file', 'call_1', '{"ok": true, "content": "print(1)"}')
|
||||
|
||||
report = collect_context_usage(
|
||||
session=session,
|
||||
model='Qwen/Qwen3-Coder-30B-A3B-Instruct',
|
||||
strategy='test session',
|
||||
)
|
||||
rendered = format_context_usage(report)
|
||||
|
||||
self.assertGreater(report.total_tokens, 0)
|
||||
self.assertIn('## Context Usage', rendered)
|
||||
self.assertIn('### System Prompt Sections', rendered)
|
||||
self.assertIn('### Message Breakdown', rendered)
|
||||
self.assertIn('#### Top Tools', rendered)
|
||||
@@ -0,0 +1,60 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from src.agent_prompting import build_prompt_context, build_system_prompt_parts, render_system_prompt
|
||||
from src.agent_runtime import LocalCodingAgent
|
||||
from src.agent_session import AgentSessionState
|
||||
from src.agent_tools import default_tool_registry
|
||||
from src.agent_types import AgentPermissions, AgentRuntimeConfig, ModelConfig
|
||||
|
||||
|
||||
class AgentPromptingTests(unittest.TestCase):
|
||||
def test_prompt_builder_contains_expected_sections(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
runtime_config = AgentRuntimeConfig(
|
||||
cwd=Path(tmp_dir),
|
||||
permissions=AgentPermissions(
|
||||
allow_file_write=True,
|
||||
allow_shell_commands=False,
|
||||
),
|
||||
)
|
||||
model_config = ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct')
|
||||
prompt_context = build_prompt_context(runtime_config, model_config)
|
||||
parts = build_system_prompt_parts(
|
||||
prompt_context=prompt_context,
|
||||
runtime_config=runtime_config,
|
||||
tools=default_tool_registry(),
|
||||
)
|
||||
|
||||
prompt = render_system_prompt(parts)
|
||||
self.assertIn('# System', prompt)
|
||||
self.assertIn('# Doing tasks', prompt)
|
||||
self.assertIn('# Using your tools', prompt)
|
||||
self.assertIn('# Environment', prompt)
|
||||
self.assertIn('__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__', prompt)
|
||||
self.assertIn('Primary working directory:', prompt)
|
||||
|
||||
def test_session_state_exports_messages_in_order(self) -> None:
|
||||
state = AgentSessionState.create(['sys one', 'sys two'], 'hello')
|
||||
state.append_assistant('working', ())
|
||||
state.append_tool('read_file', 'call_1', '{"ok": true}')
|
||||
messages = state.to_openai_messages()
|
||||
self.assertEqual(messages[0]['role'], 'system')
|
||||
self.assertEqual(messages[1]['role'], 'user')
|
||||
self.assertEqual(messages[2]['role'], 'assistant')
|
||||
self.assertEqual(messages[3]['role'], 'tool')
|
||||
self.assertEqual(messages[3]['tool_call_id'], 'call_1')
|
||||
|
||||
def test_agent_can_render_prompt_without_contacting_model(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
prompt = agent.render_system_prompt()
|
||||
self.assertIn('Claw Code Python', prompt)
|
||||
self.assertIn('# System', prompt)
|
||||
self.assertIn('# Environment', prompt)
|
||||
@@ -0,0 +1,238 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from src.agent_runtime import LocalCodingAgent
|
||||
from src.agent_tools import build_tool_context, default_tool_registry, execute_tool
|
||||
from src.agent_types import AgentRuntimeConfig, ModelConfig
|
||||
from src.openai_compat import OpenAICompatClient
|
||||
from src.session_store import load_agent_session
|
||||
|
||||
|
||||
class FakeHTTPResponse:
|
||||
def __init__(self, payload: dict[str, object]) -> None:
|
||||
self.payload = payload
|
||||
|
||||
def read(self) -> bytes:
|
||||
return json.dumps(self.payload).encode('utf-8')
|
||||
|
||||
def __enter__(self) -> 'FakeHTTPResponse':
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc, tb) -> None:
|
||||
return None
|
||||
|
||||
|
||||
def make_urlopen_side_effect(responses: list[dict[str, object]]):
|
||||
queued = [FakeHTTPResponse(payload) for payload in responses]
|
||||
|
||||
def _fake_urlopen(request_obj, timeout=None): # noqa: ANN001
|
||||
return queued.pop(0)
|
||||
|
||||
return _fake_urlopen
|
||||
|
||||
|
||||
def make_recording_urlopen_side_effect(
|
||||
responses: list[dict[str, object]],
|
||||
recorded_payloads: list[dict[str, object]],
|
||||
):
|
||||
queued = [FakeHTTPResponse(payload) for payload in responses]
|
||||
|
||||
def _fake_urlopen(request_obj, timeout=None): # noqa: ANN001
|
||||
body = request_obj.data.decode('utf-8')
|
||||
recorded_payloads.append(json.loads(body))
|
||||
return queued.pop(0)
|
||||
|
||||
return _fake_urlopen
|
||||
|
||||
|
||||
class AgentRuntimeTests(unittest.TestCase):
|
||||
def test_openai_client_parses_tool_calls(self) -> None:
|
||||
responses = [
|
||||
{
|
||||
'choices': [
|
||||
{
|
||||
'message': {
|
||||
'role': 'assistant',
|
||||
'content': 'Inspecting the file.',
|
||||
'tool_calls': [
|
||||
{
|
||||
'id': 'call_1',
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'read_file',
|
||||
'arguments': '{"path": "hello.txt"}',
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
'finish_reason': 'tool_calls',
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
with patch('src.openai_compat.request.urlopen', side_effect=make_urlopen_side_effect(responses)):
|
||||
client = OpenAICompatClient(
|
||||
ModelConfig(
|
||||
model='Qwen/Qwen3-Coder-30B-A3B-Instruct',
|
||||
base_url='http://127.0.0.1:8000/v1',
|
||||
)
|
||||
)
|
||||
turn = client.complete(
|
||||
messages=[{'role': 'user', 'content': 'read hello.txt'}],
|
||||
tools=[],
|
||||
)
|
||||
self.assertEqual(turn.content, 'Inspecting the file.')
|
||||
self.assertEqual(len(turn.tool_calls), 1)
|
||||
self.assertEqual(turn.tool_calls[0].name, 'read_file')
|
||||
self.assertEqual(turn.tool_calls[0].arguments['path'], 'hello.txt')
|
||||
|
||||
def test_agent_executes_tool_calls_against_fake_backend(self) -> None:
|
||||
responses = [
|
||||
{
|
||||
'choices': [
|
||||
{
|
||||
'message': {
|
||||
'role': 'assistant',
|
||||
'content': 'I will inspect the file first.',
|
||||
'tool_calls': [
|
||||
{
|
||||
'id': 'call_1',
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'read_file',
|
||||
'arguments': '{"path": "hello.txt"}',
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
'finish_reason': 'tool_calls',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'choices': [
|
||||
{
|
||||
'message': {
|
||||
'role': 'assistant',
|
||||
'content': 'The file contains hello world.',
|
||||
},
|
||||
'finish_reason': 'stop',
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
workspace = Path(tmp_dir)
|
||||
(workspace / 'hello.txt').write_text('hello world\n', encoding='utf-8')
|
||||
with patch('src.openai_compat.request.urlopen', side_effect=make_urlopen_side_effect(responses)):
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(
|
||||
model='Qwen/Qwen3-Coder-30B-A3B-Instruct',
|
||||
base_url='http://127.0.0.1:8000/v1',
|
||||
),
|
||||
runtime_config=AgentRuntimeConfig(cwd=workspace),
|
||||
)
|
||||
result = agent.run('Inspect hello.txt')
|
||||
|
||||
self.assertEqual(result.final_output, 'The file contains hello world.')
|
||||
self.assertEqual(result.tool_calls, 1)
|
||||
self.assertGreaterEqual(len(result.transcript), 5)
|
||||
|
||||
def test_write_tool_is_blocked_without_permission(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
config = AgentRuntimeConfig(cwd=Path(tmp_dir))
|
||||
context = build_tool_context(config)
|
||||
result = execute_tool(
|
||||
default_tool_registry(),
|
||||
'write_file',
|
||||
{'path': 'blocked.txt', 'content': 'data'},
|
||||
context,
|
||||
)
|
||||
self.assertFalse(result.ok)
|
||||
self.assertIn('--allow-write', result.content)
|
||||
|
||||
def test_local_slash_command_returns_without_model_call(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
result = agent.run('/permissions')
|
||||
self.assertEqual(result.turns, 0)
|
||||
self.assertEqual(result.tool_calls, 0)
|
||||
self.assertIn('# Permissions', result.final_output)
|
||||
|
||||
def test_agent_persists_session_and_can_resume(self) -> None:
|
||||
responses = [
|
||||
{
|
||||
'choices': [
|
||||
{
|
||||
'message': {
|
||||
'role': 'assistant',
|
||||
'content': 'Initial answer.',
|
||||
},
|
||||
'finish_reason': 'stop',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'choices': [
|
||||
{
|
||||
'message': {
|
||||
'role': 'assistant',
|
||||
'content': 'Continued answer.',
|
||||
},
|
||||
'finish_reason': 'stop',
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
recorded_payloads: list[dict[str, object]] = []
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
workspace = Path(tmp_dir)
|
||||
session_dir = workspace / '.port_sessions' / 'agent'
|
||||
runtime_config = AgentRuntimeConfig(
|
||||
cwd=workspace,
|
||||
session_directory=session_dir,
|
||||
)
|
||||
with patch(
|
||||
'src.openai_compat.request.urlopen',
|
||||
side_effect=make_recording_urlopen_side_effect(responses, recorded_payloads),
|
||||
):
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(
|
||||
model='Qwen/Qwen3-Coder-30B-A3B-Instruct',
|
||||
base_url='http://127.0.0.1:8000/v1',
|
||||
),
|
||||
runtime_config=runtime_config,
|
||||
)
|
||||
first_result = agent.run('Start task')
|
||||
self.assertIsNotNone(first_result.session_id)
|
||||
stored = load_agent_session(first_result.session_id or '', directory=session_dir)
|
||||
|
||||
resumed_agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(
|
||||
model='Qwen/Qwen3-Coder-30B-A3B-Instruct',
|
||||
base_url='http://127.0.0.1:8000/v1',
|
||||
),
|
||||
runtime_config=runtime_config,
|
||||
)
|
||||
second_result = resumed_agent.resume('Continue the task', stored)
|
||||
|
||||
self.assertTrue((session_dir / f'{first_result.session_id}.json').exists())
|
||||
|
||||
self.assertEqual(first_result.final_output, 'Initial answer.')
|
||||
self.assertEqual(second_result.final_output, 'Continued answer.')
|
||||
self.assertEqual(second_result.session_id, first_result.session_id)
|
||||
self.assertEqual(len(recorded_payloads), 2)
|
||||
resumed_messages = recorded_payloads[1]['messages']
|
||||
assert isinstance(resumed_messages, list)
|
||||
contents = [message.get('content') for message in resumed_messages if isinstance(message, dict)]
|
||||
self.assertIn('Start task', contents)
|
||||
self.assertIn('Initial answer.', contents)
|
||||
self.assertIn('Continue the task', contents)
|
||||
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from src.agent_runtime import LocalCodingAgent
|
||||
from src.agent_slash_commands import looks_like_command, parse_slash_command
|
||||
from src.agent_types import AgentRuntimeConfig, ModelConfig
|
||||
|
||||
|
||||
class AgentSlashCommandTests(unittest.TestCase):
|
||||
def test_parse_slash_command(self) -> None:
|
||||
parsed = parse_slash_command('/context extra args')
|
||||
assert parsed is not None
|
||||
self.assertEqual(parsed.command_name, 'context')
|
||||
self.assertEqual(parsed.args, 'extra args')
|
||||
self.assertFalse(parsed.is_mcp)
|
||||
|
||||
def test_looks_like_command(self) -> None:
|
||||
self.assertTrue(looks_like_command('context'))
|
||||
self.assertFalse(looks_like_command('foo/bar'))
|
||||
|
||||
def test_model_command_updates_agent_model(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
result = agent.run('/model local/test-model')
|
||||
self.assertIn('Set model to local/test-model', result.final_output)
|
||||
self.assertEqual(agent.model_config.model, 'local/test-model')
|
||||
|
||||
def test_unknown_command_returns_local_error(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
result = agent.run('/unknown-command')
|
||||
self.assertEqual(result.final_output, 'Unknown skill: unknown-command')
|
||||
|
||||
def test_context_command_renders_usage_report(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
workspace = Path(tmp_dir)
|
||||
(workspace / 'CLAUDE.md').write_text('repo instructions\n', encoding='utf-8')
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=workspace),
|
||||
)
|
||||
result = agent.run('/context')
|
||||
self.assertIn('## Context Usage', result.final_output)
|
||||
self.assertIn('### Estimated usage by category', result.final_output)
|
||||
self.assertIn('### Memory Files', result.final_output)
|
||||
|
||||
def test_tools_and_status_commands_render_local_reports(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
tools_result = agent.run('/tools')
|
||||
status_result = agent.run('/status')
|
||||
self.assertIn('# Tools', tools_result.final_output)
|
||||
self.assertIn('`read_file`', tools_result.final_output)
|
||||
self.assertIn('# Status', status_result.final_output)
|
||||
self.assertIn('Last run: none', status_result.final_output)
|
||||
|
||||
def test_clear_command_clears_saved_runtime_state(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
agent = LocalCodingAgent(
|
||||
model_config=ModelConfig(model='Qwen/Qwen3-Coder-30B-A3B-Instruct'),
|
||||
runtime_config=AgentRuntimeConfig(cwd=Path(tmp_dir)),
|
||||
)
|
||||
agent.last_session = agent.build_session('hello')
|
||||
agent.last_run_result = object() # type: ignore[assignment]
|
||||
result = agent.run('/clear')
|
||||
self.assertIn('Cleared ephemeral Python agent state', result.final_output)
|
||||
self.assertIsNone(agent.last_session)
|
||||
self.assertIsNone(agent.last_run_result)
|
||||
@@ -0,0 +1,248 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from src.commands import PORTED_COMMANDS
|
||||
from src.parity_audit import run_parity_audit
|
||||
from src.port_manifest import build_port_manifest
|
||||
from src.query_engine import QueryEnginePort
|
||||
from src.tools import PORTED_TOOLS
|
||||
|
||||
|
||||
class PortingWorkspaceTests(unittest.TestCase):
|
||||
def test_manifest_counts_python_files(self) -> None:
|
||||
manifest = build_port_manifest()
|
||||
self.assertGreaterEqual(manifest.total_python_files, 20)
|
||||
self.assertTrue(manifest.top_level_modules)
|
||||
|
||||
def test_query_engine_summary_mentions_workspace(self) -> None:
|
||||
summary = QueryEnginePort.from_workspace().render_summary()
|
||||
self.assertIn('Python Porting Workspace Summary', summary)
|
||||
self.assertIn('Command surface:', summary)
|
||||
self.assertIn('Tool surface:', summary)
|
||||
|
||||
def test_cli_summary_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'summary'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Python Porting Workspace Summary', result.stdout)
|
||||
|
||||
def test_parity_audit_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'parity-audit'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Parity Audit', result.stdout)
|
||||
|
||||
def test_root_file_coverage_is_complete_when_local_archive_exists(self) -> None:
|
||||
audit = run_parity_audit()
|
||||
if audit.archive_present:
|
||||
self.assertEqual(audit.root_file_coverage[0], audit.root_file_coverage[1])
|
||||
self.assertGreaterEqual(audit.directory_coverage[0], 28)
|
||||
self.assertGreaterEqual(audit.command_entry_ratio[0], 150)
|
||||
self.assertGreaterEqual(audit.tool_entry_ratio[0], 100)
|
||||
|
||||
def test_command_and_tool_snapshots_are_nontrivial(self) -> None:
|
||||
self.assertGreaterEqual(len(PORTED_COMMANDS), 150)
|
||||
self.assertGreaterEqual(len(PORTED_TOOLS), 100)
|
||||
|
||||
def test_commands_and_tools_cli_run(self) -> None:
|
||||
commands_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'commands', '--limit', '5', '--query', 'review'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
tools_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'tools', '--limit', '5', '--query', 'MCP'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Command entries:', commands_result.stdout)
|
||||
self.assertIn('Tool entries:', tools_result.stdout)
|
||||
|
||||
def test_subsystem_packages_expose_archive_metadata(self) -> None:
|
||||
from src import assistant, bridge, utils
|
||||
|
||||
self.assertGreater(assistant.MODULE_COUNT, 0)
|
||||
self.assertGreater(bridge.MODULE_COUNT, 0)
|
||||
self.assertGreater(utils.MODULE_COUNT, 100)
|
||||
self.assertTrue(utils.SAMPLE_FILES)
|
||||
|
||||
def test_route_and_show_entry_cli_run(self) -> None:
|
||||
route_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'route', 'review MCP tool', '--limit', '5'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
show_command = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'show-command', 'review'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
show_tool = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'show-tool', 'MCPTool'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('review', route_result.stdout.lower())
|
||||
self.assertIn('review', show_command.stdout.lower())
|
||||
self.assertIn('mcptool', show_tool.stdout.lower())
|
||||
|
||||
def test_bootstrap_cli_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'bootstrap', 'review MCP tool', '--limit', '5'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Runtime Session', result.stdout)
|
||||
self.assertIn('Startup Steps', result.stdout)
|
||||
self.assertIn('Routed Matches', result.stdout)
|
||||
|
||||
def test_bootstrap_session_tracks_turn_state(self) -> None:
|
||||
from src.runtime import PortRuntime
|
||||
|
||||
session = PortRuntime().bootstrap_session('review MCP tool', limit=5)
|
||||
self.assertGreaterEqual(len(session.turn_result.matched_tools), 1)
|
||||
self.assertIn('Prompt:', session.turn_result.output)
|
||||
self.assertGreaterEqual(session.turn_result.usage.input_tokens, 1)
|
||||
|
||||
def test_exec_command_and_tool_cli_run(self) -> None:
|
||||
command_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'exec-command', 'review', 'inspect security review'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
tool_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'exec-tool', 'MCPTool', 'fetch resource list'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn("Mirrored command 'review'", command_result.stdout)
|
||||
self.assertIn("Mirrored tool 'MCPTool'", tool_result.stdout)
|
||||
|
||||
def test_setup_report_and_registry_filters_run(self) -> None:
|
||||
setup_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'setup-report'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
command_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'commands', '--limit', '5', '--no-plugin-commands'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
tool_result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'tools', '--limit', '5', '--simple-mode', '--no-mcp'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Setup Report', setup_result.stdout)
|
||||
self.assertIn('Command entries:', command_result.stdout)
|
||||
self.assertIn('Tool entries:', tool_result.stdout)
|
||||
|
||||
def test_load_session_cli_runs(self) -> None:
|
||||
from src.runtime import PortRuntime
|
||||
|
||||
session = PortRuntime().bootstrap_session('review MCP tool', limit=5)
|
||||
session_id = Path(session.persisted_session_path).stem
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'load-session', session_id],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn(session_id, result.stdout)
|
||||
self.assertIn('messages', result.stdout)
|
||||
|
||||
def test_tool_permission_filtering_cli_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'tools', '--limit', '10', '--deny-prefix', 'mcp'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Tool entries:', result.stdout)
|
||||
self.assertNotIn('MCPTool', result.stdout)
|
||||
|
||||
def test_turn_loop_cli_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'turn-loop', 'review MCP tool', '--max-turns', '2', '--structured-output'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('## Turn 1', result.stdout)
|
||||
self.assertIn('stop_reason=', result.stdout)
|
||||
|
||||
def test_remote_mode_clis_run(self) -> None:
|
||||
remote_result = subprocess.run([sys.executable, '-m', 'src.main', 'remote-mode', 'workspace'], check=True, capture_output=True, text=True)
|
||||
ssh_result = subprocess.run([sys.executable, '-m', 'src.main', 'ssh-mode', 'workspace'], check=True, capture_output=True, text=True)
|
||||
teleport_result = subprocess.run([sys.executable, '-m', 'src.main', 'teleport-mode', 'workspace'], check=True, capture_output=True, text=True)
|
||||
self.assertIn('mode=remote', remote_result.stdout)
|
||||
self.assertIn('mode=ssh', ssh_result.stdout)
|
||||
self.assertIn('mode=teleport', teleport_result.stdout)
|
||||
|
||||
def test_flush_transcript_cli_runs(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'flush-transcript', 'review MCP tool'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('flushed=True', result.stdout)
|
||||
|
||||
def test_command_graph_and_tool_pool_cli_run(self) -> None:
|
||||
command_graph = subprocess.run([sys.executable, '-m', 'src.main', 'command-graph'], check=True, capture_output=True, text=True)
|
||||
tool_pool = subprocess.run([sys.executable, '-m', 'src.main', 'tool-pool'], check=True, capture_output=True, text=True)
|
||||
self.assertIn('Command Graph', command_graph.stdout)
|
||||
self.assertIn('Tool Pool', tool_pool.stdout)
|
||||
|
||||
def test_setup_report_mentions_deferred_init(self) -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, '-m', 'src.main', 'setup-report'],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertIn('Deferred init:', result.stdout)
|
||||
self.assertIn('plugin_init=True', result.stdout)
|
||||
|
||||
def test_execution_registry_runs(self) -> None:
|
||||
from src.execution_registry import build_execution_registry
|
||||
|
||||
registry = build_execution_registry()
|
||||
self.assertGreaterEqual(len(registry.commands), 150)
|
||||
self.assertGreaterEqual(len(registry.tools), 100)
|
||||
self.assertIn('Mirrored command', registry.command('review').execute('review security'))
|
||||
self.assertIn('Mirrored tool', registry.tool('MCPTool').execute('fetch mcp resources'))
|
||||
|
||||
def test_bootstrap_graph_and_direct_modes_run(self) -> None:
|
||||
graph_result = subprocess.run([sys.executable, '-m', 'src.main', 'bootstrap-graph'], check=True, capture_output=True, text=True)
|
||||
direct_result = subprocess.run([sys.executable, '-m', 'src.main', 'direct-connect-mode', 'workspace'], check=True, capture_output=True, text=True)
|
||||
deep_link_result = subprocess.run([sys.executable, '-m', 'src.main', 'deep-link-mode', 'workspace'], check=True, capture_output=True, text=True)
|
||||
self.assertIn('Bootstrap Graph', graph_result.stdout)
|
||||
self.assertIn('mode=direct-connect', direct_result.stdout)
|
||||
self.assertIn('mode=deep-link', deep_link_result.stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user