voidx 2.2.0__tar.gz → 2.3.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 (303) hide show
  1. {voidx-2.2.0 → voidx-2.3.0}/PKG-INFO +1 -1
  2. {voidx-2.2.0 → voidx-2.3.0}/pyproject.toml +2 -1
  3. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/__init__.py +1 -1
  4. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/agents.py +30 -15
  5. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/attachments.py +23 -3
  6. voidx-2.3.0/src/voidx/agent/graph/compaction.py +81 -0
  7. voidx-2.3.0/src/voidx/agent/graph/compaction_coordinator.py +478 -0
  8. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/contracts.py +135 -67
  9. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/core.py +213 -81
  10. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/permissions.py +46 -7
  11. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/run_loop.py +99 -48
  12. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/runtime.py +0 -2
  13. voidx-2.3.0/src/voidx/agent/graph/session_mixin.py +38 -0
  14. voidx-2.3.0/src/voidx/agent/graph/session_runtime.py +327 -0
  15. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/streaming.py +71 -16
  16. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/subagent.py +30 -68
  17. voidx-2.3.0/src/voidx/agent/graph/title_mixin.py +100 -0
  18. voidx-2.3.0/src/voidx/agent/graph/todo_events.py +17 -0
  19. voidx-2.3.0/src/voidx/agent/graph/tool_execution.py +41 -0
  20. voidx-2.3.0/src/voidx/agent/graph/tool_executor.py +640 -0
  21. voidx-2.3.0/src/voidx/agent/graph/transcript_mixin.py +18 -0
  22. voidx-2.3.0/src/voidx/agent/graph/turn_mixin.py +40 -0
  23. voidx-2.2.0/src/voidx/agent/graph/turn_mixin.py → voidx-2.3.0/src/voidx/agent/graph/turn_runner.py +125 -108
  24. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/intent_refinement.py +89 -33
  25. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/runtime_context.py +100 -12
  26. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/code_ide.py +4 -4
  27. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/guide.py +3 -4
  28. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/handler.py +46 -163
  29. voidx-2.3.0/src/voidx/agent/slash/host.py +365 -0
  30. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/init.py +4 -4
  31. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/lsp.py +6 -6
  32. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/mcp.py +22 -21
  33. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/model.py +79 -76
  34. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/profile.py +9 -8
  35. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/runtime.py +0 -2
  36. voidx-2.3.0/src/voidx/agent/slash/session.py +139 -0
  37. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/skills.py +35 -11
  38. voidx-2.3.0/src/voidx/agent/slash/upgrade.py +98 -0
  39. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/state.py +4 -3
  40. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/task_state.py +4 -0
  41. voidx-2.3.0/src/voidx/agent/todo_state.py +196 -0
  42. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings.py +2 -0
  43. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_skills.py +26 -1
  44. voidx-2.3.0/src/voidx/config/settings_update.py +72 -0
  45. voidx-2.3.0/src/voidx/data/templates/api-doc.md +64 -0
  46. voidx-2.3.0/src/voidx/data/templates/prd.md +117 -0
  47. voidx-2.3.0/src/voidx/data/templates/readme.md +55 -0
  48. voidx-2.3.0/src/voidx/data/templates/rfc.md +38 -0
  49. voidx-2.3.0/src/voidx/data/templates/tech-design.md +68 -0
  50. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/compaction.py +17 -0
  51. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/instruction.py +43 -41
  52. voidx-2.3.0/src/voidx/llm/provider.py +542 -0
  53. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/__init__.py +9 -1
  54. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/client.py +9 -2
  55. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/manager.py +70 -22
  56. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/runtime_state.py +37 -12
  57. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/store.py +4 -2
  58. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/rules.py +4 -1
  59. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/runtime/__init__.py +4 -0
  60. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/runtime/task_state.py +20 -8
  61. voidx-2.3.0/src/voidx/runtime/ui_port.py +178 -0
  62. voidx-2.3.0/src/voidx/selfupdate.py +207 -0
  63. voidx-2.3.0/src/voidx/skills/__init__.py +23 -0
  64. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/skills/context.py +4 -5
  65. voidx-2.3.0/src/voidx/skills/policy.py +43 -0
  66. voidx-2.3.0/src/voidx/skills/references.py +73 -0
  67. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/skills/registry.py +2 -1
  68. voidx-2.3.0/src/voidx/skills/runtime.py +25 -0
  69. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/skills/schema.py +3 -0
  70. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/skills/service.py +20 -115
  71. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/__init__.py +8 -1
  72. voidx-2.3.0/src/voidx/tools/advance_workflow.py +206 -0
  73. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/agent.py +5 -5
  74. voidx-2.2.0/src/voidx/tools/file_ops.py → voidx-2.3.0/src/voidx/tools/apply_patch.py +6 -201
  75. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/base.py +4 -1
  76. voidx-2.3.0/src/voidx/tools/file_ops.py +184 -0
  77. voidx-2.3.0/src/voidx/tools/file_state.py +28 -0
  78. voidx-2.3.0/src/voidx/tools/load_doc_template.py +62 -0
  79. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/load_skills.py +10 -9
  80. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/on_intent.py +7 -7
  81. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/registry.py +5 -2
  82. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/commands.py +6 -0
  83. voidx-2.3.0/src/voidx/ui/output/events/__init__.py +102 -0
  84. voidx-2.3.0/src/voidx/ui/output/events/bus.py +119 -0
  85. voidx-2.2.0/src/voidx/ui/output/events/__init__.py → voidx-2.3.0/src/voidx/ui/output/events/consumers.py +14 -121
  86. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/__init__.py +5 -0
  87. voidx-2.3.0/src/voidx/ui/tools/skill_picker.py +79 -0
  88. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/app.py +12 -0
  89. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/input.py +7 -0
  90. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/overlays.py +43 -1
  91. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/panels.py +126 -3
  92. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/parser.py +4 -0
  93. voidx-2.3.0/src/voidx/ui/tui/render_activity.py +77 -0
  94. voidx-2.3.0/src/voidx/ui/tui/render_frame.py +456 -0
  95. voidx-2.3.0/src/voidx/ui/tui/render_input.py +154 -0
  96. voidx-2.3.0/src/voidx/ui/tui/render_status.py +226 -0
  97. voidx-2.3.0/src/voidx/ui/tui/render_todo.py +81 -0
  98. voidx-2.3.0/src/voidx/ui/tui/renderer.py +24 -0
  99. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/state.py +14 -0
  100. voidx-2.3.0/src/voidx/workflow/__init__.py +68 -0
  101. voidx-2.3.0/src/voidx/workflow/auto_advance.py +162 -0
  102. voidx-2.3.0/src/voidx/workflow/context.py +66 -0
  103. voidx-2.3.0/src/voidx/workflow/dag.py +34 -0
  104. voidx-2.3.0/src/voidx/workflow/nodes.py +322 -0
  105. voidx-2.3.0/src/voidx/workflow/policy.py +147 -0
  106. voidx-2.3.0/src/voidx/workflow/render.py +100 -0
  107. voidx-2.3.0/src/voidx/workflow/runtime.py +278 -0
  108. voidx-2.3.0/src/voidx/workflow/schema.py +159 -0
  109. voidx-2.3.0/src/voidx/workflow/service.py +197 -0
  110. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/PKG-INFO +1 -1
  111. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/SOURCES.txt +46 -9
  112. voidx-2.3.0/tests/test_auto_advance.py +410 -0
  113. {voidx-2.2.0 → voidx-2.3.0}/tests/test_compaction.py +168 -29
  114. {voidx-2.2.0 → voidx-2.3.0}/tests/test_config.py +44 -3
  115. {voidx-2.2.0 → voidx-2.3.0}/tests/test_instruction_cache.py +1 -1
  116. voidx-2.3.0/tests/test_llm_provider.py +632 -0
  117. {voidx-2.2.0 → voidx-2.3.0}/tests/test_lsp.py +143 -2
  118. {voidx-2.2.0 → voidx-2.3.0}/tests/test_npm_package.py +7 -0
  119. voidx-2.3.0/tests/test_selfupdate.py +103 -0
  120. {voidx-2.2.0 → voidx-2.3.0}/tests/test_skills.py +350 -260
  121. voidx-2.3.0/tests/test_tui_frame_rendering.py +472 -0
  122. voidx-2.3.0/tests/test_tui_input_handling.py +865 -0
  123. voidx-2.3.0/tests/test_tui_output_tree.py +301 -0
  124. voidx-2.3.0/tests/test_tui_paste_handling.py +280 -0
  125. voidx-2.3.0/tests/test_tui_status_activity.py +723 -0
  126. voidx-2.3.0/tests/test_tui_terminal_panels.py +710 -0
  127. {voidx-2.2.0 → voidx-2.3.0}/tests/test_ui_events.py +23 -2
  128. voidx-2.2.0/src/voidx/agent/graph/compaction.py +0 -323
  129. voidx-2.2.0/src/voidx/agent/graph/session_mixin.py +0 -60
  130. voidx-2.2.0/src/voidx/agent/graph/title_mixin.py +0 -211
  131. voidx-2.2.0/src/voidx/agent/graph/todo_events.py +0 -21
  132. voidx-2.2.0/src/voidx/agent/graph/tool_execution.py +0 -475
  133. voidx-2.2.0/src/voidx/agent/graph/transcript_mixin.py +0 -34
  134. voidx-2.2.0/src/voidx/agent/slash/session.py +0 -239
  135. voidx-2.2.0/src/voidx/llm/provider.py +0 -320
  136. voidx-2.2.0/src/voidx/skills/__init__.py +0 -34
  137. voidx-2.2.0/src/voidx/skills/bundled/brainstorming/SKILL.md +0 -51
  138. voidx-2.2.0/src/voidx/skills/bundled/receiving-code-review/SKILL.md +0 -60
  139. voidx-2.2.0/src/voidx/skills/bundled/requesting-code-review/SKILL.md +0 -59
  140. voidx-2.2.0/src/voidx/skills/bundled/systematic-debugging/SKILL.md +0 -64
  141. voidx-2.2.0/src/voidx/skills/bundled/test-driven-development/SKILL.md +0 -61
  142. voidx-2.2.0/src/voidx/skills/bundled/verification-before-completion/SKILL.md +0 -69
  143. voidx-2.2.0/src/voidx/skills/bundled/writing-design-docs/SKILL.md +0 -87
  144. voidx-2.2.0/src/voidx/skills/bundled/writing-plans/SKILL.md +0 -54
  145. voidx-2.2.0/src/voidx/skills/policy.py +0 -121
  146. voidx-2.2.0/src/voidx/skills/runtime.py +0 -252
  147. voidx-2.2.0/src/voidx/ui/tui/renderer.py +0 -905
  148. voidx-2.2.0/tests/test_llm_provider.py +0 -225
  149. voidx-2.2.0/tests/test_pure_tui.py +0 -3204
  150. {voidx-2.2.0 → voidx-2.3.0}/README.md +0 -0
  151. {voidx-2.2.0 → voidx-2.3.0}/setup.cfg +0 -0
  152. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/__init__.py +0 -0
  153. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/__init__.py +0 -0
  154. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/convergence.py +0 -0
  155. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/topology.py +0 -0
  156. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/graph/wiring.py +0 -0
  157. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/message_rows.py +0 -0
  158. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/slash/__init__.py +0 -0
  159. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/tool_filters.py +0 -0
  160. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/agent/tool_messages.py +0 -0
  161. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/__init__.py +0 -0
  162. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/cli.py +0 -0
  163. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/enums.py +0 -0
  164. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/models.py +0 -0
  165. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/permissions.py +0 -0
  166. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_agent.py +0 -0
  167. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_api_keys.py +0 -0
  168. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_code_ide.py +0 -0
  169. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_custom.py +0 -0
  170. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_mcp.py +0 -0
  171. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_permissions.py +0 -0
  172. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_utils.py +0 -0
  173. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/config/settings_web.py +0 -0
  174. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/data/__init__.py +0 -0
  175. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/data/intent_classifier.json +0 -0
  176. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/diffing.py +0 -0
  177. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/__init__.py +0 -0
  178. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/catalog.py +0 -0
  179. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/context.py +0 -0
  180. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/message_markers.py +0 -0
  181. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/llm/usage.py +0 -0
  182. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/config.py +0 -0
  183. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/detector.py +0 -0
  184. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/detector_data.py +0 -0
  185. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/errors.py +0 -0
  186. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/schema.py +0 -0
  187. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/lsp/service.py +0 -0
  188. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/main.py +0 -0
  189. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/__init__.py +0 -0
  190. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/__init__.py +0 -0
  191. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/base.py +0 -0
  192. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/errors.py +0 -0
  193. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/http_transport.py +0 -0
  194. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/sse_transport.py +0 -0
  195. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/client/stdio_transport.py +0 -0
  196. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/manager.py +0 -0
  197. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/schema.py +0 -0
  198. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp/tool.py +0 -0
  199. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp_servers/__init__.py +0 -0
  200. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/mcp_servers/web.py +0 -0
  201. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/__init__.py +0 -0
  202. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/context_frames.py +0 -0
  203. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/model_profiles.py +0 -0
  204. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/session.py +0 -0
  205. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/memory/transcript.py +0 -0
  206. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/__init__.py +0 -0
  207. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/context.py +0 -0
  208. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/engine.py +0 -0
  209. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/evaluate.py +0 -0
  210. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/sandbox.py +0 -0
  211. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/schema.py +0 -0
  212. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/service.py +0 -0
  213. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/permission/wildcard.py +0 -0
  214. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/runtime/intent.py +0 -0
  215. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/runtime/intent_classifier.py +0 -0
  216. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/runtime/ui.py +0 -0
  217. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/bash.py +0 -0
  218. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/clarify.py +0 -0
  219. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/git.py +0 -0
  220. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/lsp.py +0 -0
  221. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/plan_checkpoint.py +0 -0
  222. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/repomap.py +0 -0
  223. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/search.py +0 -0
  224. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/task_status.py +0 -0
  225. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/task_tracker.py +0 -0
  226. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/todo.py +0 -0
  227. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/web_content.py +0 -0
  228. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/web_mcp.py +0 -0
  229. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/webfetch.py +0 -0
  230. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/tools/websearch.py +0 -0
  231. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/__init__.py +0 -0
  232. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/frontend.py +0 -0
  233. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/gateway/__init__.py +0 -0
  234. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/gateway/bootstrap.py +0 -0
  235. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/gateway/server.py +0 -0
  236. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/gateway/session.py +0 -0
  237. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/__init__.py +0 -0
  238. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/agent_display.py +0 -0
  239. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/browse.py +0 -0
  240. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/capture.py +0 -0
  241. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/console/__init__.py +0 -0
  242. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/console/app.py +0 -0
  243. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/console/formatting.py +0 -0
  244. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/console/streaming.py +0 -0
  245. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/diff.py +0 -0
  246. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/__init__.py +0 -0
  247. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/agent_placeholder.py +0 -0
  248. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/app.py +0 -0
  249. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/formatting.py +0 -0
  250. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/nodes.py +0 -0
  251. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/nodes_permission.py +0 -0
  252. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/nodes_startup.py +0 -0
  253. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/nodes_status.py +0 -0
  254. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/state.py +0 -0
  255. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/status.py +0 -0
  256. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/stream.py +0 -0
  257. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/dock/todo.py +0 -0
  258. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/events/schema.py +0 -0
  259. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/tree.py +0 -0
  260. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/output/types.py +0 -0
  261. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/__init__.py +0 -0
  262. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/commands.py +0 -0
  263. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/envelope.py +0 -0
  264. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/requests.py +0 -0
  265. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/schema.py +0 -0
  266. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/protocol/transcript.py +0 -0
  267. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/session.py +0 -0
  268. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/attachment_tokens.py +0 -0
  269. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/clipboard_image.py +0 -0
  270. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/clipboard_text.py +0 -0
  271. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/code_ide.py +0 -0
  272. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tools/file_picker.py +0 -0
  273. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/transcript.py +0 -0
  274. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/__init__.py +0 -0
  275. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/activity.py +0 -0
  276. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/choice_mixin.py +0 -0
  277. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/clipboard_mixin.py +0 -0
  278. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/helpers.py +0 -0
  279. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/terminal_mixin.py +0 -0
  280. {voidx-2.2.0 → voidx-2.3.0}/src/voidx/ui/tui/text_prompt_mixin.py +0 -0
  281. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/dependency_links.txt +0 -0
  282. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/entry_points.txt +0 -0
  283. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/requires.txt +0 -0
  284. {voidx-2.2.0 → voidx-2.3.0}/src/voidx.egg-info/top_level.txt +0 -0
  285. {voidx-2.2.0 → voidx-2.3.0}/tests/test_clipboard_image.py +0 -0
  286. {voidx-2.2.0 → voidx-2.3.0}/tests/test_clipboard_text.py +0 -0
  287. {voidx-2.2.0 → voidx-2.3.0}/tests/test_code_ide.py +0 -0
  288. {voidx-2.2.0 → voidx-2.3.0}/tests/test_intent_classifier_phase_a.py +0 -0
  289. {voidx-2.2.0 → voidx-2.3.0}/tests/test_llm_catalog.py +0 -0
  290. {voidx-2.2.0 → voidx-2.3.0}/tests/test_llm_usage.py +0 -0
  291. {voidx-2.2.0 → voidx-2.3.0}/tests/test_main.py +0 -0
  292. {voidx-2.2.0 → voidx-2.3.0}/tests/test_main_startup.py +0 -0
  293. {voidx-2.2.0 → voidx-2.3.0}/tests/test_mcp.py +0 -0
  294. {voidx-2.2.0 → voidx-2.3.0}/tests/test_output_browse.py +0 -0
  295. {voidx-2.2.0 → voidx-2.3.0}/tests/test_runtime_intent_classifier.py +0 -0
  296. {voidx-2.2.0 → voidx-2.3.0}/tests/test_runtime_ui.py +0 -0
  297. {voidx-2.2.0 → voidx-2.3.0}/tests/test_scrollback_flush.py +0 -0
  298. {voidx-2.2.0 → voidx-2.3.0}/tests/test_startup.py +0 -0
  299. {voidx-2.2.0 → voidx-2.3.0}/tests/test_tree_smoke.py +0 -0
  300. {voidx-2.2.0 → voidx-2.3.0}/tests/test_ui_diff.py +0 -0
  301. {voidx-2.2.0 → voidx-2.3.0}/tests/test_ui_frontend_protocol.py +0 -0
  302. {voidx-2.2.0 → voidx-2.3.0}/tests/test_ui_gateway.py +0 -0
  303. {voidx-2.2.0 → voidx-2.3.0}/tests/test_ui_session_changes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidx
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: A coding agent that quantifies everything and solves with tools, not fuzzy prompts.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "voidx"
3
- version = "2.2.0"
3
+ version = "2.3.0"
4
4
  description = "A coding agent that quantifies everything and solves with tools, not fuzzy prompts."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -48,6 +48,7 @@ where = ["src"]
48
48
  ]
49
49
  "voidx.data" = [
50
50
  "intent_classifier.json",
51
+ "templates/*.md",
51
52
  ]
52
53
 
53
54
  [tool.pytest.ini_options]
@@ -1,3 +1,3 @@
1
1
  """VoidX - A coding agent that quantifies everything."""
2
2
 
3
- __version__ = "2.2.0"
3
+ __version__ = "2.3.0"
@@ -46,15 +46,20 @@ BASE_SYSTEM_PROMPT = """You are voidx, a coding agent that lives in the terminal
46
46
  - Keep user-facing responses concise and focused on outcomes.
47
47
  - Do not expose internal role names unless the user asks about architecture.
48
48
  - Never claim work is complete until it has been verified.
49
+ - When Current Task State lists an active workflow gate, that workflow gate takes precedence
50
+ over role prompts, delegation rules, and the decision flow below.
49
51
 
50
52
 
51
- ## Workflow Skills
53
+ ## Workflow Runtime
52
54
 
53
- - voidx has a workflow skill system.
54
- - Current Task State is the activation source for this turn's workflow skills.
55
- - Skill Context messages contain bundled workflow skill bodies as a reference
56
- library. Follow only skills listed as active in Current Task State, unless the
57
- user explicitly references another skill.
55
+ - voidx has a structured workflow runtime.
56
+ - Current Task State is the activation source for this turn's workflow nodes.
57
+ - Workflow Context messages contain structured workflow node definitions as a
58
+ reference library. Active node definitions are expanded; inactive nodes may
59
+ appear only as summaries. Follow ONLY nodes listed as active in Current Task
60
+ State, unless the user explicitly references another node by name.
61
+ - When a node is not listed as active, its summary is reference only. Do not
62
+ follow its gate, workflow, or transition instructions.
58
63
  - load_skills can return project/global skill bodies for the current turn.
59
64
  """
60
65
 
@@ -76,8 +81,9 @@ surgical edits directly when that is the shortest safe path.
76
81
  Do not call implement. Do not start plan→implement→review.
77
82
  - Discuss/design/propose → produce options or a plan. Do not implement unless
78
83
  the user explicitly approves.
79
- - Fix/implement/modify → edit directly for small scoped changes, or delegate
80
- broad/isolated work to implement.
84
+ - Fix/implement/modify → unless blocked by an active workflow gate, edit
85
+ directly for small scoped changes, or delegate broad/isolated work to
86
+ implement.
81
87
  - Ambiguous → continue with read-only investigation when useful. Use clarify
82
88
  for one structured question before edits, unsafe bash, or implement delegation.
83
89
 
@@ -98,14 +104,14 @@ surgical edits directly when that is the shortest safe path.
98
104
  running write-capable commands, or delegating implement.
99
105
 
100
106
  4. **Code changes**
101
- - Small, local, or mechanical changesread first, then call write/edit/apply_patch
102
- yourself and verify.
107
+ - Small documentation or single-file editsunless blocked by an active
108
+ workflow gate, read first, then call write/edit yourself and verify.
103
109
  - If investigation finds a concrete edit but the user asked only to inspect,
104
110
  design, or review, stop and report the proposed change. Ask for
105
111
  confirmation before editing.
106
- - Broad, risky, or isolated implementation work → use todo and delegate a
107
- complete brief to implement. Review non-trivial delegated work before
108
- reporting completion.
112
+ - Broad, risky, source/test/config, or multi-file patch work → unless blocked
113
+ by an active workflow gate, use todo and delegate a complete brief to
114
+ implement. Review non-trivial delegated work before reporting completion.
109
115
  - If review says FAIL or NEEDS_CHANGE → fix, review again.
110
116
 
111
117
  5. **Unclear intent** — ask through clarify. One specific clarifying question is
@@ -118,10 +124,15 @@ surgical edits directly when that is the shortest safe path.
118
124
  - In plan mode, do not call write/edit/lsp_format, unsafe bash, or implement.
119
125
  - Ambiguous implementation intent is not enough for write/edit/lsp_format,
120
126
  unsafe bash, or implement delegation.
127
+ - apply_patch is implement-only. As orchestrator, use write/edit for direct
128
+ edits and delegate multi-file patch work to implement.
121
129
  - Child agents do not interact with the user. If a child plan result needs user
122
130
  approval or clarification, call plan_checkpoint or clarify yourself.
123
131
  - Don't tell the user "done" until changes are verified.
124
132
  - Child agents have isolated context — give them complete, self-contained briefs.
133
+ - If Current Task State lists an active workflow gate, that workflow gate takes precedence over
134
+ this decision flow. Do not delegate to implement or take implementation action while a gate
135
+ blocks implementation workflows.
125
136
  """
126
137
 
127
138
  # Plan mode prompt — injected when plan_mode=True
@@ -233,6 +244,9 @@ verdict: PASS | FAIL | NEEDS_CHANGE
233
244
  - PASS means the code is ready to ship — no issues found.
234
245
  - NEEDS_CHANGE for minor issues that don't block functionality.
235
246
  - FAIL for bugs, security issues, or broken functionality.
247
+ - Workflow impact: PASS leaves review workflow completion to the orchestrator.
248
+ FAIL or NEEDS_CHANGE means the orchestrator should advance review with
249
+ `review_has_issues` into review-feedback.
236
250
  """
237
251
 
238
252
 
@@ -338,11 +352,12 @@ BUILTIN_AGENTS: dict[str, AgentDef] = {
338
352
  "delegates broad work to specialists, reviews results.",
339
353
  when_to_use="Default agent for all user interactions. Always use first.",
340
354
  tools=[
341
- "on_intent", "clarify", "plan_checkpoint",
355
+ "on_intent", "clarify", "plan_checkpoint", "advance_workflow",
342
356
  "read", "glob", "grep", "bash", "agent", "task_status", "todo", "load_skills",
357
+ "load_doc_template",
343
358
  "webfetch", "websearch", "repo_map",
344
359
  "lsp_diagnostics", "lsp_symbols", "lsp_definition", "lsp_references",
345
- "write", "edit", "apply_patch", "lsp_format",
360
+ "write", "edit", "lsp_format",
346
361
  ],
347
362
  can_write=True,
348
363
  can_delegate=True,
@@ -56,7 +56,13 @@ def serialize_message_content(content: str | list[dict[str, Any]]) -> tuple[str,
56
56
  return content, "text"
57
57
 
58
58
 
59
- def build_user_message_payload(user_text: str, workspace: str) -> UserMessagePayload:
59
+ def build_user_message_payload(
60
+ user_text: str,
61
+ workspace: str,
62
+ *,
63
+ text_prefix: str = "",
64
+ extra_removed_spans: list[tuple[int, int]] | None = None,
65
+ ) -> UserMessagePayload:
60
66
  workspace_path = Path(workspace).resolve()
61
67
  tokens = _attachment_tokens(user_text)
62
68
  removed_spans: list[tuple[int, int]] = []
@@ -112,8 +118,13 @@ def build_user_message_payload(user_text: str, workspace: str) -> UserMessagePay
112
118
  if section:
113
119
  text_sections.append(section)
114
120
 
121
+ display_clean_text = _normalize_text(_remove_spans(user_text, removed_spans))
122
+ if extra_removed_spans:
123
+ removed_spans.extend(extra_removed_spans)
115
124
  clean_text = _normalize_text(_remove_spans(user_text, removed_spans))
116
125
  text_content = _build_text_content(clean_text, attachments, text_sections)
126
+ if text_prefix.strip():
127
+ text_content = _prefix_text_content(text_prefix.strip(), text_content)
117
128
  content: str | list[dict[str, Any]]
118
129
  content_format = "text"
119
130
  if image_parts:
@@ -122,7 +133,7 @@ def build_user_message_payload(user_text: str, workspace: str) -> UserMessagePay
122
133
  else:
123
134
  content = text_content
124
135
 
125
- display_text = _display_text(clean_text, attachments)
136
+ display_text = _display_text(display_clean_text, attachments)
126
137
  title_text = clean_text or (f"Attached {attachments[0].rel_path}" if attachments else user_text)
127
138
  return UserMessagePayload(
128
139
  raw_text=user_text,
@@ -158,7 +169,9 @@ def _remove_spans(text: str, spans: list[tuple[int, int]]) -> str:
158
169
  return text
159
170
  result: list[str] = []
160
171
  last = 0
161
- for start, end in spans:
172
+ for start, end in sorted(spans):
173
+ if start < last:
174
+ continue
162
175
  result.append(text[last:start])
163
176
  result.append(" ")
164
177
  last = end
@@ -166,6 +179,13 @@ def _remove_spans(text: str, spans: list[tuple[int, int]]) -> str:
166
179
  return "".join(result)
167
180
 
168
181
 
182
+ def _prefix_text_content(prefix: str, text: str) -> str:
183
+ text = text.strip()
184
+ if not text:
185
+ return prefix
186
+ return f"{prefix}\n\n{text}"
187
+
188
+
169
189
  def _resolve_workspace_path(workspace: Path, raw_path: str) -> Path | None:
170
190
  candidate = Path(raw_path).expanduser()
171
191
  resolved = candidate.resolve() if candidate.is_absolute() else (workspace / candidate).resolve()
@@ -0,0 +1,81 @@
1
+ """Context compaction method proxies for the agent graph."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from voidx.agent.graph.compaction_coordinator import CompactionResult, GraphCompactionCoordinator
8
+
9
+ if TYPE_CHECKING:
10
+ from voidx.agent.graph.contracts import GraphCompactionHost
11
+
12
+
13
+ def _compaction_component_for(host: GraphCompactionHost) -> GraphCompactionCoordinator:
14
+ coordinator = getattr(host, "_compaction_coordinator", None)
15
+ if coordinator is None:
16
+ # Bare mixin tests can instantiate a host without VoidXGraph.__init__.
17
+ coordinator = GraphCompactionCoordinator(host)
18
+ host._compaction_coordinator = coordinator
19
+ return coordinator
20
+
21
+
22
+ class GraphCompactionMixin:
23
+ def _compaction_component(self: GraphCompactionHost) -> GraphCompactionCoordinator:
24
+ return _compaction_component_for(self)
25
+
26
+ async def _maybe_compact(
27
+ self: GraphCompactionHost,
28
+ messages: list,
29
+ session_msgs: list | None = None,
30
+ *,
31
+ force: bool = False,
32
+ ask: bool = True,
33
+ ) -> tuple[list | None, str | None]:
34
+ return await _compaction_component_for(self).maybe_compact(
35
+ messages,
36
+ session_msgs,
37
+ force=force,
38
+ ask=ask,
39
+ run_compaction_agent=self._run_compaction_agent,
40
+ persist_compaction=self._persist_compaction,
41
+ )
42
+
43
+ async def _in_turn_compact(
44
+ self: GraphCompactionHost,
45
+ messages: list,
46
+ ) -> CompactionResult | None:
47
+ count = getattr(self, "_in_turn_compaction_count", 0) + 1
48
+ self._in_turn_compaction_count = count
49
+ if count > 2:
50
+ return None
51
+ return await _compaction_component_for(self).compact_for_live_state(
52
+ messages,
53
+ force=True,
54
+ ask=False,
55
+ include_summary_message=True,
56
+ run_compaction_agent=self._run_compaction_agent,
57
+ persist_compaction=self._persist_compaction,
58
+ )
59
+
60
+ async def _ask_compact(self: GraphCompactionHost, total_tokens: int) -> bool:
61
+ return await _compaction_component_for(self).ask_compact(total_tokens)
62
+
63
+ async def _persist_compaction(self: GraphCompactionHost, head_messages: list) -> None:
64
+ await _compaction_component_for(self).persist_compaction(head_messages)
65
+
66
+ async def _compact_session_history(self: GraphCompactionHost, *, force: bool = True) -> bool:
67
+ return await _compaction_component_for(self).compact_session_history(
68
+ force=force,
69
+ run_compaction_agent=self._run_compaction_agent,
70
+ persist_compaction=self._persist_compaction,
71
+ )
72
+
73
+ async def _run_compaction_agent(
74
+ self: GraphCompactionHost,
75
+ head_messages: list,
76
+ previous_summary: str | None,
77
+ ) -> str | None:
78
+ return await _compaction_component_for(self).run_compaction_agent(
79
+ head_messages,
80
+ previous_summary,
81
+ )