795 lines
89 KiB
Plaintext
795 lines
89 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Ollama Worker Demo\n",
|
|
"\n",
|
|
"This notebook demonstrates the structured local worker flow:\n",
|
|
"\n",
|
|
"1. Create a task packet\n",
|
|
"2. Create a worker\n",
|
|
"3. Run the worker with a live Ollama-backed task\n",
|
|
"4. Inspect worker state\n",
|
|
"5. Resume the last packet\n",
|
|
"6. Close the worker\n",
|
|
"\n",
|
|
"The notebook captures the `worker_id` programmatically. No manual copy/paste is required."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "e9f6a34f",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Workspace root: /Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\n",
|
|
"Python: /Users/wongdowling/opt/anaconda3/bin/python\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from __future__ import annotations\n",
|
|
"\n",
|
|
"import json\n",
|
|
"import shlex\n",
|
|
"import subprocess\n",
|
|
"import sys\n",
|
|
"import urllib.error\n",
|
|
"import urllib.request\n",
|
|
"from pathlib import Path\n",
|
|
"\n",
|
|
"def is_repo_root(candidate: Path) -> bool:\n",
|
|
" return (candidate / \"src\" / \"main.py\").exists() and (candidate / \"tests\" / \"test_porting_workspace.py\").exists()\n",
|
|
"\n",
|
|
"def find_repo_root(start: Path | None = None) -> Path:\n",
|
|
" current = (start or Path.cwd()).resolve()\n",
|
|
" for candidate in (current, *current.parents):\n",
|
|
" if is_repo_root(candidate):\n",
|
|
" return candidate\n",
|
|
" for nested in (candidate / \"claw-code\", candidate / \"harness\" / \"claw-code\"):\n",
|
|
" if is_repo_root(nested):\n",
|
|
" return nested\n",
|
|
" raise RuntimeError(\n",
|
|
" f\"Could not locate the claw-code repo from {current}. Start the notebook from the repo, its notebooks directory, or the enclosing autoresearch workspace.\"\n",
|
|
" )\n",
|
|
"\n",
|
|
"ROOT = find_repo_root()\n",
|
|
"PYTHON = sys.executable\n",
|
|
"NOTEBOOK_DIR = ROOT / \"notebooks\"\n",
|
|
"NOTEBOOK_DIR.mkdir(parents=True, exist_ok=True)\n",
|
|
"\n",
|
|
"def run_cmd(args: list[str], check: bool = True) -> subprocess.CompletedProcess[str]:\n",
|
|
" print(\"$\", \" \".join(shlex.quote(arg) for arg in args))\n",
|
|
" result = subprocess.run(args, cwd=ROOT, capture_output=True, text=True)\n",
|
|
" if result.stdout:\n",
|
|
" print(result.stdout)\n",
|
|
" if result.stderr:\n",
|
|
" print(result.stderr, file=sys.stderr)\n",
|
|
" if check and result.returncode != 0:\n",
|
|
" details = result.stderr.strip() or result.stdout.strip() or \"no output\"\n",
|
|
" raise RuntimeError(f\"command failed with exit code {result.returncode}: {details}\")\n",
|
|
" return result\n",
|
|
"\n",
|
|
"def run_json(args: list[str], check: bool = True):\n",
|
|
" result = run_cmd(args, check=check)\n",
|
|
" return json.loads(result.stdout)\n",
|
|
"\n",
|
|
"def ollama_ready(host: str = \"http://localhost:11434\") -> bool:\n",
|
|
" try:\n",
|
|
" with urllib.request.urlopen(f\"{host.rstrip('/')}/api/tags\", timeout=2) as response:\n",
|
|
" return response.status == 200\n",
|
|
" except (urllib.error.URLError, TimeoutError):\n",
|
|
" return False\n",
|
|
"\n",
|
|
"print(f\"Workspace root: {ROOT}\")\n",
|
|
"print(f\"Python: {PYTHON}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "62a8107a",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"{'ollama_host': 'http://localhost:11434', 'ollama_ready': True}\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"OLLAMA_HOST = \"http://localhost:11434\"\n",
|
|
"OLLAMA_MODEL = \"qwen2.5-coder:7b\"\n",
|
|
"OLLAMA_IS_READY = ollama_ready(OLLAMA_HOST)\n",
|
|
"print({\"ollama_host\": OLLAMA_HOST, \"ollama_ready\": OLLAMA_IS_READY})\n",
|
|
"if not OLLAMA_IS_READY:\n",
|
|
" raise RuntimeError(\"Ollama is not reachable. Start Ollama before running the live smoke test.\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "b58cc4d9",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"PosixPath('/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code/notebooks/demo_task.json')"
|
|
]
|
|
},
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"task_packet = {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
"}\n",
|
|
"\n",
|
|
"task_path = NOTEBOOK_DIR / \"demo_task.json\"\n",
|
|
"task_path.write_text(json.dumps(task_packet, indent=2), encoding=\"utf-8\")\n",
|
|
"task_path"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "e2c19f73",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"$ /Users/wongdowling/opt/anaconda3/bin/python -m src.main worker create --root /Users/wongdowling/Documents/autoresearch_harness/harness/claw-code --model qwen2.5-coder:7b --host http://localhost:11434\n",
|
|
"{\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"root\": \"/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\",\n",
|
|
" \"model\": \"qwen2.5-coder:7b\",\n",
|
|
" \"host\": \"http://localhost:11434\",\n",
|
|
" \"state\": \"ready\",\n",
|
|
" \"created_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"updated_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"run_count\": 0,\n",
|
|
" \"last_packet\": null,\n",
|
|
" \"last_result\": null,\n",
|
|
" \"last_error\": null\n",
|
|
"}\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{'worker_id': '07786cd4905d4275ab8666a113bf7e10',\n",
|
|
" 'root': '/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code',\n",
|
|
" 'model': 'qwen2.5-coder:7b',\n",
|
|
" 'host': 'http://localhost:11434',\n",
|
|
" 'state': 'ready',\n",
|
|
" 'created_at': '2026-04-07T20:09:34Z',\n",
|
|
" 'updated_at': '2026-04-07T20:09:34Z',\n",
|
|
" 'run_count': 0,\n",
|
|
" 'last_packet': None,\n",
|
|
" 'last_result': None,\n",
|
|
" 'last_error': None}"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"worker = run_json([\n",
|
|
" PYTHON,\n",
|
|
" \"-m\",\n",
|
|
" \"src.main\",\n",
|
|
" \"worker\",\n",
|
|
" \"create\",\n",
|
|
" \"--root\",\n",
|
|
" str(ROOT),\n",
|
|
" \"--model\",\n",
|
|
" OLLAMA_MODEL,\n",
|
|
" \"--host\",\n",
|
|
" OLLAMA_HOST,\n",
|
|
"])\n",
|
|
"worker_id = worker[\"worker_id\"]\n",
|
|
"worker"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"$ /Users/wongdowling/opt/anaconda3/bin/python -m src.main worker run 07786cd4905d4275ab8666a113bf7e10 --packet /Users/wongdowling/Documents/autoresearch_harness/harness/claw-code/notebooks/demo_task.json --trace\n",
|
|
"{\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"root\": \"/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\",\n",
|
|
" \"model\": \"qwen2.5-coder:7b\",\n",
|
|
" \"host\": \"http://localhost:11434\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"created_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"updated_at\": \"2026-04-07T20:10:20Z\",\n",
|
|
" \"run_count\": 1,\n",
|
|
" \"last_packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"last_result\": {\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"tool_calls\": [\n",
|
|
" \"read_file\"\n",
|
|
" ],\n",
|
|
" \"tool_trace\": [\n",
|
|
" {\n",
|
|
" \"turn\": 1,\n",
|
|
" \"name\": \"read_file\",\n",
|
|
" \"arguments\": {\n",
|
|
" \"path\": \"src/main.py\"\n",
|
|
" },\n",
|
|
" \"success\": true,\n",
|
|
" \"output\": \"1\\tfrom __future__ import annotations\\n2\\t\\n3\\timport argparse\\n4\\timport json\\n5\\timport sys\\n6\\tfrom pathlib import Path\\n7\\t\\n8\\tfrom .autoresearch_runner import parse_run_log, setup_autoresearch\\n9\\tfrom .autoresearch_worker import run_autoresearch_packet\\n10\\tfrom .bootstrap_graph import build_bootstrap_graph\\n11\\tfrom .command_graph import build_command_graph\\n12\\tfrom .commands import execute_command, get_command, get_commands, render_command_index\\n13\\tfrom .agent_loop import DEFAULT_AGENT_SYSTEM_PROMPT, run_agent_task\\n14\\tfrom .llm_backend import DEFAULT_OLLAMA_HOST, DEFAULT_OLLAMA_MODEL, LLMBackendError\\n15\\tfrom .direct_modes import run_deep_link, run_direct_connect\\n16\\tfrom .parity_audit import run_parity_audit\\n17\\tfrom .permissions import ToolPermissionContext\\n18\\tfrom .port_manifest import build_port_manifest\\n19\\tfrom .query_engine import QueryEnginePort\\n20\\tfrom .remote_runtime import run_remote_mode, run_ssh_mode, run_teleport_mode\\n21\\tfrom .runtime import PortRuntime\\n22\\tfrom .session_store import load_session\\n23\\tfrom .setup import run_setup\\n24\\tfrom .task import DEFAULT_SYSTEM_PROMPT, run_local_task\\n25\\tfrom .worker_api import close_worker, create_worker, list_workers, load_worker, resume_worker, run_worker\\n26\\tfrom .tool_pool import assemble_tool_pool\\n27\\tfrom .tools import execute_tool, get_tool, get_tools, render_tool_index\\n28\\t\\n29\\t\\n30\\tdef build_parser() -> argparse.ArgumentParser:\\n31\\t parser = argparse.ArgumentParser(description='Python porting workspace for the Claude Code rewrite effort')\\n32\\t subparsers = parser.add_subparsers(dest='command', required=True)\\n33\\t subparsers.add_parser('summary', help='render a Markdown summary of the Python porting workspace')\\n34\\t subparsers.add_parser('manifest', help='print the current Python workspace manifest')\\n35\\t subparsers.add_parser('parity-audit', help='compare the Python workspace against the local ignored TypeScript archive when available')\\n36\\t subparsers.add_parser('setup-report', help='render the startup/prefetch setup report')\\n37\\t subparsers.add_parser('command-graph', help='show command graph segmentation')\\n38\\t subparsers.add_parser('tool-pool', help='show assembled tool pool with default settings')\\n39\\t subparsers.add_parser('bootstrap-graph', help='show the mirrored bootstrap/runtime graph stages')\\n40\\t list_parser = subparsers.add_parser('subsystems', help='list the current Python modules in the workspace')\\n41\\t list_parser.add_argument('--limit', type=int, default=32)\\n42\\t\\n43\\t commands_parser = subparsers.add_parser('commands', help='list mirrored command entries from the archived snapshot')\\n44\\t commands_parser.add_argument('--limit', type=int, default=20)\\n45\\t commands_parser.add_argument('--query')\\n46\\t commands_parser.add_argument('--no-plugin-commands', action='store_true')\\n47\\t commands_parser.add_argument('--no-skill-commands', action='store_true')\\n48\\t\\n49\\t tools_parser = subparsers.add_parser('tools', help='list mirrored tool entries from the archived snapshot')\\n50\\t tools_parser.add_argument('--limit', type=int, default=20)\\n51\\t tools_parser.add_argument('--query')\\n52\\t tools_parser.add_argument('--simple-mode', action='store_true')\\n53\\t tools_parser.add_argument('--no-mcp', action='store_true')\\n54\\t tools_parser.add_argument('--deny-tool', action='append', default=[])\\n55\\t tools_parser.add_argument('--deny-prefix', action='append', default=[])\\n56\\t\\n57\\t route_parser = subparsers.add_parser('route', help='route a prompt across mirrored command/tool inventories')\\n58\\t route_parser.add_argument('prompt')\\n59\\t route_parser.add_argument('--limit', type=int, default=5)\\n60\\t\\n61\\t bootstrap_parser = subparsers.add_parser('bootstrap', help='build a runtime-style session report from the mirrored inventories')\\n62\\t bootstrap_parser.add_argument('prompt')\\n63\\t bootstrap_parser.add_argument('--limit', type=int, default=5)\\n64\\t\\n65\\t loop_parser = subparsers.add_parser('turn-loop', help='run a small stateful turn loop for the mirrored runtime')\\n66\\t loop_parser.add_argument('prompt')\\n67\\t loop_parser.add_argument('--limit', type=int, default=5)\\n68\\t loop_parser.add_argument('--max-turns', type=int, default=3)\\n69\\t loop_parser.add_argument('--structured-output', action='store_true')\\n70\\t\\n71\\t flush_parser = subparsers.add_parser('flush-transcript', help='persist and flush a temporary session transcript')\\n72\\t flush_parser.add_argument('prompt')\\n73\\t\\n74\\t load_session_parser = subparsers.add_parser('load-session', help='load a previously persisted session')\\n75\\t load_session_parser.add_argument('session_id')\\n76\\t\\n77\\t remote_parser = subparsers.add_parser('remote-mode', help='simulate remote-control runtime branching')\\n78\\t remote_parser.add_argument('target')\\n79\\t ssh_parser = subparsers.add_parser('ssh-mode', help='simulate SSH runtime branching')\\n80\\t ssh_parser.add_argument('target')\\n81\\t teleport_parser = subparsers.add_parser('teleport-mode', help='simulate teleport runtime branching')\\n82\\t teleport_parser.add_argument('target')\\n83\\t direct_parser = subparsers.add_parser('direct-connect-mode', help='simulate direct-connect runtime branching')\\n84\\t direct_parser.add_argument('target')\\n85\\t deep_link_parser = subparsers.add_parser('deep-link-mode', help='simulate deep-link runtime branching')\\n86\\t deep_link_parser.add_argument('target')\\n87\\t\\n88\\t show_command = subparsers.add_parser('show-command', help='show one mirrored command entry by exact name')\\n89\\t show_command.add_argument('name')\\n90\\t show_tool = subparsers.add_parser('show-tool', help='show one mirrored tool entry by exact name')\\n91\\t show_tool.add_argument('name')\\n92\\t\\n93\\t exec_command_parser = subparsers.add_parser('exec-command', help='execute a mirrored command shim by exact name')\\n94\\t exec_command_parser.add_argument('name')\\n95\\t exec_command_parser.add_argument('prompt')\\n96\\t\\n97\\t exec_tool_parser = subparsers.add_parser('exec-tool', help='execute a mirrored tool shim by exact name')\\n98\\t exec_tool_parser.add_argument('name')\\n99\\t exec_tool_parser.add_argument('payload')\\n100\\t\\n101\\t chat_parser = subparsers.add_parser('chat', help='send a prompt to a local Ollama model')\\n102\\t chat_parser.add_argument('prompt', nargs='?')\\n103\\t chat_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n104\\t chat_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n105\\t chat_parser.add_argument('--system')\\n106\\t\\n107\\t agent_parser = subparsers.add_parser('agent', help='run the local Ollama agent loop with executable workspace tools')\\n108\\t agent_parser.add_argument('prompt', nargs='?')\\n109\\t agent_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n110\\t agent_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n111\\t agent_parser.add_argument('--system')\\n112\\t agent_parser.add_argument('--max-turns', type=int, default=8)\\n113\\t agent_parser.add_argument('--deny-tool', action='append', default=[])\\n114\\t agent_parser.add_argument('--deny-prefix', action='append', default=[])\\n115\\t agent_parser.add_argument('--trace', action='store_true')\\n116\\t\\n117\\t worker_parser = subparsers.add_parser('worker', help='manage structured local Ollama workers')\\n118\\t worker_subparsers = worker_parser.add_subparsers(dest='worker_command', required=True)\\n119\\t\\n120\\t worker_create = worker_subparsers.add_parser('create', help='create a worker record')\\n121\\t worker_create.add_argument('--root', default='.')\\n122\\t worker_create.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n123\\t worker_create.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n124\\t\\n125\\t worker_subparsers.add_parser('list', help='list stored worker records')\\n126\\t\\n127\\t worker_run = worker_subparsers.add_parser('run', help='run a task packet on a worker')\\n128\\t worker_run.add_argument('worker_id')\\n129\\t worker_run.add_argument('--packet', required=True)\\n130\\t worker_run.add_argument('--trace', action='store_true')\\n131\\t\\n132\\t worker_status = worker_subparsers.add_parser('status', help='show worker state')\\n133\\t worker_status.add_argument('worker_id')\\n134\\t\\n135\\t worker_resume = worker_subparsers.add_parser('resume', help='rerun the last stored task packet')\\n136\\t worker_resume.add_argument('worker_id')\\n137\\t worker_resume.add_argument('--trace', action='store_true')\\n138\\t\\n139\\t worker_close = worker_subparsers.add_parser('close', help='close a worker record')\\n140\\t worker_close.add_argument('worker_id')\\n141\\t\\n142\\t autoresearch_parser = subparsers.add_parser('autoresearch', help='project-specific control plane for autoresearch experiments')\\n143\\t autoresearch_subparsers = autoresearch_parser.add_subparsers(dest='autoresearch_command', required=True)\\n144\\t\\n145\\t autoresearch_setup = autoresearch_subparsers.add_parser('setup', help='verify autoresearch repo state and initialize results.tsv')\\n146\\t autoresearch_setup.add_argument('--root')\\n147\\t autoresearch_setup.add_argument('--no-init-results', action='store_true')\\n148\\t\\n149\\t autoresearch_run = autoresearch_subparsers.add_parser('run', help='run one autoresearch experiment packet through the worker + experiment runner')\\n150\\t autoresearch_run.add_argument('--root')\\n151\\t autoresearch_run.add_argument('--packet', required=True)\\n152\\t autoresearch_run.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n153\\t autoresearch_run.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n154\\t autoresearch_run.add_argument('--trace', action='store_true')\\n155\\t\\n156\\t autoresearch_parse_log = autoresearch_subparsers.add_parser('parse-log', help='parse a train.py run log into machine-readable metrics')\\n157\\t autoresearch_parse_log.add_argument('--root')\\n158\\t autoresearch_parse_log.add_argument('log_path')\\n159\\t return parser\\n160\\t\\n161\\t\\n162\\tdef resolve_chat_prompt(args: argparse.Namespace, parser: argparse.ArgumentParser) -> str:\\n163\\t if args.prompt:\\n164\\t return args.prompt\\n165\\t prompt = sys.stdin.read().strip()\\n166\\t if prompt:\\n167\\t return prompt\\n168\\t command_name = getattr(args, 'command', 'command')\\n169\\t parser.error(f'{command_name} requires a prompt argument or stdin input')\\n170\\t raise AssertionError('unreachable')\\n171\\t\\n172\\t\\n173\\tdef main(argv: list[str] | None = None) -> int:\\n174\\t parser = build_parser()\\n175\\t args = parser.parse_args(argv)\\n176\\t manifest = build_port_manifest()\\n177\\t if args.command == 'summary':\\n178\\t print(QueryEnginePort(manifest).render_summary())\\n179\\t return 0\\n180\\t if args.command == 'manifest':\\n181\\t print(manifest.to_markdown())\\n182\\t return 0\\n183\\t if args.command == 'parity-audit':\\n184\\t print(run_parity_audit().to_markdown())\\n185\\t return 0\\n186\\t if args.command == 'setup-report':\\n187\\t print(run_setup().as_markdown())\\n188\\t return 0\\n189\\t if args.command == 'command-graph':\\n190\\t print(build_command_graph().as_markdown())\\n191\\t return 0\\n192\\t if args.command == 'tool-pool':\\n193\\t print(assemble_tool_pool().as_markdown())\\n194\\t return 0\\n195\\t if args.command == 'bootstrap-graph':\\n196\\t print(build_bootstrap_graph().as_markdown())\\n197\\t return 0\\n198\\t if args.command == 'subsystems':\\n199\\t for subsystem in manifest.top_level_modules[: args.limit]:\\n200\\t print(f'{subsystem.name}\\\\t{subsystem.file_count}\\\\t{subsystem.notes}')\\n201\\t return 0\\n202\\t if args.command == 'commands':\\n203\\t if args.query:\\n204\\t print(render_command_index(limit=args.limit, query=args.query))\\n205\\t else:\\n206\\t commands = get_commands(include_plugin_commands=not args.no_plugin_commands, include_skill_commands=not args.no_skill_commands)\\n207\\t output_lines = [f'Command entries: {len(commands)}', '']\\n208\\t output_lines.extend(f'- {module.name} \\u2014 {module.source_hint}' for module in commands[: args.limit])\\n209\\t print('\\\\n'.join(output_lines))\\n210\\t return 0\\n...[truncated]\",\n",
|
|
" \"metadata\": {\n",
|
|
" \"path\": \"src/main.py\",\n",
|
|
" \"start_line\": 1,\n",
|
|
" \"end_line\": 386,\n",
|
|
" \"line_count\": 386\n",
|
|
" },\n",
|
|
" \"error\": null\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"artifacts\": [],\n",
|
|
" \"changed_files\": [],\n",
|
|
" \"verification\": {\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" {\n",
|
|
" \"command\": \"python3 -m unittest tests/test_porting_workspace.py\",\n",
|
|
" \"success\": true,\n",
|
|
" \"exit_code\": 0,\n",
|
|
" \"output\": \".........................................\\n----------------------------------------------------------------------\\nRan 41 tests in 4.739s\\n\\nOK\"\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"tool_runs\": {\n",
|
|
" \"run_tests\": [],\n",
|
|
" \"run_build\": []\n",
|
|
" }\n",
|
|
" },\n",
|
|
" \"final_answer\": \"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\",\n",
|
|
" \"stop_reason\": \"completed\",\n",
|
|
" \"turns\": 3,\n",
|
|
" \"trace_events\": [\n",
|
|
" \"assistant_raw[1]={\\\"type\\\":\\\"tool_call\\\",\\\"name\\\":\\\"read_file\\\",\\\"arguments\\\":{\\\"path\\\":\\\"src/main.py\\\"}}\",\n",
|
|
" \"tool_call[1]=read_file {\\\"path\\\": \\\"src/main.py\\\"}\",\n",
|
|
" \"tool_result[1]=read_file success=True error=None\",\n",
|
|
" \"assistant_raw[2]={\\\"response\\\": \\\"The provided code snippet is from a Python script located at 'src/main.py'. It appears to be the main entry point for a command-line interface (CLI) application. The script defines several subcommands and their corresponding functionalities, such as building parsers, resolving chat prompts, and executing various commands like 'summary', 'manifest', 'parity-audit', etc. Each subcommand is handled within conditional statements in the `main` function. The script also includes functions for parsing logs, running experiments, and managing workers. Overall, this script serves as a control plane for managing and interacting with an autoresearch experiment environment.\\\"}\",\n",
|
|
" \"protocol_error[2]=Response type must be either \\\"tool_call\\\" or \\\"final\\\".\",\n",
|
|
" \"assistant_raw[3]={\\\"type\\\":\\\"final\\\",\\\"content\\\":\\\"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\\\"}\"\n",
|
|
" ]\n",
|
|
" },\n",
|
|
" \"last_error\": null\n",
|
|
"}\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"('finished', 'completed')"
|
|
]
|
|
},
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"worker_run = run_json([\n",
|
|
" PYTHON,\n",
|
|
" \"-m\",\n",
|
|
" \"src.main\",\n",
|
|
" \"worker\",\n",
|
|
" \"run\",\n",
|
|
" worker_id,\n",
|
|
" \"--packet\",\n",
|
|
" str(task_path),\n",
|
|
" \"--trace\",\n",
|
|
"])\n",
|
|
"worker_run[\"state\"], worker_run[\"last_result\"][\"stop_reason\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"tool_calls: ['read_file']\n",
|
|
"changed_files: []\n",
|
|
"verification:\n",
|
|
"{\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" {\n",
|
|
" \"command\": \"python3 -m unittest tests/test_porting_workspace.py\",\n",
|
|
" \"success\": true,\n",
|
|
" \"exit_code\": 0,\n",
|
|
" \"output\": \".........................................\\n----------------------------------------------------------------------\\nRan 41 tests in 4.739s\\n\\nOK\"\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"tool_runs\": {\n",
|
|
" \"run_tests\": [],\n",
|
|
" \"run_build\": []\n",
|
|
" }\n",
|
|
"}\n",
|
|
"final_answer:\n",
|
|
"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"result = worker_run[\"last_result\"]\n",
|
|
"print(\"tool_calls:\", result[\"tool_calls\"])\n",
|
|
"print(\"changed_files:\", result[\"changed_files\"])\n",
|
|
"print(\"verification:\")\n",
|
|
"print(json.dumps(result[\"verification\"], indent=2))\n",
|
|
"print(\"final_answer:\")\n",
|
|
"print(result[\"final_answer\"])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"$ /Users/wongdowling/opt/anaconda3/bin/python -m src.main worker status 07786cd4905d4275ab8666a113bf7e10\n",
|
|
"{\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"root\": \"/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\",\n",
|
|
" \"model\": \"qwen2.5-coder:7b\",\n",
|
|
" \"host\": \"http://localhost:11434\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"created_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"updated_at\": \"2026-04-07T20:10:20Z\",\n",
|
|
" \"run_count\": 1,\n",
|
|
" \"last_packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"last_result\": {\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"tool_calls\": [\n",
|
|
" \"read_file\"\n",
|
|
" ],\n",
|
|
" \"tool_trace\": [\n",
|
|
" {\n",
|
|
" \"turn\": 1,\n",
|
|
" \"name\": \"read_file\",\n",
|
|
" \"arguments\": {\n",
|
|
" \"path\": \"src/main.py\"\n",
|
|
" },\n",
|
|
" \"success\": true,\n",
|
|
" \"output\": \"1\\tfrom __future__ import annotations\\n2\\t\\n3\\timport argparse\\n4\\timport json\\n5\\timport sys\\n6\\tfrom pathlib import Path\\n7\\t\\n8\\tfrom .autoresearch_runner import parse_run_log, setup_autoresearch\\n9\\tfrom .autoresearch_worker import run_autoresearch_packet\\n10\\tfrom .bootstrap_graph import build_bootstrap_graph\\n11\\tfrom .command_graph import build_command_graph\\n12\\tfrom .commands import execute_command, get_command, get_commands, render_command_index\\n13\\tfrom .agent_loop import DEFAULT_AGENT_SYSTEM_PROMPT, run_agent_task\\n14\\tfrom .llm_backend import DEFAULT_OLLAMA_HOST, DEFAULT_OLLAMA_MODEL, LLMBackendError\\n15\\tfrom .direct_modes import run_deep_link, run_direct_connect\\n16\\tfrom .parity_audit import run_parity_audit\\n17\\tfrom .permissions import ToolPermissionContext\\n18\\tfrom .port_manifest import build_port_manifest\\n19\\tfrom .query_engine import QueryEnginePort\\n20\\tfrom .remote_runtime import run_remote_mode, run_ssh_mode, run_teleport_mode\\n21\\tfrom .runtime import PortRuntime\\n22\\tfrom .session_store import load_session\\n23\\tfrom .setup import run_setup\\n24\\tfrom .task import DEFAULT_SYSTEM_PROMPT, run_local_task\\n25\\tfrom .worker_api import close_worker, create_worker, list_workers, load_worker, resume_worker, run_worker\\n26\\tfrom .tool_pool import assemble_tool_pool\\n27\\tfrom .tools import execute_tool, get_tool, get_tools, render_tool_index\\n28\\t\\n29\\t\\n30\\tdef build_parser() -> argparse.ArgumentParser:\\n31\\t parser = argparse.ArgumentParser(description='Python porting workspace for the Claude Code rewrite effort')\\n32\\t subparsers = parser.add_subparsers(dest='command', required=True)\\n33\\t subparsers.add_parser('summary', help='render a Markdown summary of the Python porting workspace')\\n34\\t subparsers.add_parser('manifest', help='print the current Python workspace manifest')\\n35\\t subparsers.add_parser('parity-audit', help='compare the Python workspace against the local ignored TypeScript archive when available')\\n36\\t subparsers.add_parser('setup-report', help='render the startup/prefetch setup report')\\n37\\t subparsers.add_parser('command-graph', help='show command graph segmentation')\\n38\\t subparsers.add_parser('tool-pool', help='show assembled tool pool with default settings')\\n39\\t subparsers.add_parser('bootstrap-graph', help='show the mirrored bootstrap/runtime graph stages')\\n40\\t list_parser = subparsers.add_parser('subsystems', help='list the current Python modules in the workspace')\\n41\\t list_parser.add_argument('--limit', type=int, default=32)\\n42\\t\\n43\\t commands_parser = subparsers.add_parser('commands', help='list mirrored command entries from the archived snapshot')\\n44\\t commands_parser.add_argument('--limit', type=int, default=20)\\n45\\t commands_parser.add_argument('--query')\\n46\\t commands_parser.add_argument('--no-plugin-commands', action='store_true')\\n47\\t commands_parser.add_argument('--no-skill-commands', action='store_true')\\n48\\t\\n49\\t tools_parser = subparsers.add_parser('tools', help='list mirrored tool entries from the archived snapshot')\\n50\\t tools_parser.add_argument('--limit', type=int, default=20)\\n51\\t tools_parser.add_argument('--query')\\n52\\t tools_parser.add_argument('--simple-mode', action='store_true')\\n53\\t tools_parser.add_argument('--no-mcp', action='store_true')\\n54\\t tools_parser.add_argument('--deny-tool', action='append', default=[])\\n55\\t tools_parser.add_argument('--deny-prefix', action='append', default=[])\\n56\\t\\n57\\t route_parser = subparsers.add_parser('route', help='route a prompt across mirrored command/tool inventories')\\n58\\t route_parser.add_argument('prompt')\\n59\\t route_parser.add_argument('--limit', type=int, default=5)\\n60\\t\\n61\\t bootstrap_parser = subparsers.add_parser('bootstrap', help='build a runtime-style session report from the mirrored inventories')\\n62\\t bootstrap_parser.add_argument('prompt')\\n63\\t bootstrap_parser.add_argument('--limit', type=int, default=5)\\n64\\t\\n65\\t loop_parser = subparsers.add_parser('turn-loop', help='run a small stateful turn loop for the mirrored runtime')\\n66\\t loop_parser.add_argument('prompt')\\n67\\t loop_parser.add_argument('--limit', type=int, default=5)\\n68\\t loop_parser.add_argument('--max-turns', type=int, default=3)\\n69\\t loop_parser.add_argument('--structured-output', action='store_true')\\n70\\t\\n71\\t flush_parser = subparsers.add_parser('flush-transcript', help='persist and flush a temporary session transcript')\\n72\\t flush_parser.add_argument('prompt')\\n73\\t\\n74\\t load_session_parser = subparsers.add_parser('load-session', help='load a previously persisted session')\\n75\\t load_session_parser.add_argument('session_id')\\n76\\t\\n77\\t remote_parser = subparsers.add_parser('remote-mode', help='simulate remote-control runtime branching')\\n78\\t remote_parser.add_argument('target')\\n79\\t ssh_parser = subparsers.add_parser('ssh-mode', help='simulate SSH runtime branching')\\n80\\t ssh_parser.add_argument('target')\\n81\\t teleport_parser = subparsers.add_parser('teleport-mode', help='simulate teleport runtime branching')\\n82\\t teleport_parser.add_argument('target')\\n83\\t direct_parser = subparsers.add_parser('direct-connect-mode', help='simulate direct-connect runtime branching')\\n84\\t direct_parser.add_argument('target')\\n85\\t deep_link_parser = subparsers.add_parser('deep-link-mode', help='simulate deep-link runtime branching')\\n86\\t deep_link_parser.add_argument('target')\\n87\\t\\n88\\t show_command = subparsers.add_parser('show-command', help='show one mirrored command entry by exact name')\\n89\\t show_command.add_argument('name')\\n90\\t show_tool = subparsers.add_parser('show-tool', help='show one mirrored tool entry by exact name')\\n91\\t show_tool.add_argument('name')\\n92\\t\\n93\\t exec_command_parser = subparsers.add_parser('exec-command', help='execute a mirrored command shim by exact name')\\n94\\t exec_command_parser.add_argument('name')\\n95\\t exec_command_parser.add_argument('prompt')\\n96\\t\\n97\\t exec_tool_parser = subparsers.add_parser('exec-tool', help='execute a mirrored tool shim by exact name')\\n98\\t exec_tool_parser.add_argument('name')\\n99\\t exec_tool_parser.add_argument('payload')\\n100\\t\\n101\\t chat_parser = subparsers.add_parser('chat', help='send a prompt to a local Ollama model')\\n102\\t chat_parser.add_argument('prompt', nargs='?')\\n103\\t chat_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n104\\t chat_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n105\\t chat_parser.add_argument('--system')\\n106\\t\\n107\\t agent_parser = subparsers.add_parser('agent', help='run the local Ollama agent loop with executable workspace tools')\\n108\\t agent_parser.add_argument('prompt', nargs='?')\\n109\\t agent_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n110\\t agent_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n111\\t agent_parser.add_argument('--system')\\n112\\t agent_parser.add_argument('--max-turns', type=int, default=8)\\n113\\t agent_parser.add_argument('--deny-tool', action='append', default=[])\\n114\\t agent_parser.add_argument('--deny-prefix', action='append', default=[])\\n115\\t agent_parser.add_argument('--trace', action='store_true')\\n116\\t\\n117\\t worker_parser = subparsers.add_parser('worker', help='manage structured local Ollama workers')\\n118\\t worker_subparsers = worker_parser.add_subparsers(dest='worker_command', required=True)\\n119\\t\\n120\\t worker_create = worker_subparsers.add_parser('create', help='create a worker record')\\n121\\t worker_create.add_argument('--root', default='.')\\n122\\t worker_create.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n123\\t worker_create.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n124\\t\\n125\\t worker_subparsers.add_parser('list', help='list stored worker records')\\n126\\t\\n127\\t worker_run = worker_subparsers.add_parser('run', help='run a task packet on a worker')\\n128\\t worker_run.add_argument('worker_id')\\n129\\t worker_run.add_argument('--packet', required=True)\\n130\\t worker_run.add_argument('--trace', action='store_true')\\n131\\t\\n132\\t worker_status = worker_subparsers.add_parser('status', help='show worker state')\\n133\\t worker_status.add_argument('worker_id')\\n134\\t\\n135\\t worker_resume = worker_subparsers.add_parser('resume', help='rerun the last stored task packet')\\n136\\t worker_resume.add_argument('worker_id')\\n137\\t worker_resume.add_argument('--trace', action='store_true')\\n138\\t\\n139\\t worker_close = worker_subparsers.add_parser('close', help='close a worker record')\\n140\\t worker_close.add_argument('worker_id')\\n141\\t\\n142\\t autoresearch_parser = subparsers.add_parser('autoresearch', help='project-specific control plane for autoresearch experiments')\\n143\\t autoresearch_subparsers = autoresearch_parser.add_subparsers(dest='autoresearch_command', required=True)\\n144\\t\\n145\\t autoresearch_setup = autoresearch_subparsers.add_parser('setup', help='verify autoresearch repo state and initialize results.tsv')\\n146\\t autoresearch_setup.add_argument('--root')\\n147\\t autoresearch_setup.add_argument('--no-init-results', action='store_true')\\n148\\t\\n149\\t autoresearch_run = autoresearch_subparsers.add_parser('run', help='run one autoresearch experiment packet through the worker + experiment runner')\\n150\\t autoresearch_run.add_argument('--root')\\n151\\t autoresearch_run.add_argument('--packet', required=True)\\n152\\t autoresearch_run.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n153\\t autoresearch_run.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n154\\t autoresearch_run.add_argument('--trace', action='store_true')\\n155\\t\\n156\\t autoresearch_parse_log = autoresearch_subparsers.add_parser('parse-log', help='parse a train.py run log into machine-readable metrics')\\n157\\t autoresearch_parse_log.add_argument('--root')\\n158\\t autoresearch_parse_log.add_argument('log_path')\\n159\\t return parser\\n160\\t\\n161\\t\\n162\\tdef resolve_chat_prompt(args: argparse.Namespace, parser: argparse.ArgumentParser) -> str:\\n163\\t if args.prompt:\\n164\\t return args.prompt\\n165\\t prompt = sys.stdin.read().strip()\\n166\\t if prompt:\\n167\\t return prompt\\n168\\t command_name = getattr(args, 'command', 'command')\\n169\\t parser.error(f'{command_name} requires a prompt argument or stdin input')\\n170\\t raise AssertionError('unreachable')\\n171\\t\\n172\\t\\n173\\tdef main(argv: list[str] | None = None) -> int:\\n174\\t parser = build_parser()\\n175\\t args = parser.parse_args(argv)\\n176\\t manifest = build_port_manifest()\\n177\\t if args.command == 'summary':\\n178\\t print(QueryEnginePort(manifest).render_summary())\\n179\\t return 0\\n180\\t if args.command == 'manifest':\\n181\\t print(manifest.to_markdown())\\n182\\t return 0\\n183\\t if args.command == 'parity-audit':\\n184\\t print(run_parity_audit().to_markdown())\\n185\\t return 0\\n186\\t if args.command == 'setup-report':\\n187\\t print(run_setup().as_markdown())\\n188\\t return 0\\n189\\t if args.command == 'command-graph':\\n190\\t print(build_command_graph().as_markdown())\\n191\\t return 0\\n192\\t if args.command == 'tool-pool':\\n193\\t print(assemble_tool_pool().as_markdown())\\n194\\t return 0\\n195\\t if args.command == 'bootstrap-graph':\\n196\\t print(build_bootstrap_graph().as_markdown())\\n197\\t return 0\\n198\\t if args.command == 'subsystems':\\n199\\t for subsystem in manifest.top_level_modules[: args.limit]:\\n200\\t print(f'{subsystem.name}\\\\t{subsystem.file_count}\\\\t{subsystem.notes}')\\n201\\t return 0\\n202\\t if args.command == 'commands':\\n203\\t if args.query:\\n204\\t print(render_command_index(limit=args.limit, query=args.query))\\n205\\t else:\\n206\\t commands = get_commands(include_plugin_commands=not args.no_plugin_commands, include_skill_commands=not args.no_skill_commands)\\n207\\t output_lines = [f'Command entries: {len(commands)}', '']\\n208\\t output_lines.extend(f'- {module.name} \\u2014 {module.source_hint}' for module in commands[: args.limit])\\n209\\t print('\\\\n'.join(output_lines))\\n210\\t return 0\\n...[truncated]\",\n",
|
|
" \"metadata\": {\n",
|
|
" \"path\": \"src/main.py\",\n",
|
|
" \"start_line\": 1,\n",
|
|
" \"end_line\": 386,\n",
|
|
" \"line_count\": 386\n",
|
|
" },\n",
|
|
" \"error\": null\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"artifacts\": [],\n",
|
|
" \"changed_files\": [],\n",
|
|
" \"verification\": {\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" {\n",
|
|
" \"command\": \"python3 -m unittest tests/test_porting_workspace.py\",\n",
|
|
" \"success\": true,\n",
|
|
" \"exit_code\": 0,\n",
|
|
" \"output\": \".........................................\\n----------------------------------------------------------------------\\nRan 41 tests in 4.739s\\n\\nOK\"\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"tool_runs\": {\n",
|
|
" \"run_tests\": [],\n",
|
|
" \"run_build\": []\n",
|
|
" }\n",
|
|
" },\n",
|
|
" \"final_answer\": \"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\",\n",
|
|
" \"stop_reason\": \"completed\",\n",
|
|
" \"turns\": 3,\n",
|
|
" \"trace_events\": [\n",
|
|
" \"assistant_raw[1]={\\\"type\\\":\\\"tool_call\\\",\\\"name\\\":\\\"read_file\\\",\\\"arguments\\\":{\\\"path\\\":\\\"src/main.py\\\"}}\",\n",
|
|
" \"tool_call[1]=read_file {\\\"path\\\": \\\"src/main.py\\\"}\",\n",
|
|
" \"tool_result[1]=read_file success=True error=None\",\n",
|
|
" \"assistant_raw[2]={\\\"response\\\": \\\"The provided code snippet is from a Python script located at 'src/main.py'. It appears to be the main entry point for a command-line interface (CLI) application. The script defines several subcommands and their corresponding functionalities, such as building parsers, resolving chat prompts, and executing various commands like 'summary', 'manifest', 'parity-audit', etc. Each subcommand is handled within conditional statements in the `main` function. The script also includes functions for parsing logs, running experiments, and managing workers. Overall, this script serves as a control plane for managing and interacting with an autoresearch experiment environment.\\\"}\",\n",
|
|
" \"protocol_error[2]=Response type must be either \\\"tool_call\\\" or \\\"final\\\".\",\n",
|
|
" \"assistant_raw[3]={\\\"type\\\":\\\"final\\\",\\\"content\\\":\\\"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\\\"}\"\n",
|
|
" ]\n",
|
|
" },\n",
|
|
" \"last_error\": null\n",
|
|
"}\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'finished'"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"worker_status = run_json([\n",
|
|
" PYTHON,\n",
|
|
" \"-m\",\n",
|
|
" \"src.main\",\n",
|
|
" \"worker\",\n",
|
|
" \"status\",\n",
|
|
" worker_id,\n",
|
|
"])\n",
|
|
"worker_status[\"state\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"$ /Users/wongdowling/opt/anaconda3/bin/python -m src.main worker resume 07786cd4905d4275ab8666a113bf7e10 --trace\n",
|
|
"{\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"root\": \"/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\",\n",
|
|
" \"model\": \"qwen2.5-coder:7b\",\n",
|
|
" \"host\": \"http://localhost:11434\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"created_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"updated_at\": \"2026-04-07T20:10:59Z\",\n",
|
|
" \"run_count\": 2,\n",
|
|
" \"last_packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"last_result\": {\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"tool_calls\": [\n",
|
|
" \"read_file\"\n",
|
|
" ],\n",
|
|
" \"tool_trace\": [\n",
|
|
" {\n",
|
|
" \"turn\": 1,\n",
|
|
" \"name\": \"read_file\",\n",
|
|
" \"arguments\": {\n",
|
|
" \"path\": \"src/main.py\"\n",
|
|
" },\n",
|
|
" \"success\": true,\n",
|
|
" \"output\": \"1\\tfrom __future__ import annotations\\n2\\t\\n3\\timport argparse\\n4\\timport json\\n5\\timport sys\\n6\\tfrom pathlib import Path\\n7\\t\\n8\\tfrom .autoresearch_runner import parse_run_log, setup_autoresearch\\n9\\tfrom .autoresearch_worker import run_autoresearch_packet\\n10\\tfrom .bootstrap_graph import build_bootstrap_graph\\n11\\tfrom .command_graph import build_command_graph\\n12\\tfrom .commands import execute_command, get_command, get_commands, render_command_index\\n13\\tfrom .agent_loop import DEFAULT_AGENT_SYSTEM_PROMPT, run_agent_task\\n14\\tfrom .llm_backend import DEFAULT_OLLAMA_HOST, DEFAULT_OLLAMA_MODEL, LLMBackendError\\n15\\tfrom .direct_modes import run_deep_link, run_direct_connect\\n16\\tfrom .parity_audit import run_parity_audit\\n17\\tfrom .permissions import ToolPermissionContext\\n18\\tfrom .port_manifest import build_port_manifest\\n19\\tfrom .query_engine import QueryEnginePort\\n20\\tfrom .remote_runtime import run_remote_mode, run_ssh_mode, run_teleport_mode\\n21\\tfrom .runtime import PortRuntime\\n22\\tfrom .session_store import load_session\\n23\\tfrom .setup import run_setup\\n24\\tfrom .task import DEFAULT_SYSTEM_PROMPT, run_local_task\\n25\\tfrom .worker_api import close_worker, create_worker, list_workers, load_worker, resume_worker, run_worker\\n26\\tfrom .tool_pool import assemble_tool_pool\\n27\\tfrom .tools import execute_tool, get_tool, get_tools, render_tool_index\\n28\\t\\n29\\t\\n30\\tdef build_parser() -> argparse.ArgumentParser:\\n31\\t parser = argparse.ArgumentParser(description='Python porting workspace for the Claude Code rewrite effort')\\n32\\t subparsers = parser.add_subparsers(dest='command', required=True)\\n33\\t subparsers.add_parser('summary', help='render a Markdown summary of the Python porting workspace')\\n34\\t subparsers.add_parser('manifest', help='print the current Python workspace manifest')\\n35\\t subparsers.add_parser('parity-audit', help='compare the Python workspace against the local ignored TypeScript archive when available')\\n36\\t subparsers.add_parser('setup-report', help='render the startup/prefetch setup report')\\n37\\t subparsers.add_parser('command-graph', help='show command graph segmentation')\\n38\\t subparsers.add_parser('tool-pool', help='show assembled tool pool with default settings')\\n39\\t subparsers.add_parser('bootstrap-graph', help='show the mirrored bootstrap/runtime graph stages')\\n40\\t list_parser = subparsers.add_parser('subsystems', help='list the current Python modules in the workspace')\\n41\\t list_parser.add_argument('--limit', type=int, default=32)\\n42\\t\\n43\\t commands_parser = subparsers.add_parser('commands', help='list mirrored command entries from the archived snapshot')\\n44\\t commands_parser.add_argument('--limit', type=int, default=20)\\n45\\t commands_parser.add_argument('--query')\\n46\\t commands_parser.add_argument('--no-plugin-commands', action='store_true')\\n47\\t commands_parser.add_argument('--no-skill-commands', action='store_true')\\n48\\t\\n49\\t tools_parser = subparsers.add_parser('tools', help='list mirrored tool entries from the archived snapshot')\\n50\\t tools_parser.add_argument('--limit', type=int, default=20)\\n51\\t tools_parser.add_argument('--query')\\n52\\t tools_parser.add_argument('--simple-mode', action='store_true')\\n53\\t tools_parser.add_argument('--no-mcp', action='store_true')\\n54\\t tools_parser.add_argument('--deny-tool', action='append', default=[])\\n55\\t tools_parser.add_argument('--deny-prefix', action='append', default=[])\\n56\\t\\n57\\t route_parser = subparsers.add_parser('route', help='route a prompt across mirrored command/tool inventories')\\n58\\t route_parser.add_argument('prompt')\\n59\\t route_parser.add_argument('--limit', type=int, default=5)\\n60\\t\\n61\\t bootstrap_parser = subparsers.add_parser('bootstrap', help='build a runtime-style session report from the mirrored inventories')\\n62\\t bootstrap_parser.add_argument('prompt')\\n63\\t bootstrap_parser.add_argument('--limit', type=int, default=5)\\n64\\t\\n65\\t loop_parser = subparsers.add_parser('turn-loop', help='run a small stateful turn loop for the mirrored runtime')\\n66\\t loop_parser.add_argument('prompt')\\n67\\t loop_parser.add_argument('--limit', type=int, default=5)\\n68\\t loop_parser.add_argument('--max-turns', type=int, default=3)\\n69\\t loop_parser.add_argument('--structured-output', action='store_true')\\n70\\t\\n71\\t flush_parser = subparsers.add_parser('flush-transcript', help='persist and flush a temporary session transcript')\\n72\\t flush_parser.add_argument('prompt')\\n73\\t\\n74\\t load_session_parser = subparsers.add_parser('load-session', help='load a previously persisted session')\\n75\\t load_session_parser.add_argument('session_id')\\n76\\t\\n77\\t remote_parser = subparsers.add_parser('remote-mode', help='simulate remote-control runtime branching')\\n78\\t remote_parser.add_argument('target')\\n79\\t ssh_parser = subparsers.add_parser('ssh-mode', help='simulate SSH runtime branching')\\n80\\t ssh_parser.add_argument('target')\\n81\\t teleport_parser = subparsers.add_parser('teleport-mode', help='simulate teleport runtime branching')\\n82\\t teleport_parser.add_argument('target')\\n83\\t direct_parser = subparsers.add_parser('direct-connect-mode', help='simulate direct-connect runtime branching')\\n84\\t direct_parser.add_argument('target')\\n85\\t deep_link_parser = subparsers.add_parser('deep-link-mode', help='simulate deep-link runtime branching')\\n86\\t deep_link_parser.add_argument('target')\\n87\\t\\n88\\t show_command = subparsers.add_parser('show-command', help='show one mirrored command entry by exact name')\\n89\\t show_command.add_argument('name')\\n90\\t show_tool = subparsers.add_parser('show-tool', help='show one mirrored tool entry by exact name')\\n91\\t show_tool.add_argument('name')\\n92\\t\\n93\\t exec_command_parser = subparsers.add_parser('exec-command', help='execute a mirrored command shim by exact name')\\n94\\t exec_command_parser.add_argument('name')\\n95\\t exec_command_parser.add_argument('prompt')\\n96\\t\\n97\\t exec_tool_parser = subparsers.add_parser('exec-tool', help='execute a mirrored tool shim by exact name')\\n98\\t exec_tool_parser.add_argument('name')\\n99\\t exec_tool_parser.add_argument('payload')\\n100\\t\\n101\\t chat_parser = subparsers.add_parser('chat', help='send a prompt to a local Ollama model')\\n102\\t chat_parser.add_argument('prompt', nargs='?')\\n103\\t chat_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n104\\t chat_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n105\\t chat_parser.add_argument('--system')\\n106\\t\\n107\\t agent_parser = subparsers.add_parser('agent', help='run the local Ollama agent loop with executable workspace tools')\\n108\\t agent_parser.add_argument('prompt', nargs='?')\\n109\\t agent_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n110\\t agent_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n111\\t agent_parser.add_argument('--system')\\n112\\t agent_parser.add_argument('--max-turns', type=int, default=8)\\n113\\t agent_parser.add_argument('--deny-tool', action='append', default=[])\\n114\\t agent_parser.add_argument('--deny-prefix', action='append', default=[])\\n115\\t agent_parser.add_argument('--trace', action='store_true')\\n116\\t\\n117\\t worker_parser = subparsers.add_parser('worker', help='manage structured local Ollama workers')\\n118\\t worker_subparsers = worker_parser.add_subparsers(dest='worker_command', required=True)\\n119\\t\\n120\\t worker_create = worker_subparsers.add_parser('create', help='create a worker record')\\n121\\t worker_create.add_argument('--root', default='.')\\n122\\t worker_create.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n123\\t worker_create.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n124\\t\\n125\\t worker_subparsers.add_parser('list', help='list stored worker records')\\n126\\t\\n127\\t worker_run = worker_subparsers.add_parser('run', help='run a task packet on a worker')\\n128\\t worker_run.add_argument('worker_id')\\n129\\t worker_run.add_argument('--packet', required=True)\\n130\\t worker_run.add_argument('--trace', action='store_true')\\n131\\t\\n132\\t worker_status = worker_subparsers.add_parser('status', help='show worker state')\\n133\\t worker_status.add_argument('worker_id')\\n134\\t\\n135\\t worker_resume = worker_subparsers.add_parser('resume', help='rerun the last stored task packet')\\n136\\t worker_resume.add_argument('worker_id')\\n137\\t worker_resume.add_argument('--trace', action='store_true')\\n138\\t\\n139\\t worker_close = worker_subparsers.add_parser('close', help='close a worker record')\\n140\\t worker_close.add_argument('worker_id')\\n141\\t\\n142\\t autoresearch_parser = subparsers.add_parser('autoresearch', help='project-specific control plane for autoresearch experiments')\\n143\\t autoresearch_subparsers = autoresearch_parser.add_subparsers(dest='autoresearch_command', required=True)\\n144\\t\\n145\\t autoresearch_setup = autoresearch_subparsers.add_parser('setup', help='verify autoresearch repo state and initialize results.tsv')\\n146\\t autoresearch_setup.add_argument('--root')\\n147\\t autoresearch_setup.add_argument('--no-init-results', action='store_true')\\n148\\t\\n149\\t autoresearch_run = autoresearch_subparsers.add_parser('run', help='run one autoresearch experiment packet through the worker + experiment runner')\\n150\\t autoresearch_run.add_argument('--root')\\n151\\t autoresearch_run.add_argument('--packet', required=True)\\n152\\t autoresearch_run.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n153\\t autoresearch_run.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n154\\t autoresearch_run.add_argument('--trace', action='store_true')\\n155\\t\\n156\\t autoresearch_parse_log = autoresearch_subparsers.add_parser('parse-log', help='parse a train.py run log into machine-readable metrics')\\n157\\t autoresearch_parse_log.add_argument('--root')\\n158\\t autoresearch_parse_log.add_argument('log_path')\\n159\\t return parser\\n160\\t\\n161\\t\\n162\\tdef resolve_chat_prompt(args: argparse.Namespace, parser: argparse.ArgumentParser) -> str:\\n163\\t if args.prompt:\\n164\\t return args.prompt\\n165\\t prompt = sys.stdin.read().strip()\\n166\\t if prompt:\\n167\\t return prompt\\n168\\t command_name = getattr(args, 'command', 'command')\\n169\\t parser.error(f'{command_name} requires a prompt argument or stdin input')\\n170\\t raise AssertionError('unreachable')\\n171\\t\\n172\\t\\n173\\tdef main(argv: list[str] | None = None) -> int:\\n174\\t parser = build_parser()\\n175\\t args = parser.parse_args(argv)\\n176\\t manifest = build_port_manifest()\\n177\\t if args.command == 'summary':\\n178\\t print(QueryEnginePort(manifest).render_summary())\\n179\\t return 0\\n180\\t if args.command == 'manifest':\\n181\\t print(manifest.to_markdown())\\n182\\t return 0\\n183\\t if args.command == 'parity-audit':\\n184\\t print(run_parity_audit().to_markdown())\\n185\\t return 0\\n186\\t if args.command == 'setup-report':\\n187\\t print(run_setup().as_markdown())\\n188\\t return 0\\n189\\t if args.command == 'command-graph':\\n190\\t print(build_command_graph().as_markdown())\\n191\\t return 0\\n192\\t if args.command == 'tool-pool':\\n193\\t print(assemble_tool_pool().as_markdown())\\n194\\t return 0\\n195\\t if args.command == 'bootstrap-graph':\\n196\\t print(build_bootstrap_graph().as_markdown())\\n197\\t return 0\\n198\\t if args.command == 'subsystems':\\n199\\t for subsystem in manifest.top_level_modules[: args.limit]:\\n200\\t print(f'{subsystem.name}\\\\t{subsystem.file_count}\\\\t{subsystem.notes}')\\n201\\t return 0\\n202\\t if args.command == 'commands':\\n203\\t if args.query:\\n204\\t print(render_command_index(limit=args.limit, query=args.query))\\n205\\t else:\\n206\\t commands = get_commands(include_plugin_commands=not args.no_plugin_commands, include_skill_commands=not args.no_skill_commands)\\n207\\t output_lines = [f'Command entries: {len(commands)}', '']\\n208\\t output_lines.extend(f'- {module.name} \\u2014 {module.source_hint}' for module in commands[: args.limit])\\n209\\t print('\\\\n'.join(output_lines))\\n210\\t return 0\\n...[truncated]\",\n",
|
|
" \"metadata\": {\n",
|
|
" \"path\": \"src/main.py\",\n",
|
|
" \"start_line\": 1,\n",
|
|
" \"end_line\": 386,\n",
|
|
" \"line_count\": 386\n",
|
|
" },\n",
|
|
" \"error\": null\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"artifacts\": [],\n",
|
|
" \"changed_files\": [],\n",
|
|
" \"verification\": {\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" {\n",
|
|
" \"command\": \"python3 -m unittest tests/test_porting_workspace.py\",\n",
|
|
" \"success\": true,\n",
|
|
" \"exit_code\": 0,\n",
|
|
" \"output\": \".........................................\\n----------------------------------------------------------------------\\nRan 41 tests in 3.865s\\n\\nOK\"\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"tool_runs\": {\n",
|
|
" \"run_tests\": [],\n",
|
|
" \"run_build\": []\n",
|
|
" }\n",
|
|
" },\n",
|
|
" \"final_answer\": \"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\",\n",
|
|
" \"stop_reason\": \"completed\",\n",
|
|
" \"turns\": 3,\n",
|
|
" \"trace_events\": [\n",
|
|
" \"assistant_raw[1]={\\\"type\\\":\\\"tool_call\\\",\\\"name\\\":\\\"read_file\\\",\\\"arguments\\\":{\\\"path\\\":\\\"src/main.py\\\"}}\",\n",
|
|
" \"tool_call[1]=read_file {\\\"path\\\": \\\"src/main.py\\\"}\",\n",
|
|
" \"tool_result[1]=read_file success=True error=None\",\n",
|
|
" \"assistant_raw[2]={\\\"response\\\": \\\"The provided code snippet is from a Python script located at 'src/main.py'. It appears to be the main entry point for a command-line interface (CLI) application. The script defines several subcommands and their corresponding functionalities, such as building parsers, resolving chat prompts, and executing various commands like 'summary', 'manifest', 'parity-audit', etc. Each subcommand is handled within conditional statements in the `main` function. The script also includes functions for parsing logs, running experiments, and managing workers. Overall, this script serves as a control plane for managing and interacting with an autoresearch experiment environment.\\\"}\",\n",
|
|
" \"protocol_error[2]=Response type must be either \\\"tool_call\\\" or \\\"final\\\".\",\n",
|
|
" \"assistant_raw[3]={\\\"type\\\":\\\"final\\\",\\\"content\\\":\\\"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\\\"}\"\n",
|
|
" ]\n",
|
|
" },\n",
|
|
" \"last_error\": null\n",
|
|
"}\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"2"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"worker_resumed = run_json([\n",
|
|
" PYTHON,\n",
|
|
" \"-m\",\n",
|
|
" \"src.main\",\n",
|
|
" \"worker\",\n",
|
|
" \"resume\",\n",
|
|
" worker_id,\n",
|
|
" \"--trace\",\n",
|
|
"])\n",
|
|
"worker_resumed[\"run_count\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"$ /Users/wongdowling/opt/anaconda3/bin/python -m src.main worker close 07786cd4905d4275ab8666a113bf7e10\n",
|
|
"{\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"root\": \"/Users/wongdowling/Documents/autoresearch_harness/harness/claw-code\",\n",
|
|
" \"model\": \"qwen2.5-coder:7b\",\n",
|
|
" \"host\": \"http://localhost:11434\",\n",
|
|
" \"state\": \"closed\",\n",
|
|
" \"created_at\": \"2026-04-07T20:09:34Z\",\n",
|
|
" \"updated_at\": \"2026-04-07T20:10:59Z\",\n",
|
|
" \"run_count\": 2,\n",
|
|
" \"last_packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"last_result\": {\n",
|
|
" \"worker_id\": \"07786cd4905d4275ab8666a113bf7e10\",\n",
|
|
" \"state\": \"finished\",\n",
|
|
" \"packet\": {\n",
|
|
" \"objective\": \"Inspect the Python CLI and report the worker-related commands.\",\n",
|
|
" \"scope\": \"Inspect src/main.py and worker modules only when needed.\",\n",
|
|
" \"repo\": \"claw-code\",\n",
|
|
" \"branch_policy\": \"Do not create or switch branches.\",\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" \"python3 -m unittest tests/test_porting_workspace.py\"\n",
|
|
" ],\n",
|
|
" \"commit_policy\": \"Do not commit.\",\n",
|
|
" \"reporting_contract\": \"Report worker commands, changed files, verification results, and blockers.\",\n",
|
|
" \"escalation_policy\": \"Stop if Ollama is unavailable or a required tool fails repeatedly.\"\n",
|
|
" },\n",
|
|
" \"tool_calls\": [\n",
|
|
" \"read_file\"\n",
|
|
" ],\n",
|
|
" \"tool_trace\": [\n",
|
|
" {\n",
|
|
" \"turn\": 1,\n",
|
|
" \"name\": \"read_file\",\n",
|
|
" \"arguments\": {\n",
|
|
" \"path\": \"src/main.py\"\n",
|
|
" },\n",
|
|
" \"success\": true,\n",
|
|
" \"output\": \"1\\tfrom __future__ import annotations\\n2\\t\\n3\\timport argparse\\n4\\timport json\\n5\\timport sys\\n6\\tfrom pathlib import Path\\n7\\t\\n8\\tfrom .autoresearch_runner import parse_run_log, setup_autoresearch\\n9\\tfrom .autoresearch_worker import run_autoresearch_packet\\n10\\tfrom .bootstrap_graph import build_bootstrap_graph\\n11\\tfrom .command_graph import build_command_graph\\n12\\tfrom .commands import execute_command, get_command, get_commands, render_command_index\\n13\\tfrom .agent_loop import DEFAULT_AGENT_SYSTEM_PROMPT, run_agent_task\\n14\\tfrom .llm_backend import DEFAULT_OLLAMA_HOST, DEFAULT_OLLAMA_MODEL, LLMBackendError\\n15\\tfrom .direct_modes import run_deep_link, run_direct_connect\\n16\\tfrom .parity_audit import run_parity_audit\\n17\\tfrom .permissions import ToolPermissionContext\\n18\\tfrom .port_manifest import build_port_manifest\\n19\\tfrom .query_engine import QueryEnginePort\\n20\\tfrom .remote_runtime import run_remote_mode, run_ssh_mode, run_teleport_mode\\n21\\tfrom .runtime import PortRuntime\\n22\\tfrom .session_store import load_session\\n23\\tfrom .setup import run_setup\\n24\\tfrom .task import DEFAULT_SYSTEM_PROMPT, run_local_task\\n25\\tfrom .worker_api import close_worker, create_worker, list_workers, load_worker, resume_worker, run_worker\\n26\\tfrom .tool_pool import assemble_tool_pool\\n27\\tfrom .tools import execute_tool, get_tool, get_tools, render_tool_index\\n28\\t\\n29\\t\\n30\\tdef build_parser() -> argparse.ArgumentParser:\\n31\\t parser = argparse.ArgumentParser(description='Python porting workspace for the Claude Code rewrite effort')\\n32\\t subparsers = parser.add_subparsers(dest='command', required=True)\\n33\\t subparsers.add_parser('summary', help='render a Markdown summary of the Python porting workspace')\\n34\\t subparsers.add_parser('manifest', help='print the current Python workspace manifest')\\n35\\t subparsers.add_parser('parity-audit', help='compare the Python workspace against the local ignored TypeScript archive when available')\\n36\\t subparsers.add_parser('setup-report', help='render the startup/prefetch setup report')\\n37\\t subparsers.add_parser('command-graph', help='show command graph segmentation')\\n38\\t subparsers.add_parser('tool-pool', help='show assembled tool pool with default settings')\\n39\\t subparsers.add_parser('bootstrap-graph', help='show the mirrored bootstrap/runtime graph stages')\\n40\\t list_parser = subparsers.add_parser('subsystems', help='list the current Python modules in the workspace')\\n41\\t list_parser.add_argument('--limit', type=int, default=32)\\n42\\t\\n43\\t commands_parser = subparsers.add_parser('commands', help='list mirrored command entries from the archived snapshot')\\n44\\t commands_parser.add_argument('--limit', type=int, default=20)\\n45\\t commands_parser.add_argument('--query')\\n46\\t commands_parser.add_argument('--no-plugin-commands', action='store_true')\\n47\\t commands_parser.add_argument('--no-skill-commands', action='store_true')\\n48\\t\\n49\\t tools_parser = subparsers.add_parser('tools', help='list mirrored tool entries from the archived snapshot')\\n50\\t tools_parser.add_argument('--limit', type=int, default=20)\\n51\\t tools_parser.add_argument('--query')\\n52\\t tools_parser.add_argument('--simple-mode', action='store_true')\\n53\\t tools_parser.add_argument('--no-mcp', action='store_true')\\n54\\t tools_parser.add_argument('--deny-tool', action='append', default=[])\\n55\\t tools_parser.add_argument('--deny-prefix', action='append', default=[])\\n56\\t\\n57\\t route_parser = subparsers.add_parser('route', help='route a prompt across mirrored command/tool inventories')\\n58\\t route_parser.add_argument('prompt')\\n59\\t route_parser.add_argument('--limit', type=int, default=5)\\n60\\t\\n61\\t bootstrap_parser = subparsers.add_parser('bootstrap', help='build a runtime-style session report from the mirrored inventories')\\n62\\t bootstrap_parser.add_argument('prompt')\\n63\\t bootstrap_parser.add_argument('--limit', type=int, default=5)\\n64\\t\\n65\\t loop_parser = subparsers.add_parser('turn-loop', help='run a small stateful turn loop for the mirrored runtime')\\n66\\t loop_parser.add_argument('prompt')\\n67\\t loop_parser.add_argument('--limit', type=int, default=5)\\n68\\t loop_parser.add_argument('--max-turns', type=int, default=3)\\n69\\t loop_parser.add_argument('--structured-output', action='store_true')\\n70\\t\\n71\\t flush_parser = subparsers.add_parser('flush-transcript', help='persist and flush a temporary session transcript')\\n72\\t flush_parser.add_argument('prompt')\\n73\\t\\n74\\t load_session_parser = subparsers.add_parser('load-session', help='load a previously persisted session')\\n75\\t load_session_parser.add_argument('session_id')\\n76\\t\\n77\\t remote_parser = subparsers.add_parser('remote-mode', help='simulate remote-control runtime branching')\\n78\\t remote_parser.add_argument('target')\\n79\\t ssh_parser = subparsers.add_parser('ssh-mode', help='simulate SSH runtime branching')\\n80\\t ssh_parser.add_argument('target')\\n81\\t teleport_parser = subparsers.add_parser('teleport-mode', help='simulate teleport runtime branching')\\n82\\t teleport_parser.add_argument('target')\\n83\\t direct_parser = subparsers.add_parser('direct-connect-mode', help='simulate direct-connect runtime branching')\\n84\\t direct_parser.add_argument('target')\\n85\\t deep_link_parser = subparsers.add_parser('deep-link-mode', help='simulate deep-link runtime branching')\\n86\\t deep_link_parser.add_argument('target')\\n87\\t\\n88\\t show_command = subparsers.add_parser('show-command', help='show one mirrored command entry by exact name')\\n89\\t show_command.add_argument('name')\\n90\\t show_tool = subparsers.add_parser('show-tool', help='show one mirrored tool entry by exact name')\\n91\\t show_tool.add_argument('name')\\n92\\t\\n93\\t exec_command_parser = subparsers.add_parser('exec-command', help='execute a mirrored command shim by exact name')\\n94\\t exec_command_parser.add_argument('name')\\n95\\t exec_command_parser.add_argument('prompt')\\n96\\t\\n97\\t exec_tool_parser = subparsers.add_parser('exec-tool', help='execute a mirrored tool shim by exact name')\\n98\\t exec_tool_parser.add_argument('name')\\n99\\t exec_tool_parser.add_argument('payload')\\n100\\t\\n101\\t chat_parser = subparsers.add_parser('chat', help='send a prompt to a local Ollama model')\\n102\\t chat_parser.add_argument('prompt', nargs='?')\\n103\\t chat_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n104\\t chat_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n105\\t chat_parser.add_argument('--system')\\n106\\t\\n107\\t agent_parser = subparsers.add_parser('agent', help='run the local Ollama agent loop with executable workspace tools')\\n108\\t agent_parser.add_argument('prompt', nargs='?')\\n109\\t agent_parser.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n110\\t agent_parser.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n111\\t agent_parser.add_argument('--system')\\n112\\t agent_parser.add_argument('--max-turns', type=int, default=8)\\n113\\t agent_parser.add_argument('--deny-tool', action='append', default=[])\\n114\\t agent_parser.add_argument('--deny-prefix', action='append', default=[])\\n115\\t agent_parser.add_argument('--trace', action='store_true')\\n116\\t\\n117\\t worker_parser = subparsers.add_parser('worker', help='manage structured local Ollama workers')\\n118\\t worker_subparsers = worker_parser.add_subparsers(dest='worker_command', required=True)\\n119\\t\\n120\\t worker_create = worker_subparsers.add_parser('create', help='create a worker record')\\n121\\t worker_create.add_argument('--root', default='.')\\n122\\t worker_create.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n123\\t worker_create.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n124\\t\\n125\\t worker_subparsers.add_parser('list', help='list stored worker records')\\n126\\t\\n127\\t worker_run = worker_subparsers.add_parser('run', help='run a task packet on a worker')\\n128\\t worker_run.add_argument('worker_id')\\n129\\t worker_run.add_argument('--packet', required=True)\\n130\\t worker_run.add_argument('--trace', action='store_true')\\n131\\t\\n132\\t worker_status = worker_subparsers.add_parser('status', help='show worker state')\\n133\\t worker_status.add_argument('worker_id')\\n134\\t\\n135\\t worker_resume = worker_subparsers.add_parser('resume', help='rerun the last stored task packet')\\n136\\t worker_resume.add_argument('worker_id')\\n137\\t worker_resume.add_argument('--trace', action='store_true')\\n138\\t\\n139\\t worker_close = worker_subparsers.add_parser('close', help='close a worker record')\\n140\\t worker_close.add_argument('worker_id')\\n141\\t\\n142\\t autoresearch_parser = subparsers.add_parser('autoresearch', help='project-specific control plane for autoresearch experiments')\\n143\\t autoresearch_subparsers = autoresearch_parser.add_subparsers(dest='autoresearch_command', required=True)\\n144\\t\\n145\\t autoresearch_setup = autoresearch_subparsers.add_parser('setup', help='verify autoresearch repo state and initialize results.tsv')\\n146\\t autoresearch_setup.add_argument('--root')\\n147\\t autoresearch_setup.add_argument('--no-init-results', action='store_true')\\n148\\t\\n149\\t autoresearch_run = autoresearch_subparsers.add_parser('run', help='run one autoresearch experiment packet through the worker + experiment runner')\\n150\\t autoresearch_run.add_argument('--root')\\n151\\t autoresearch_run.add_argument('--packet', required=True)\\n152\\t autoresearch_run.add_argument('--model', default=DEFAULT_OLLAMA_MODEL)\\n153\\t autoresearch_run.add_argument('--host', default=DEFAULT_OLLAMA_HOST)\\n154\\t autoresearch_run.add_argument('--trace', action='store_true')\\n155\\t\\n156\\t autoresearch_parse_log = autoresearch_subparsers.add_parser('parse-log', help='parse a train.py run log into machine-readable metrics')\\n157\\t autoresearch_parse_log.add_argument('--root')\\n158\\t autoresearch_parse_log.add_argument('log_path')\\n159\\t return parser\\n160\\t\\n161\\t\\n162\\tdef resolve_chat_prompt(args: argparse.Namespace, parser: argparse.ArgumentParser) -> str:\\n163\\t if args.prompt:\\n164\\t return args.prompt\\n165\\t prompt = sys.stdin.read().strip()\\n166\\t if prompt:\\n167\\t return prompt\\n168\\t command_name = getattr(args, 'command', 'command')\\n169\\t parser.error(f'{command_name} requires a prompt argument or stdin input')\\n170\\t raise AssertionError('unreachable')\\n171\\t\\n172\\t\\n173\\tdef main(argv: list[str] | None = None) -> int:\\n174\\t parser = build_parser()\\n175\\t args = parser.parse_args(argv)\\n176\\t manifest = build_port_manifest()\\n177\\t if args.command == 'summary':\\n178\\t print(QueryEnginePort(manifest).render_summary())\\n179\\t return 0\\n180\\t if args.command == 'manifest':\\n181\\t print(manifest.to_markdown())\\n182\\t return 0\\n183\\t if args.command == 'parity-audit':\\n184\\t print(run_parity_audit().to_markdown())\\n185\\t return 0\\n186\\t if args.command == 'setup-report':\\n187\\t print(run_setup().as_markdown())\\n188\\t return 0\\n189\\t if args.command == 'command-graph':\\n190\\t print(build_command_graph().as_markdown())\\n191\\t return 0\\n192\\t if args.command == 'tool-pool':\\n193\\t print(assemble_tool_pool().as_markdown())\\n194\\t return 0\\n195\\t if args.command == 'bootstrap-graph':\\n196\\t print(build_bootstrap_graph().as_markdown())\\n197\\t return 0\\n198\\t if args.command == 'subsystems':\\n199\\t for subsystem in manifest.top_level_modules[: args.limit]:\\n200\\t print(f'{subsystem.name}\\\\t{subsystem.file_count}\\\\t{subsystem.notes}')\\n201\\t return 0\\n202\\t if args.command == 'commands':\\n203\\t if args.query:\\n204\\t print(render_command_index(limit=args.limit, query=args.query))\\n205\\t else:\\n206\\t commands = get_commands(include_plugin_commands=not args.no_plugin_commands, include_skill_commands=not args.no_skill_commands)\\n207\\t output_lines = [f'Command entries: {len(commands)}', '']\\n208\\t output_lines.extend(f'- {module.name} \\u2014 {module.source_hint}' for module in commands[: args.limit])\\n209\\t print('\\\\n'.join(output_lines))\\n210\\t return 0\\n...[truncated]\",\n",
|
|
" \"metadata\": {\n",
|
|
" \"path\": \"src/main.py\",\n",
|
|
" \"start_line\": 1,\n",
|
|
" \"end_line\": 386,\n",
|
|
" \"line_count\": 386\n",
|
|
" },\n",
|
|
" \"error\": null\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"artifacts\": [],\n",
|
|
" \"changed_files\": [],\n",
|
|
" \"verification\": {\n",
|
|
" \"acceptance_tests\": [\n",
|
|
" {\n",
|
|
" \"command\": \"python3 -m unittest tests/test_porting_workspace.py\",\n",
|
|
" \"success\": true,\n",
|
|
" \"exit_code\": 0,\n",
|
|
" \"output\": \".........................................\\n----------------------------------------------------------------------\\nRan 41 tests in 3.865s\\n\\nOK\"\n",
|
|
" }\n",
|
|
" ],\n",
|
|
" \"tool_runs\": {\n",
|
|
" \"run_tests\": [],\n",
|
|
" \"run_build\": []\n",
|
|
" }\n",
|
|
" },\n",
|
|
" \"final_answer\": \"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\",\n",
|
|
" \"stop_reason\": \"completed\",\n",
|
|
" \"turns\": 3,\n",
|
|
" \"trace_events\": [\n",
|
|
" \"assistant_raw[1]={\\\"type\\\":\\\"tool_call\\\",\\\"name\\\":\\\"read_file\\\",\\\"arguments\\\":{\\\"path\\\":\\\"src/main.py\\\"}}\",\n",
|
|
" \"tool_call[1]=read_file {\\\"path\\\": \\\"src/main.py\\\"}\",\n",
|
|
" \"tool_result[1]=read_file success=True error=None\",\n",
|
|
" \"assistant_raw[2]={\\\"response\\\": \\\"The provided code snippet is from a Python script located at 'src/main.py'. It appears to be the main entry point for a command-line interface (CLI) application. The script defines several subcommands and their corresponding functionalities, such as building parsers, resolving chat prompts, and executing various commands like 'summary', 'manifest', 'parity-audit', etc. Each subcommand is handled within conditional statements in the `main` function. The script also includes functions for parsing logs, running experiments, and managing workers. Overall, this script serves as a control plane for managing and interacting with an autoresearch experiment environment.\\\"}\",\n",
|
|
" \"protocol_error[2]=Response type must be either \\\"tool_call\\\" or \\\"final\\\".\",\n",
|
|
" \"assistant_raw[3]={\\\"type\\\":\\\"final\\\",\\\"content\\\":\\\"I found a Python script at 'src/main.py' that serves as the main entry point for a CLI application. It includes various subcommands and functionalities such as building parsers, resolving chat prompts, and executing commands like 'summary', 'manifest', 'parity-audit', etc.\\\"}\"\n",
|
|
" ]\n",
|
|
" },\n",
|
|
" \"last_error\": null\n",
|
|
"}\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'closed'"
|
|
]
|
|
},
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"worker_closed = run_json([\n",
|
|
" PYTHON,\n",
|
|
" \"-m\",\n",
|
|
" \"src.main\",\n",
|
|
" \"worker\",\n",
|
|
" \"close\",\n",
|
|
" worker_id,\n",
|
|
"])\n",
|
|
"worker_closed[\"state\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Smoke Test Success Criteria\n",
|
|
"\n",
|
|
"The smoke test is considered successful when:\n",
|
|
"\n",
|
|
"- the worker is created without manual `worker_id` handling\n",
|
|
"- `worker run` returns JSON\n",
|
|
"- `last_result.tool_calls` is non-empty\n",
|
|
"- `last_result.verification.acceptance_tests` is present\n",
|
|
"- `last_result.stop_reason` is `completed` or `verification_failed`\n",
|
|
"- `worker status`, `worker resume`, and `worker close` all succeed"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "base",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.9.20"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|