voidx 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. voidx-1.0.0/PKG-INFO +59 -0
  2. voidx-1.0.0/README.md +37 -0
  3. voidx-1.0.0/pyproject.toml +50 -0
  4. voidx-1.0.0/setup.cfg +4 -0
  5. voidx-1.0.0/src/voidx/__init__.py +3 -0
  6. voidx-1.0.0/src/voidx/agent/__init__.py +0 -0
  7. voidx-1.0.0/src/voidx/agent/agents.py +439 -0
  8. voidx-1.0.0/src/voidx/agent/attachments.py +235 -0
  9. voidx-1.0.0/src/voidx/agent/graph.py +463 -0
  10. voidx-1.0.0/src/voidx/agent/graph_components/__init__.py +1 -0
  11. voidx-1.0.0/src/voidx/agent/graph_components/compaction.py +268 -0
  12. voidx-1.0.0/src/voidx/agent/graph_components/permissions.py +139 -0
  13. voidx-1.0.0/src/voidx/agent/graph_components/run_loop.py +532 -0
  14. voidx-1.0.0/src/voidx/agent/graph_components/runtime.py +14 -0
  15. voidx-1.0.0/src/voidx/agent/graph_components/streaming.py +351 -0
  16. voidx-1.0.0/src/voidx/agent/graph_components/subagent.py +278 -0
  17. voidx-1.0.0/src/voidx/agent/graph_components/tool_execution.py +208 -0
  18. voidx-1.0.0/src/voidx/agent/runtime_context.py +368 -0
  19. voidx-1.0.0/src/voidx/agent/slash.py +466 -0
  20. voidx-1.0.0/src/voidx/agent/slash_components/__init__.py +1 -0
  21. voidx-1.0.0/src/voidx/agent/slash_components/code_ide.py +68 -0
  22. voidx-1.0.0/src/voidx/agent/slash_components/lsp.py +105 -0
  23. voidx-1.0.0/src/voidx/agent/slash_components/mcp.py +332 -0
  24. voidx-1.0.0/src/voidx/agent/slash_components/model.py +419 -0
  25. voidx-1.0.0/src/voidx/agent/slash_components/runtime.py +55 -0
  26. voidx-1.0.0/src/voidx/agent/slash_components/skills.py +94 -0
  27. voidx-1.0.0/src/voidx/agent/state.py +32 -0
  28. voidx-1.0.0/src/voidx/agent/task_state.py +278 -0
  29. voidx-1.0.0/src/voidx/agent/tool_filters.py +27 -0
  30. voidx-1.0.0/src/voidx/config.py +707 -0
  31. voidx-1.0.0/src/voidx/llm/__init__.py +0 -0
  32. voidx-1.0.0/src/voidx/llm/catalog.py +188 -0
  33. voidx-1.0.0/src/voidx/llm/compaction.py +267 -0
  34. voidx-1.0.0/src/voidx/llm/context.py +43 -0
  35. voidx-1.0.0/src/voidx/llm/instruction.py +220 -0
  36. voidx-1.0.0/src/voidx/llm/provider.py +312 -0
  37. voidx-1.0.0/src/voidx/llm/usage.py +341 -0
  38. voidx-1.0.0/src/voidx/lsp/__init__.py +30 -0
  39. voidx-1.0.0/src/voidx/lsp/client.py +259 -0
  40. voidx-1.0.0/src/voidx/lsp/config.py +172 -0
  41. voidx-1.0.0/src/voidx/lsp/detector.py +512 -0
  42. voidx-1.0.0/src/voidx/lsp/errors.py +19 -0
  43. voidx-1.0.0/src/voidx/lsp/manager.py +280 -0
  44. voidx-1.0.0/src/voidx/lsp/schema.py +179 -0
  45. voidx-1.0.0/src/voidx/lsp/service.py +103 -0
  46. voidx-1.0.0/src/voidx/main.py +154 -0
  47. voidx-1.0.0/src/voidx/mcp/__init__.py +33 -0
  48. voidx-1.0.0/src/voidx/mcp/client.py +458 -0
  49. voidx-1.0.0/src/voidx/mcp/manager.py +267 -0
  50. voidx-1.0.0/src/voidx/mcp/schema.py +112 -0
  51. voidx-1.0.0/src/voidx/mcp/tool.py +122 -0
  52. voidx-1.0.0/src/voidx/mcp_servers/__init__.py +1 -0
  53. voidx-1.0.0/src/voidx/mcp_servers/web.py +104 -0
  54. voidx-1.0.0/src/voidx/memory/__init__.py +0 -0
  55. voidx-1.0.0/src/voidx/memory/context_frames.py +188 -0
  56. voidx-1.0.0/src/voidx/memory/model_profiles.py +98 -0
  57. voidx-1.0.0/src/voidx/memory/runtime_state.py +240 -0
  58. voidx-1.0.0/src/voidx/memory/session.py +272 -0
  59. voidx-1.0.0/src/voidx/memory/store.py +245 -0
  60. voidx-1.0.0/src/voidx/memory/transcript.py +137 -0
  61. voidx-1.0.0/src/voidx/permission/__init__.py +28 -0
  62. voidx-1.0.0/src/voidx/permission/engine.py +430 -0
  63. voidx-1.0.0/src/voidx/permission/evaluate.py +114 -0
  64. voidx-1.0.0/src/voidx/permission/sandbox.py +280 -0
  65. voidx-1.0.0/src/voidx/permission/schema.py +24 -0
  66. voidx-1.0.0/src/voidx/permission/service.py +314 -0
  67. voidx-1.0.0/src/voidx/permission/wildcard.py +34 -0
  68. voidx-1.0.0/src/voidx/skills/__init__.py +18 -0
  69. voidx-1.0.0/src/voidx/skills/bundled/superpowers/receiving-code-review/SKILL.md +30 -0
  70. voidx-1.0.0/src/voidx/skills/bundled/superpowers/requesting-code-review/SKILL.md +27 -0
  71. voidx-1.0.0/src/voidx/skills/bundled/superpowers/systematic-debugging/SKILL.md +36 -0
  72. voidx-1.0.0/src/voidx/skills/bundled/superpowers/test-driven-development/SKILL.md +33 -0
  73. voidx-1.0.0/src/voidx/skills/bundled/superpowers/verification-before-completion/SKILL.md +31 -0
  74. voidx-1.0.0/src/voidx/skills/bundled/superpowers/writing-plans/SKILL.md +27 -0
  75. voidx-1.0.0/src/voidx/skills/policy.py +97 -0
  76. voidx-1.0.0/src/voidx/skills/registry.py +162 -0
  77. voidx-1.0.0/src/voidx/skills/schema.py +47 -0
  78. voidx-1.0.0/src/voidx/skills/service.py +199 -0
  79. voidx-1.0.0/src/voidx/tools/__init__.py +0 -0
  80. voidx-1.0.0/src/voidx/tools/agent.py +81 -0
  81. voidx-1.0.0/src/voidx/tools/base.py +86 -0
  82. voidx-1.0.0/src/voidx/tools/bash.py +105 -0
  83. voidx-1.0.0/src/voidx/tools/file_ops.py +193 -0
  84. voidx-1.0.0/src/voidx/tools/lsp.py +155 -0
  85. voidx-1.0.0/src/voidx/tools/registry.py +104 -0
  86. voidx-1.0.0/src/voidx/tools/repomap.py +238 -0
  87. voidx-1.0.0/src/voidx/tools/search.py +162 -0
  88. voidx-1.0.0/src/voidx/tools/task_status.py +57 -0
  89. voidx-1.0.0/src/voidx/tools/task_tracker.py +81 -0
  90. voidx-1.0.0/src/voidx/tools/todo.py +82 -0
  91. voidx-1.0.0/src/voidx/tools/web_content.py +357 -0
  92. voidx-1.0.0/src/voidx/tools/web_mcp.py +107 -0
  93. voidx-1.0.0/src/voidx/tools/webfetch.py +155 -0
  94. voidx-1.0.0/src/voidx/tools/websearch.py +276 -0
  95. voidx-1.0.0/src/voidx/ui/__init__.py +0 -0
  96. voidx-1.0.0/src/voidx/ui/app.py +1033 -0
  97. voidx-1.0.0/src/voidx/ui/app_components/__init__.py +1 -0
  98. voidx-1.0.0/src/voidx/ui/app_components/clipboard_image.py +245 -0
  99. voidx-1.0.0/src/voidx/ui/app_components/commands.py +18 -0
  100. voidx-1.0.0/src/voidx/ui/app_components/controls.py +29 -0
  101. voidx-1.0.0/src/voidx/ui/app_components/file_picker.py +115 -0
  102. voidx-1.0.0/src/voidx/ui/app_components/formatting.py +187 -0
  103. voidx-1.0.0/src/voidx/ui/app_components/git_changes.py +51 -0
  104. voidx-1.0.0/src/voidx/ui/app_components/rendering.py +1169 -0
  105. voidx-1.0.0/src/voidx/ui/browse.py +160 -0
  106. voidx-1.0.0/src/voidx/ui/capture.py +169 -0
  107. voidx-1.0.0/src/voidx/ui/code_ide.py +251 -0
  108. voidx-1.0.0/src/voidx/ui/commands.py +83 -0
  109. voidx-1.0.0/src/voidx/ui/console.py +381 -0
  110. voidx-1.0.0/src/voidx/ui/console_components/__init__.py +1 -0
  111. voidx-1.0.0/src/voidx/ui/console_components/formatting.py +96 -0
  112. voidx-1.0.0/src/voidx/ui/console_components/streaming.py +253 -0
  113. voidx-1.0.0/src/voidx/ui/diff.py +331 -0
  114. voidx-1.0.0/src/voidx/ui/dock.py +372 -0
  115. voidx-1.0.0/src/voidx/ui/dock_components/__init__.py +1 -0
  116. voidx-1.0.0/src/voidx/ui/dock_components/formatting.py +123 -0
  117. voidx-1.0.0/src/voidx/ui/dock_components/nodes.py +401 -0
  118. voidx-1.0.0/src/voidx/ui/dock_components/state.py +51 -0
  119. voidx-1.0.0/src/voidx/ui/event_components/__init__.py +1 -0
  120. voidx-1.0.0/src/voidx/ui/event_components/schema.py +249 -0
  121. voidx-1.0.0/src/voidx/ui/events.py +341 -0
  122. voidx-1.0.0/src/voidx/ui/session_changes.py +163 -0
  123. voidx-1.0.0/src/voidx/ui/startup.py +161 -0
  124. voidx-1.0.0/src/voidx/ui/transcript.py +148 -0
  125. voidx-1.0.0/src/voidx/ui/tree.py +316 -0
  126. voidx-1.0.0/src/voidx.egg-info/PKG-INFO +59 -0
  127. voidx-1.0.0/src/voidx.egg-info/SOURCES.txt +145 -0
  128. voidx-1.0.0/src/voidx.egg-info/dependency_links.txt +1 -0
  129. voidx-1.0.0/src/voidx.egg-info/entry_points.txt +2 -0
  130. voidx-1.0.0/src/voidx.egg-info/requires.txt +16 -0
  131. voidx-1.0.0/src/voidx.egg-info/top_level.txt +1 -0
  132. voidx-1.0.0/tests/test_clipboard_image.py +100 -0
  133. voidx-1.0.0/tests/test_code_ide.py +75 -0
  134. voidx-1.0.0/tests/test_config.py +264 -0
  135. voidx-1.0.0/tests/test_llm_provider.py +225 -0
  136. voidx-1.0.0/tests/test_llm_usage.py +184 -0
  137. voidx-1.0.0/tests/test_lsp.py +287 -0
  138. voidx-1.0.0/tests/test_main.py +91 -0
  139. voidx-1.0.0/tests/test_mcp.py +270 -0
  140. voidx-1.0.0/tests/test_npm_package.py +101 -0
  141. voidx-1.0.0/tests/test_prompt_tui.py +1614 -0
  142. voidx-1.0.0/tests/test_skills.py +255 -0
  143. voidx-1.0.0/tests/test_startup.py +57 -0
  144. voidx-1.0.0/tests/test_tree_smoke.py +169 -0
  145. voidx-1.0.0/tests/test_ui_diff.py +68 -0
  146. voidx-1.0.0/tests/test_ui_events.py +482 -0
  147. voidx-1.0.0/tests/test_ui_session_changes.py +31 -0
voidx-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: voidx
3
+ Version: 1.0.0
4
+ Summary: A coding agent that quantifies everything and solves with tools, not fuzzy prompts.
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: langgraph>=0.3.0
8
+ Requires-Dist: langchain>=0.3.0
9
+ Requires-Dist: langchain-anthropic>=0.3.0
10
+ Requires-Dist: langchain-openai>=0.3.0
11
+ Requires-Dist: pydantic>=2.10.0
12
+ Requires-Dist: pydantic-settings>=2.7.0
13
+ Requires-Dist: typer>=0.15.0
14
+ Requires-Dist: rich>=13.9.0
15
+ Requires-Dist: prompt_toolkit>=3.0.0
16
+ Requires-Dist: tiktoken>=0.8.0
17
+ Requires-Dist: httpx>=0.28.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: build>=1.2.0; extra == "dev"
20
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
21
+ Requires-Dist: pytest-asyncio>=0.25.0; extra == "dev"
22
+
23
+ # voidx
24
+
25
+ voidx is a terminal AI coding agent built in Python.
26
+
27
+ ## Install
28
+
29
+ Python users can install the canonical package from PyPI:
30
+
31
+ ```bash
32
+ pip install voidx
33
+ voidx
34
+ ```
35
+
36
+ Node users can install the npm launcher. The launcher requires Python 3.11+
37
+ on the machine and installs the matching Python package into an isolated
38
+ user-local virtual environment on first run:
39
+
40
+ ```bash
41
+ npm install -g @voidx/cli
42
+ voidx
43
+ ```
44
+
45
+ ## Useful Commands
46
+
47
+ ```bash
48
+ voidx version
49
+ voidx sessions
50
+ voidx -w /path/to/project
51
+ ```
52
+
53
+ ## Development
54
+
55
+ ```bash
56
+ .venv/bin/python -m pytest
57
+ .venv/bin/python scripts/package.py --format all --clean
58
+ npm --prefix npm run check
59
+ ```
voidx-1.0.0/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # voidx
2
+
3
+ voidx is a terminal AI coding agent built in Python.
4
+
5
+ ## Install
6
+
7
+ Python users can install the canonical package from PyPI:
8
+
9
+ ```bash
10
+ pip install voidx
11
+ voidx
12
+ ```
13
+
14
+ Node users can install the npm launcher. The launcher requires Python 3.11+
15
+ on the machine and installs the matching Python package into an isolated
16
+ user-local virtual environment on first run:
17
+
18
+ ```bash
19
+ npm install -g @voidx/cli
20
+ voidx
21
+ ```
22
+
23
+ ## Useful Commands
24
+
25
+ ```bash
26
+ voidx version
27
+ voidx sessions
28
+ voidx -w /path/to/project
29
+ ```
30
+
31
+ ## Development
32
+
33
+ ```bash
34
+ .venv/bin/python -m pytest
35
+ .venv/bin/python scripts/package.py --format all --clean
36
+ npm --prefix npm run check
37
+ ```
@@ -0,0 +1,50 @@
1
+ [project]
2
+ name = "voidx"
3
+ version = "1.0.0"
4
+ description = "A coding agent that quantifies everything and solves with tools, not fuzzy prompts."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = [
8
+ "langgraph>=0.3.0",
9
+ "langchain>=0.3.0",
10
+ "langchain-anthropic>=0.3.0",
11
+ "langchain-openai>=0.3.0",
12
+ "pydantic>=2.10.0",
13
+ "pydantic-settings>=2.7.0",
14
+ "typer>=0.15.0",
15
+ "rich>=13.9.0",
16
+ "prompt_toolkit>=3.0.0",
17
+ "tiktoken>=0.8.0",
18
+ "httpx>=0.28.0",
19
+ ]
20
+
21
+ [project.scripts]
22
+ voidx = "voidx.main:cli"
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "build>=1.2.0",
27
+ "pytest>=8.0.0",
28
+ "pytest-asyncio>=0.25.0",
29
+ ]
30
+
31
+ [dependency-groups]
32
+ dev = [
33
+ "build>=1.2.0",
34
+ "pytest>=8.0.0",
35
+ "pytest-asyncio>=0.25.0",
36
+ ]
37
+
38
+ [build-system]
39
+ requires = ["setuptools>=68", "wheel"]
40
+ build-backend = "setuptools.build_meta"
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+
45
+ [tool.setuptools.package-data]
46
+ "voidx.skills" = ["bundled/superpowers/*/SKILL.md"]
47
+
48
+ [tool.pytest.ini_options]
49
+ asyncio_mode = "auto"
50
+ testpaths = ["tests"]
voidx-1.0.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """VoidX - A coding agent that quantifies everything."""
2
+
3
+ __version__ = "1.0.0"
File without changes
@@ -0,0 +1,439 @@
1
+ """Agent definitions — typed config, whenToUse descriptions, prompts.
2
+
3
+ 5 agents:
4
+ orchestrator — primary, coordinates, can make small direct edits
5
+ explore — read-only codebase search
6
+ plan — read-only architecture design
7
+ implement — delegated coding agent for broad or isolated changes
8
+ review — read-only code review, produces PASS/FAIL verdicts
9
+
10
+ Inspired by opencode's agent system + Claude Code's whenToUse routing.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from pydantic import BaseModel, Field
16
+
17
+
18
+ # ── prompts ───────────────────────────────────────────────────────────────
19
+
20
+ BASE_SYSTEM_PROMPT = """You are voidx, a coding agent that lives in the terminal.
21
+
22
+ ## Communication Style
23
+
24
+ - **Natural and warm.** Write like a skilled colleague, not a robot.
25
+ Use contractions, vary sentence length, show personality.
26
+ - **Match the user's language.** If the user writes in Chinese, respond in Chinese.
27
+ If they write in English, respond in English. Mirror their tone.
28
+ - **Be concise.** One good sentence beats three mediocre ones. The user can ask
29
+ follow-ups if they want more detail.
30
+ - **Don't explain your internals.** The user doesn't need to know about agents,
31
+ roles, explore/plan/implement/review, or your architecture. Just help them.
32
+ If asked "who are you", say "I'm voidx, a coding assistant" — one sentence max.
33
+ - **Say what you're about to do.** Brief heads-up before searching or editing:
34
+ "Let me check the auth module." — not "I will now delegate to the explore agent."
35
+ - **Summarize results, not process.** After completing work, tell the user what
36
+ changed and where. Don't narrate which agents you used or how many steps it took.
37
+ - **Acknowledge uncertainty.** If you're not sure, say so. "I think it's auth.py:42,
38
+ but let me verify" — not "I have medium confidence in this assessment."
39
+ - **Show progress via todo.** Update the todo list so progress is visible.
40
+ But don't narrate todo updates in your text.
41
+
42
+ ## Global Rules
43
+
44
+ - Use tools for facts about the workspace; do not guess file contents.
45
+ - Read before editing. Make minimal, precise changes.
46
+ - Keep user-facing responses concise and focused on outcomes.
47
+ - Do not expose internal role names unless the user asks about architecture.
48
+ - Never claim work is complete until it has been verified.
49
+
50
+ ## Workflow Skills
51
+
52
+ - voidx may activate workflow skills such as systematic-debugging,
53
+ test-driven-development, verification-before-completion,
54
+ receiving-code-review, requesting-code-review, and writing-plans.
55
+ - The Current Task State lists active workflow skills for this turn.
56
+ - The Active Skills section contains the full instructions for active skills.
57
+ - Follow active workflow skills before acting.
58
+
59
+ ## Parallel Execution
60
+
61
+ - Multiple tool calls in one model response run in parallel.
62
+ - Tool calls across separate model responses run sequentially.
63
+ - Batch independent reads/searches together; keep dependent work sequential.
64
+ """
65
+
66
+
67
+ ORCHESTRATOR_PROMPT = """You are voidx orchestrator, the primary coordination role.
68
+
69
+ ## Role
70
+
71
+ Understand the user's intent, decide whether tools or child agents are needed,
72
+ and keep the conversation aligned with the user's goal. You may make small,
73
+ surgical edits directly when that is the shortest safe path.
74
+
75
+ ## Decision Flow
76
+
77
+ 0. **Intent gate** — before delegating or changing files, classify the latest
78
+ user request:
79
+ - Answer/explain → answer directly. No tools unless context is required.
80
+ - Inspect/understand current state → use read/glob/grep/repo_map directly.
81
+ Do not call implement. Do not start plan→implement→review.
82
+ - Discuss/design/propose → produce options or a plan. Do not implement unless
83
+ the user explicitly approves.
84
+ - Fix/implement/modify → edit directly for small scoped changes, or delegate
85
+ broad/isolated work to implement.
86
+ - Ambiguous → continue with read-only investigation when useful. Ask one
87
+ clarifying question before edits, unsafe bash, or implement delegation.
88
+
89
+ Words like "看看", "分析", "梳理", "有什么建议", "如何设计", "优化方案",
90
+ "look at", "analyze", "suggest", and "proposal" do NOT imply permission
91
+ to edit. Treat them as inspect/design requests unless the user explicitly
92
+ says to modify code.
93
+
94
+ 1. **Chat / explain** — just answer. No tools unless you need to look something up.
95
+
96
+ 2. **Simple search** — grab read/glob/grep and find it yourself. Only send explore
97
+ for broad searches across many files.
98
+
99
+ 3. **Design / plan** — hand off to plan for architecture questions.
100
+
101
+ 4. **Code changes**
102
+ - Small, local, or mechanical changes → read first, then call write/edit
103
+ yourself and verify.
104
+ - If investigation finds a concrete edit but the user asked only to inspect,
105
+ design, or review, stop and report the proposed change. Ask for
106
+ confirmation before editing.
107
+ - Broad, risky, or isolated implementation work → use todo and delegate a
108
+ complete brief to implement. Review non-trivial delegated work before
109
+ reporting completion.
110
+ - If review says FAIL or NEEDS_CHANGE → fix, review again.
111
+
112
+ 5. **Unclear intent** — ask. One specific clarifying question is better than five
113
+ assumptions. "When you say 'broken', do you mean it crashes, returns wrong data,
114
+ or something else?"
115
+
116
+ ## Rules
117
+
118
+ - Do not delegate to implement unless the user explicitly asks to modify code.
119
+ - In plan mode, do not call write/edit/lsp_format, unsafe bash, or implement.
120
+ - Ambiguous implementation intent is not enough for write/edit/lsp_format,
121
+ unsafe bash, or implement delegation.
122
+ - Don't tell the user "done" until changes are verified.
123
+ - Child agents have isolated context — give them complete, self-contained briefs.
124
+
125
+ ## Parallel Execution
126
+ - Multiple tool calls in ONE response → they run in parallel.
127
+ - Tool calls across SEPARATE responses → they run sequentially.
128
+ - Batch independent work: read 3 files at once, search + fetch in the same step.
129
+ - Sequential work: search first, then read based on what you found.
130
+ """
131
+
132
+ # Plan mode prompt — injected when plan_mode=True
133
+ PLAN_MODE_APPEND = """
134
+ ## PLAN MODE ACTIVE
135
+ You are in plan mode. Write/edit tools are BLOCKED at the permission level.
136
+ - You CAN: read, glob, grep, bash (read-only), agent(plan/explore/review)
137
+ - You CANNOT: write, edit, agent(implement), bash (destructive)
138
+ - Focus on analysis, design, and creating structured plans.
139
+ - When ready to implement, tell the user to exit plan mode.
140
+ """
141
+
142
+ EXPLORE_PROMPT = """You are voidx explore, a fast read-only codebase explorer.
143
+
144
+ ## Role
145
+ Search, find, and understand code. Use only the tools listed in the Tool Contract.
146
+ Report what you find with file paths, line numbers, and relevant code.
147
+ Be thorough but efficient.
148
+
149
+ ## Rules
150
+ - Do NOT suggest edits or fixes — just report findings.
151
+ - Include specific file paths and line numbers.
152
+ - If the user specifies "quick", be brief. If "very thorough", be exhaustive.
153
+ """
154
+
155
+
156
+ PLAN_PROMPT = """You are voidx plan, a software architect.
157
+
158
+ ## Role
159
+ Design implementation approaches. Study the existing codebase with the tools
160
+ listed in the Tool Contract. Output structured, implementable plans.
161
+
162
+ ## Output Format
163
+
164
+ ```
165
+ ## Context
166
+ (what's being changed and why)
167
+
168
+ ## Approach
169
+ (high-level strategy, architecture decisions)
170
+
171
+ ## Steps
172
+ 1. (concrete step with file paths)
173
+ 2. ...
174
+
175
+ ## Affected Files
176
+ - path/to/file.py (new/modified/deleted)
177
+
178
+ ## Risks
179
+ - (potential issues, trade-offs)
180
+ ```
181
+
182
+ ## Rules
183
+ - Study existing patterns before proposing changes.
184
+ - Each step must be concrete enough for implement to execute.
185
+ - Consider edge cases, error handling, and existing tests.
186
+ """
187
+
188
+ IMPLEMENT_PROMPT = """You are voidx implement, the coding agent.
189
+
190
+ ## Role
191
+ Execute coding tasks using the tools listed in the Tool Contract.
192
+ You are the dedicated executor for broad or isolated implementation tasks.
193
+
194
+ ## Rules
195
+ - Read before writing. Never guess file contents.
196
+ - Make minimal, precise edits. Use edit with exact old_string matches.
197
+ - Follow the plan if one was provided.
198
+ - Run tests/bash after changes to verify.
199
+ - Return: what files were changed, what was done, any issues encountered.
200
+ - Do NOT start other child agents (you are the executor, not the coordinator).
201
+
202
+ ## Parallel Execution
203
+ - Tools in the same response run IN PARALLEL via asyncio.gather.
204
+ - Tools across separate responses run SEQUENTIALLY.
205
+ - Read multiple files before editing → batch reads in one response.
206
+ - Edit + verify test → two responses (edit first, then bash test).
207
+ """
208
+
209
+ REVIEW_PROMPT = """You are voidx review, a code reviewer.
210
+
211
+ ## Role
212
+ Review code changes for correctness, style, security, and completeness.
213
+ Use only the tools listed in the Tool Contract.
214
+ You do NOT write or edit code.
215
+
216
+ ## Output Format
217
+
218
+ ```
219
+ verdict: PASS | FAIL | NEEDS_CHANGE
220
+
221
+ ## Issues
222
+ - [severity: critical/high/medium/low]
223
+ file: path/to/file.py
224
+ line: 42
225
+ problem: (what's wrong)
226
+ suggestion: (how to fix)
227
+ ```
228
+
229
+ ## Checklist
230
+ - **Correctness**: Does the code do what was intended? Any logic bugs?
231
+ - **Completeness**: Edge cases handled? Error handling present?
232
+ - **Style**: Follows existing patterns and conventions?
233
+ - **Security**: Injection risks? Unsafe file operations? Hardcoded secrets?
234
+ - **Side effects**: What else might this change affect?
235
+
236
+ ## Rules
237
+ - Be specific: include file paths, line numbers, concrete suggestions.
238
+ - PASS means the code is ready to ship — no issues found.
239
+ - NEEDS_CHANGE for minor issues that don't block functionality.
240
+ - FAIL for bugs, security issues, or broken functionality.
241
+ """
242
+
243
+
244
+ # ── agent definitions ─────────────────────────────────────────────────────
245
+
246
+ class AgentDef(BaseModel):
247
+ """An agent's complete definition — typed, no loose config."""
248
+ name: str
249
+ description: str
250
+ when_to_use: str
251
+ tools: list[str] # tool IDs this agent can use
252
+ can_write: bool
253
+ can_delegate: bool # can it start child agents via the agent tool?
254
+ max_steps: int = 25
255
+ hidden: bool = False # hidden from user-facing lists?
256
+ model: str | None = None # None = inherit from parent
257
+
258
+ @property
259
+ def role_prompt(self) -> str:
260
+ prompts = {
261
+ "orchestrator": ORCHESTRATOR_PROMPT,
262
+ "explore": EXPLORE_PROMPT,
263
+ "plan": PLAN_PROMPT,
264
+ "implement": IMPLEMENT_PROMPT,
265
+ "review": REVIEW_PROMPT,
266
+ }
267
+ return prompts.get(self.name, "")
268
+
269
+ @property
270
+ def tool_contract(self) -> str:
271
+ lines = [
272
+ f"- Role: {self.name}",
273
+ f"- Can write files: {str(self.can_write).lower()}",
274
+ f"- Can start child agents: {str(self.can_delegate).lower()}",
275
+ f"- Max steps: {self.max_steps}",
276
+ ]
277
+ if self.tools:
278
+ lines.append(f"- Available tools: {', '.join(self.tools)}")
279
+ else:
280
+ lines.append("- Available tools: none")
281
+ if not self.can_write:
282
+ lines.append("- Constraint: this role must not write or edit files.")
283
+ if not self.can_delegate:
284
+ lines.append("- Constraint: this role must not start another child agent.")
285
+ return "\n".join(lines)
286
+
287
+ @property
288
+ def prompt(self) -> str:
289
+ return self.role_prompt
290
+
291
+
292
+ # ── built-in agents ────────────────────────────────────────────────────────
293
+
294
+ BUILTIN_AGENTS: dict[str, AgentDef] = {
295
+ "orchestrator": AgentDef(
296
+ name="orchestrator",
297
+ description="Coordinator agent. Understands intent, edits small scoped changes directly, "
298
+ "delegates broad work to specialists, reviews results.",
299
+ when_to_use="Default agent for all user interactions. Always use first.",
300
+ tools=[
301
+ "read", "glob", "grep", "bash", "agent", "task_status", "todo",
302
+ "webfetch", "websearch", "repo_map",
303
+ "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
304
+ "write", "edit", "lsp_format",
305
+ ],
306
+ can_write=True,
307
+ can_delegate=True,
308
+ max_steps=20,
309
+ hidden=False,
310
+ ),
311
+ "explore": AgentDef(
312
+ name="explore",
313
+ description="Fast read-only agent for exploring codebases. Finds files by pattern, "
314
+ "searches for symbols, understands how things work.",
315
+ when_to_use="Use when you need to find files, search code, understand structure, "
316
+ "or answer 'how does X work' questions. Specify thoroughness: "
317
+ "'quick' for basic, 'medium' for moderate, 'very thorough' for exhaustive.",
318
+ tools=[
319
+ "read", "glob", "grep", "webfetch", "websearch", "repo_map",
320
+ "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
321
+ ],
322
+ can_write=False,
323
+ can_delegate=False,
324
+ max_steps=10,
325
+ hidden=False,
326
+
327
+ ),
328
+ "plan": AgentDef(
329
+ name="plan",
330
+ description="Software architect for designing implementation plans. Analyzes codebase, "
331
+ "proposes approaches, identifies risks.",
332
+ when_to_use="Use for design/architecture questions, before complex implementations, "
333
+ "or when the user asks for a plan/approach/solution design.",
334
+ tools=[
335
+ "read", "glob", "grep", "webfetch", "websearch", "repo_map",
336
+ "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
337
+ ],
338
+ can_write=False,
339
+ can_delegate=False,
340
+ max_steps=15,
341
+ hidden=False,
342
+ ),
343
+ "implement": AgentDef(
344
+ name="implement",
345
+ description="Delegated coding agent. Writes and edits files, runs bash commands.",
346
+ when_to_use="Use for all code writing, file editing, refactoring, bug fixing, "
347
+ "and bash execution. Give complete, self-contained task descriptions.",
348
+ tools=[
349
+ "read", "write", "edit", "glob", "grep", "bash", "todo", "repo_map",
350
+ "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
351
+ "lsp_format",
352
+ ],
353
+ can_write=True,
354
+ can_delegate=False,
355
+ max_steps=25,
356
+ hidden=False,
357
+ ),
358
+ "review": AgentDef(
359
+ name="review",
360
+ description="Code reviewer. Checks implementations for correctness, style, security. "
361
+ "Returns PASS/FAIL/NEEDS_CHANGE verdicts with specific issues.",
362
+ when_to_use="ALWAYS invoke after implement finishes non-trivial work. "
363
+ "Use to verify correctness before reporting completion to the user.",
364
+ tools=[
365
+ "read", "glob", "grep", "bash", "webfetch", "websearch", "repo_map",
366
+ "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
367
+ ],
368
+ can_write=False,
369
+ can_delegate=False,
370
+ max_steps=10,
371
+ hidden=False,
372
+ ),
373
+ # ── hidden agents (not user-visible, internal only) ───────────────
374
+ "compaction": AgentDef(
375
+ name="compaction",
376
+ description="Internal agent for generating context summaries when compaction is needed.",
377
+ when_to_use="INTERNAL ONLY. Invoked automatically when context overflow is detected.",
378
+ tools=[], # no tools — just generates summaries
379
+ can_write=False,
380
+ can_delegate=False,
381
+ max_steps=3,
382
+ hidden=True,
383
+ ),
384
+ "title": AgentDef(
385
+ name="title",
386
+ description="Internal agent for generating session titles from first user message.",
387
+ when_to_use="INTERNAL ONLY. Invoked automatically after first user message.",
388
+ tools=[],
389
+ can_write=False,
390
+ can_delegate=False,
391
+ max_steps=2,
392
+ hidden=True,
393
+ ),
394
+ }
395
+
396
+ COMPACTION_PROMPT = """You are voidx compaction agent. Your job is to generate a
397
+ structured summary of the conversation history to free context space.
398
+
399
+ You have NO tools. Just read the conversation history below and output the
400
+ summary in the exact format specified.
401
+
402
+ """ + "Use template defined in CompactionService."
403
+
404
+ TITLE_PROMPT = """You are voidx title agent. Generate a short, descriptive
405
+ title (max 80 chars) for this conversation based on the first user message.
406
+ Output ONLY the title text, nothing else. No quotes, no formatting."""
407
+
408
+
409
+ def get_agent(name: str) -> AgentDef | None:
410
+ return BUILTIN_AGENTS.get(name)
411
+
412
+
413
+ def get_visible_agents() -> list[AgentDef]:
414
+ return [a for a in BUILTIN_AGENTS.values() if not a.hidden]
415
+
416
+
417
+ def get_subagents() -> list[AgentDef]:
418
+ """Worker roles the orchestrator can run (all non-primary, non-hidden)."""
419
+ return [
420
+ a for a in BUILTIN_AGENTS.values()
421
+ if a.name != "orchestrator" and not a.hidden
422
+ ]
423
+
424
+
425
+ def child_agent_descriptions_for_llm() -> str:
426
+ """Generate child-agent descriptions for the agent tool."""
427
+ lines = ["Available child agents and the tools they have access to:"]
428
+ for agent in get_subagents():
429
+ tools_str = ", ".join(agent.tools)
430
+ lines.append(
431
+ f"- {agent.name}: {agent.description}\n"
432
+ f" Tools: {tools_str}\n"
433
+ f" Write access: {agent.can_write}"
434
+ )
435
+ return "\n".join(lines)
436
+
437
+
438
+ def subagent_descriptions_for_llm() -> str:
439
+ return child_agent_descriptions_for_llm()