Implemented the next parity slice.

New runtime/code:

  - src/ask_user_runtime.py
  - src/team_runtime.py

  New real tools in src/agent_tools.py:

  - ask_user_question
  - team_create
  - team_delete
  - team_list
  - team_get
  - send_message
  - team_messages
  - notebook_edit
This commit is contained in:
Abdelrahman Abdallah
2026-04-07 03:48:20 +02:00
parent a5629295ac
commit c17c2768eb
17 changed files with 2507 additions and 3 deletions
+187
View File
@@ -0,0 +1,187 @@
from __future__ import annotations
import json
import shutil
import subprocess
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 AgentPermissions, AgentRuntimeConfig, ModelConfig
from src.worktree_runtime import WorktreeRuntime
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 _init_git_repo(workspace: Path) -> None:
subprocess.run(['git', 'init', '-q'], cwd=workspace, check=True)
subprocess.run(['git', 'config', 'user.email', 'test@example.com'], cwd=workspace, check=True)
subprocess.run(['git', 'config', 'user.name', 'Test User'], cwd=workspace, check=True)
(workspace / 'README.md').write_text('hello\n', encoding='utf-8')
subprocess.run(['git', 'add', 'README.md'], cwd=workspace, check=True)
subprocess.run(['git', 'commit', '-qm', 'init'], cwd=workspace, check=True)
@unittest.skipUnless(shutil.which('git'), 'git is required for worktree tests')
class WorktreeRuntimeTests(unittest.TestCase):
def test_worktree_runtime_enters_and_exits_managed_session(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
_init_git_repo(workspace)
runtime = WorktreeRuntime.from_workspace(workspace)
enter_report = runtime.enter('feature-preview')
worktree_path = Path(enter_report.worktree_path or '')
exit_report = runtime.exit(action='keep')
self.assertTrue(enter_report.active)
self.assertTrue(worktree_path.exists())
self.assertIn('feature-preview', enter_report.worktree_branch or '')
self.assertFalse(exit_report.active)
self.assertEqual(exit_report.original_cwd, str(workspace))
def test_worktree_tools_execute_against_runtime(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
_init_git_repo(workspace)
runtime = WorktreeRuntime.from_workspace(workspace)
context = build_tool_context(
AgentRuntimeConfig(
cwd=workspace,
permissions=AgentPermissions(allow_file_write=True),
),
worktree_runtime=runtime,
)
enter_result = execute_tool(
default_tool_registry(),
'worktree_enter',
{'name': 'preview'},
context,
)
status_result = execute_tool(
default_tool_registry(),
'worktree_status',
{},
context,
)
exit_result = execute_tool(
default_tool_registry(),
'worktree_exit',
{'action': 'remove', 'discard_changes': True},
context,
)
self.assertTrue(enter_result.ok)
self.assertIn('preview', enter_result.content)
self.assertEqual(enter_result.metadata.get('action'), 'worktree_enter')
self.assertTrue(status_result.ok)
self.assertIn('Active managed worktree: True', status_result.content)
self.assertTrue(exit_result.ok)
self.assertEqual(exit_result.metadata.get('action'), 'worktree_exit')
def test_agent_switches_cwd_after_worktree_enter(self) -> None:
responses = [
{
'choices': [
{
'message': {
'role': 'assistant',
'content': 'Entering worktree.',
'tool_calls': [
{
'id': 'call_enter',
'type': 'function',
'function': {
'name': 'worktree_enter',
'arguments': '{"name":"preview"}',
},
}
],
},
'finish_reason': 'tool_calls',
}
],
'usage': {'prompt_tokens': 8, 'completion_tokens': 2},
},
{
'choices': [
{
'message': {
'role': 'assistant',
'content': 'Writing inside the worktree.',
'tool_calls': [
{
'id': 'call_write',
'type': 'function',
'function': {
'name': 'write_file',
'arguments': '{"path":"note.txt","content":"from worktree\\n"}',
},
}
],
},
'finish_reason': 'tool_calls',
}
],
'usage': {'prompt_tokens': 8, 'completion_tokens': 2},
},
{
'choices': [
{
'message': {
'role': 'assistant',
'content': 'done',
},
'finish_reason': 'stop',
}
],
'usage': {'prompt_tokens': 6, 'completion_tokens': 1},
},
]
with tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
_init_git_repo(workspace)
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'),
runtime_config=AgentRuntimeConfig(
cwd=workspace,
permissions=AgentPermissions(allow_file_write=True),
),
)
result = agent.run('Use a worktree and write a file there')
runtime = WorktreeRuntime.from_workspace(workspace)
assert runtime.active_session is not None
worktree_path = Path(runtime.active_session.worktree_path)
self.assertEqual(result.final_output, 'done')
self.assertFalse((workspace / 'note.txt').exists())
self.assertTrue((worktree_path / 'note.txt').exists())
self.assertEqual(agent.runtime_config.cwd, worktree_path.resolve())