voidx 3.6.0__tar.gz → 3.7.1__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 (623) hide show
  1. {voidx-3.6.0/src/voidx.egg-info → voidx-3.7.1}/PKG-INFO +20 -2
  2. {voidx-3.6.0 → voidx-3.7.1}/README.md +19 -1
  3. voidx-3.7.1/src/tests/test_agent/graph/conftest.py +1 -0
  4. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/stream_llm_helpers.py +20 -0
  5. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_call_llm_compaction.py +173 -8
  6. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_call_llm_compaction_advanced.py +13 -8
  7. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_call_llm_tools.py +117 -2
  8. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_compaction_flow_run_once.py +4 -4
  9. voidx-3.7.1/src/tests/test_agent/graph/test_execute_tools_guard.py +1807 -0
  10. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_execute_tools_todo.py +1 -1
  11. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_graph_setup_prompts.py +4 -3
  12. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_guards_tool_op.py +4 -0
  13. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_parallel_subagents_dedup.py +1 -1
  14. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_prepare_workflow.py +3 -1
  15. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_run_loop_startup.py +67 -6
  16. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_run_loop_title_misc.py +26 -22
  17. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_run_loop_workflow.py +5 -5
  18. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_run_loop_workflow_advanced.py +12 -16
  19. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_runtime_guards.py +30 -0
  20. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_llm_retry.py +8 -3
  21. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_tool_execution_auth.py +13 -10
  22. voidx-3.7.1/src/tests/test_agent/graph/test_turn_control_e2e.py +250 -0
  23. voidx-3.7.1/src/tests/test_agent/graph/test_turn_control_integration.py +643 -0
  24. voidx-3.7.1/src/tests/test_agent/graph/test_turn_runner_guidance_discard.py +138 -0
  25. voidx-3.7.1/src/tests/test_agent/graph/test_turn_runner_idle_event.py +11 -0
  26. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_workflow_transactions.py +1 -1
  27. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_workflow_transactions_barrier.py +2 -2
  28. voidx-3.7.1/src/tests/test_agent/loop/test_manager.py +126 -0
  29. voidx-3.7.1/src/tests/test_agent/loop/test_prompt_source.py +71 -0
  30. voidx-3.7.1/src/tests/test_agent/slash/test_slash_loop.py +82 -0
  31. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_model.py +3 -6
  32. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_session.py +16 -0
  33. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_skills.py +14 -0
  34. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_file_rwlock.py +258 -16
  35. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_goal_resolver.py +124 -8
  36. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_goal_resolver_advanced.py +19 -24
  37. voidx-3.7.1/src/tests/test_agent/test_guard_guidance.py +70 -0
  38. voidx-3.7.1/src/tests/test_agent/test_guide_command.py +110 -0
  39. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_message_trimming_rules.py +3 -3
  40. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_permission.py +65 -14
  41. voidx-3.7.1/src/tests/test_agent/test_permission_phase2.py +454 -0
  42. voidx-3.7.1/src/tests/test_agent/test_permission_phase3.py +399 -0
  43. voidx-3.7.1/src/tests/test_agent/test_permission_phase4.py +298 -0
  44. voidx-3.7.1/src/tests/test_agent/test_permission_phase5.py +114 -0
  45. voidx-3.7.1/src/tests/test_agent/test_permission_phase6.py +306 -0
  46. voidx-3.7.1/src/tests/test_agent/test_prompts.py +130 -0
  47. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_runtime_context_builder.py +42 -2
  48. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_task_state_rendering.py +5 -3
  49. voidx-3.7.1/src/tests/test_agent/test_turn_control.py +250 -0
  50. voidx-3.7.1/src/tests/test_agent/test_turn_control_prompt.py +57 -0
  51. voidx-3.7.1/src/tests/test_agent/test_turn_metrics.py +74 -0
  52. voidx-3.7.1/src/tests/test_agent/test_turn_start.py +159 -0
  53. voidx-3.7.1/src/tests/test_archive_script.py +386 -0
  54. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_config/test_config_advanced.py +89 -2
  55. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_install_sh.py +116 -5
  56. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_fallback_summary.py +66 -0
  57. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_gemini_provider.py +19 -0
  58. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_instruction_cache.py +30 -5
  59. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_llm_catalog.py +4 -13
  60. voidx-3.7.1/src/tests/test_llm/test_llm_catalog_fetchers.py +255 -0
  61. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_llm_provider.py +122 -2
  62. voidx-3.7.1/src/tests/test_logging/test_external.py +41 -0
  63. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_lsp/test_lsp.py +156 -3
  64. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_mcp/test_mcp.py +125 -0
  65. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_memory/test_main.py +0 -14
  66. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_npm_package.py +259 -12
  67. voidx-3.7.1/src/tests/test_runtime/test_processes.py +362 -0
  68. voidx-3.7.1/src/tests/test_selfupdate/test_selfupdate.py +575 -0
  69. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/test_workflow_advance.py +20 -2
  70. voidx-3.7.1/src/tests/test_test_runner.py +677 -0
  71. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/bash/test_router_git.py +3 -3
  72. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/bash/test_tool.py +35 -3
  73. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_bounds_input.py +4 -4
  74. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_coverage.py +17 -0
  75. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_dedup.py +293 -0
  76. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_errors.py +1 -1
  77. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_llm_messages.py +9 -9
  78. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_read.py +24 -16
  79. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_read_write.py +5 -5
  80. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_write_file.py +133 -12
  81. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_clarify_tool.py +0 -1
  82. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_diffing.py +46 -0
  83. voidx-3.7.1/src/tests/test_tools/test_file_tools_redesign.py +801 -0
  84. voidx-3.7.1/src/tests/test_tools/test_git_tool_phase5.py +455 -0
  85. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_git_tool_raw_permissions.py +2 -1
  86. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_git_tool_schema_errors.py +26 -1
  87. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_git_tool_structured.py +38 -0
  88. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_infer_state_patch.py +18 -6
  89. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_interactive_tools.py +33 -6
  90. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_interactive_tools_write.py +6 -6
  91. voidx-3.7.1/src/tests/test_tools/test_loop_integration.py +34 -0
  92. voidx-3.7.1/src/tests/test_tools/test_loop_registry.py +42 -0
  93. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_plan_checkpoint.py +23 -23
  94. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_powershell_tool.py +4 -0
  95. voidx-3.7.1/src/tests/test_tools/test_powershell_tool_phase6.py +53 -0
  96. voidx-3.7.1/src/tests/test_tools/test_resolve_safe.py +18 -0
  97. voidx-3.7.1/src/tests/test_tools/test_schedule_wakeup.py +70 -0
  98. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_search.py +4 -8
  99. voidx-3.7.1/src/tests/test_tools/test_shell_tool_phase6.py +111 -0
  100. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_task_tracker.py +26 -0
  101. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_tool_error_handling.py +25 -4
  102. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_tool_registry.py +4 -3
  103. voidx-3.7.1/src/tests/test_tools/test_tool_schemas.py +276 -0
  104. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_web_mcp.py +85 -0
  105. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_webfetch.py +46 -0
  106. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_workflow_tool.py +176 -29
  107. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_adapter.py +44 -1
  108. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_v2_routing.py +29 -0
  109. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_v2_server.py +6 -10
  110. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_dock_prompts.py +78 -21
  111. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_dock_status.py +58 -0
  112. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_streaming.py +45 -0
  113. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_gateway.py +29 -18
  114. voidx-3.7.1/src/tests/test_ui/output/test_console_app.py +15 -0
  115. voidx-3.7.1/src/tests/test_ui/output/test_fmt_args.py +95 -0
  116. voidx-3.7.1/src/tests/test_ui/output/test_output_browse.py +11 -0
  117. voidx-3.7.1/src/tests/test_ui/output/test_tool_display.py +33 -0
  118. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/test_tree_smoke.py +56 -0
  119. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/test_display_policy.py +4 -4
  120. voidx-3.7.1/src/tests/test_voidx_entrypoint.py +71 -0
  121. voidx-3.7.1/src/tests/test_wheel_verify_cwd.py +67 -0
  122. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/__init__.py +1 -1
  123. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/attachments.py +2 -18
  124. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/goal_resolver.py +115 -18
  125. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/contracts.py +3 -2
  126. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/core/helpers.py +20 -1
  127. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/core/llm.py +313 -14
  128. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/core/voidx_graph.py +55 -14
  129. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/permissions.py +2 -0
  130. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/run_loop.py +35 -22
  131. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/runtime_guards.py +22 -1
  132. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/subagent.py +23 -8
  133. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/executor.py +58 -21
  134. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/guards.py +5 -4
  135. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/helpers.py +201 -36
  136. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/types.py +2 -0
  137. voidx-3.7.1/src/voidx/agent/graph/turn_control.py +146 -0
  138. voidx-3.7.1/src/voidx/agent/graph/turn_metrics.py +34 -0
  139. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/turn_runner.py +29 -20
  140. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/wiring.py +15 -5
  141. voidx-3.7.1/src/voidx/agent/loop/__init__.py +6 -0
  142. voidx-3.7.1/src/voidx/agent/loop/manager.py +162 -0
  143. voidx-3.7.1/src/voidx/agent/loop/prompt_source.py +136 -0
  144. voidx-3.7.1/src/voidx/agent/loop/slash.py +98 -0
  145. voidx-3.7.1/src/voidx/agent/prompts.py +312 -0
  146. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/runtime_context.py +45 -45
  147. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/handler.py +14 -4
  148. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/host.py +9 -3
  149. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/model.py +0 -1
  150. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/profile.py +1 -1
  151. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/runtime.py +3 -0
  152. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/state.py +1 -0
  153. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/models.py +18 -2
  154. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings.py +37 -4
  155. voidx-3.7.1/src/voidx/config/settings_permissions.py +172 -0
  156. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/README.md +1 -1
  157. voidx-3.7.1/src/voidx/data/documents/templates/api-doc.md +69 -0
  158. voidx-3.7.1/src/voidx/data/documents/templates/capability-spec.md +66 -0
  159. voidx-3.7.1/src/voidx/data/documents/templates/implementation-spec.md +98 -0
  160. voidx-3.7.1/src/voidx/data/documents/templates/prd.md +118 -0
  161. voidx-3.7.1/src/voidx/data/documents/templates/readme.md +26 -0
  162. voidx-3.7.1/src/voidx/data/documents/templates/rfc.md +56 -0
  163. voidx-3.7.1/src/voidx/data/documents/templates/tasks.md +65 -0
  164. voidx-3.7.1/src/voidx/data/documents/templates/tech-design.md +114 -0
  165. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/extension.md +7 -0
  166. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/reference.md +9 -1
  167. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/workflow.md +2 -0
  168. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/diffing.py +9 -4
  169. voidx-3.7.1/src/voidx/llm/catalog.py +403 -0
  170. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/compaction.py +57 -3
  171. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/instruction.py +5 -8
  172. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/provider.py +93 -3
  173. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/service.py +5 -0
  174. voidx-3.7.1/src/voidx/logging/external.py +47 -0
  175. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/client.py +77 -32
  176. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/errors.py +4 -0
  177. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/manager.py +5 -2
  178. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/main.py +14 -14
  179. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/base.py +37 -33
  180. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/http_transport.py +5 -11
  181. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/sse_transport.py +6 -13
  182. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/stdio_transport.py +5 -7
  183. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/manager.py +13 -13
  184. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/tool.py +11 -2
  185. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/transcript.py +0 -4
  186. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/paths.py +32 -0
  187. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/context.py +33 -2
  188. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/engine.py +57 -45
  189. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/evaluate.py +1 -1
  190. voidx-3.7.1/src/voidx/permission/git_policy.py +270 -0
  191. voidx-3.7.1/src/voidx/permission/grants.py +385 -0
  192. voidx-3.7.1/src/voidx/permission/process_sandbox.py +46 -0
  193. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/rules.py +10 -11
  194. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/schema.py +1 -1
  195. voidx-3.7.1/src/voidx/permission/service.py +589 -0
  196. voidx-3.7.1/src/voidx/permission/shell_policy.py +138 -0
  197. voidx-3.7.1/src/voidx/runtime/_win32_jobs.py +200 -0
  198. voidx-3.7.1/src/voidx/runtime/processes.py +277 -0
  199. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/ui.py +18 -1
  200. voidx-3.7.1/src/voidx/selfupdate.py +534 -0
  201. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/__init__.py +1 -2
  202. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/agent.py +42 -5
  203. voidx-3.7.1/src/voidx/tools/base.py +424 -0
  204. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/safety.py +1 -1
  205. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/tool.py +38 -11
  206. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/checkpoint.py +16 -18
  207. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/clarify.py +6 -9
  208. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/document.py +5 -7
  209. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/__init__.py +1 -3
  210. voidx-3.7.1/src/voidx/tools/file/manage.py +456 -0
  211. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/read.py +61 -36
  212. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/replace.py +116 -65
  213. voidx-3.7.1/src/voidx/tools/file/safe_path.py +461 -0
  214. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/state.py +8 -0
  215. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/write.py +109 -32
  216. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/git.py +356 -65
  217. voidx-3.7.1/src/voidx/tools/lsp.py +216 -0
  218. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/sandbox.py +4 -4
  219. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/tool.py +39 -11
  220. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/registry.py +13 -4
  221. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/retry.py +0 -7
  222. voidx-3.7.1/src/voidx/tools/schedule_wakeup.py +90 -0
  223. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/search.py +18 -21
  224. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/service.py +2 -2
  225. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/shell/common.py +12 -48
  226. voidx-3.7.1/src/voidx/tools/shell/hint/git.py +78 -0
  227. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/skills.py +5 -5
  228. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/todo.py +29 -8
  229. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/web/fetch.py +13 -2
  230. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/web/mcp.py +14 -1
  231. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/web/search.py +17 -1
  232. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/workflow.py +41 -12
  233. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/commands.py +11 -0
  234. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/adapter.py +22 -9
  235. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/server.py +11 -8
  236. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/core.py +10 -11
  237. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/sessions.py +2 -2
  238. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/settings.py +15 -6
  239. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/browse.py +0 -4
  240. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/console/app.py +2 -2
  241. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/console/formatting.py +5 -1
  242. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/diff.py +0 -2
  243. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/display_policy.py +1 -1
  244. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/__init__.py +2 -0
  245. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/app.py +45 -0
  246. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes.py +10 -41
  247. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes_checkpoint.py +6 -8
  248. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes_clarify.py +5 -8
  249. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes_status.py +0 -3
  250. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/state.py +6 -0
  251. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/status.py +21 -34
  252. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/events/__init__.py +2 -0
  253. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/events/bus.py +1 -5
  254. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/events/consumers.py +32 -68
  255. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/events/schema.py +9 -1
  256. voidx-3.7.1/src/voidx/ui/output/manage_display.py +113 -0
  257. voidx-3.7.1/src/voidx/ui/output/tool_display.py +62 -0
  258. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/tree.py +12 -1
  259. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/session.py +29 -3
  260. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/dag.py +1 -1
  261. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/nodes.py +33 -22
  262. {voidx-3.6.0 → voidx-3.7.1/src/voidx.egg-info}/PKG-INFO +20 -2
  263. {voidx-3.6.0 → voidx-3.7.1}/src/voidx.egg-info/SOURCES.txt +53 -0
  264. voidx-3.6.0/src/tests/test_agent/graph/test_execute_tools_guard.py +0 -798
  265. voidx-3.6.0/src/tests/test_agent/test_prompts.py +0 -53
  266. voidx-3.6.0/src/tests/test_archive_script.py +0 -180
  267. voidx-3.6.0/src/tests/test_selfupdate/test_selfupdate.py +0 -245
  268. voidx-3.6.0/src/tests/test_tools/test_file_tools_redesign.py +0 -390
  269. voidx-3.6.0/src/tests/test_tools/test_resolve_safe.py +0 -68
  270. voidx-3.6.0/src/tests/test_tools/test_tool_schemas.py +0 -178
  271. voidx-3.6.0/src/tests/test_ui/output/test_fmt_args.py +0 -50
  272. voidx-3.6.0/src/tests/test_ui/output/test_output_browse.py +0 -22
  273. voidx-3.6.0/src/voidx/agent/prompts.py +0 -174
  274. voidx-3.6.0/src/voidx/config/settings_permissions.py +0 -86
  275. voidx-3.6.0/src/voidx/data/documents/templates/api-doc.md +0 -64
  276. voidx-3.6.0/src/voidx/data/documents/templates/prd.md +0 -117
  277. voidx-3.6.0/src/voidx/data/documents/templates/readme.md +0 -9
  278. voidx-3.6.0/src/voidx/data/documents/templates/rfc.md +0 -38
  279. voidx-3.6.0/src/voidx/data/documents/templates/tech-design.md +0 -68
  280. voidx-3.6.0/src/voidx/llm/catalog.py +0 -204
  281. voidx-3.6.0/src/voidx/permission/service.py +0 -326
  282. voidx-3.6.0/src/voidx/selfupdate.py +0 -303
  283. voidx-3.6.0/src/voidx/tools/base.py +0 -230
  284. voidx-3.6.0/src/voidx/tools/file/manage.py +0 -277
  285. voidx-3.6.0/src/voidx/tools/lsp.py +0 -140
  286. voidx-3.6.0/src/voidx/tools/shell/hint/git.py +0 -44
  287. {voidx-3.6.0 → voidx-3.7.1}/LICENSE +0 -0
  288. {voidx-3.6.0 → voidx-3.7.1}/pyproject.toml +0 -0
  289. {voidx-3.6.0 → voidx-3.7.1}/setup.cfg +0 -0
  290. {voidx-3.6.0 → voidx-3.7.1}/src/tests/__init__.py +0 -0
  291. {voidx-3.6.0 → voidx-3.7.1}/src/tests/conftest.py +0 -0
  292. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/__init__.py +0 -0
  293. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/conftest.py +0 -0
  294. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/__init__.py +0 -0
  295. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/run_loop_helpers.py +0 -0
  296. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_compaction_flow.py +0 -0
  297. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_convergence.py +0 -0
  298. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_graph_authorization.py +0 -0
  299. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_parallel_subagents.py +0 -0
  300. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_run_loop_title_lsp.py +0 -0
  301. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_context_frames.py +0 -0
  302. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_crud.py +0 -0
  303. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_messages.py +0 -0
  304. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_persistence.py +0 -0
  305. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_run_once.py +0 -0
  306. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_runtime_state.py +0 -0
  307. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_session_transcript.py +0 -0
  308. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_stream_llm_sanitization.py +0 -0
  309. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_persistence.py +0 -0
  310. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_runner.py +0 -0
  311. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_step_budget.py +0 -0
  312. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_step_budget_convergence.py +0 -0
  313. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_subagent_step_budget_final.py +0 -0
  314. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_todo_events.py +0 -0
  315. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_tool_result_preview.py +0 -0
  316. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_workflow_done.py +0 -0
  317. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/graph/test_workflow_review.py +0 -0
  318. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/__init__.py +0 -0
  319. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_init.py +0 -0
  320. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_mcp.py +0 -0
  321. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_model_advanced.py +0 -0
  322. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_tavily.py +0 -0
  323. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/slash/test_slash_upgrade.py +0 -0
  324. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_attachments.py +0 -0
  325. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_message_trimming_parsers.py +0 -0
  326. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_module_boundaries.py +0 -0
  327. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_permission_append.py +0 -0
  328. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_runtime_context_prompts.py +0 -0
  329. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_runtime_context_skill_stripping.py +0 -0
  330. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_task_state.py +0 -0
  331. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_task_state_context_sync.py +0 -0
  332. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_todo_replay_sanitization.py +0 -0
  333. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_tool_exchange_sanitizer.py +0 -0
  334. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_tool_filters_gemini.py +0 -0
  335. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_tool_messages.py +0 -0
  336. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_agent/test_tool_result_storage.py +0 -0
  337. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_config/__init__.py +0 -0
  338. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_config/test_config.py +0 -0
  339. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_config/test_retry_config.py +0 -0
  340. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/conftest.py +0 -0
  341. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_compaction_retry.py +0 -0
  342. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_goal_resolver_retry.py +0 -0
  343. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_llm_provider_advanced.py +0 -0
  344. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_llm_usage.py +0 -0
  345. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_overflow_threshold.py +0 -0
  346. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_prune_args.py +0 -0
  347. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_request_log.py +0 -0
  348. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_streaming_sanitize.py +0 -0
  349. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_llm/test_token_counting.py +0 -0
  350. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_logging/test_internal_error.py +0 -0
  351. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_logging/test_tool_log.py +0 -0
  352. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_lsp/__init__.py +0 -0
  353. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_lsp/test_lsp_advanced.py +0 -0
  354. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_mcp/__init__.py +0 -0
  355. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_memory/__init__.py +0 -0
  356. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_memory/test_main_startup.py +0 -0
  357. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_memory/test_schema_migration.py +0 -0
  358. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_permission/__init__.py +0 -0
  359. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_runtime/__init__.py +0 -0
  360. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_runtime/test_goal_resolution_refactor.py +0 -0
  361. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_runtime/test_runtime_ui.py +0 -0
  362. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_selfupdate/__init__.py +0 -0
  363. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/__init__.py +0 -0
  364. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/conftest.py +0 -0
  365. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/test_create_skill.py +0 -0
  366. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/test_skill_parsing.py +0 -0
  367. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_skills/test_skill_references.py +0 -0
  368. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/__init__.py +0 -0
  369. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/bash/__init__.py +0 -0
  370. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/bash/test_router_safety.py +0 -0
  371. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/bash/test_router_sed_grep.py +0 -0
  372. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/__init__.py +0 -0
  373. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_coverage_fingerprint.py +0 -0
  374. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_anchors.py +0 -0
  375. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_drift_fallback.py +0 -0
  376. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_drift_fallback_e2e.py +0 -0
  377. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_line_insert.py +0 -0
  378. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_replace.py +0 -0
  379. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_edit_trailing_newline.py +0 -0
  380. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/file/test_render_numbered_diff.py +0 -0
  381. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_git_tool_destructive.py +0 -0
  382. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_load_doc_template.py +0 -0
  383. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_make_interact_callback.py +0 -0
  384. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_replace_failure_logging.py +0 -0
  385. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_retry.py +0 -0
  386. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_skills_tool.py +0 -0
  387. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_state_update_from_executed_tools.py +0 -0
  388. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_todo_tool.py +0 -0
  389. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_tool_state_patch.py +0 -0
  390. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_tools/test_user_interaction_models.py +0 -0
  391. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/__init__.py +0 -0
  392. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/conftest.py +0 -0
  393. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/helpers.py +0 -0
  394. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_diff_review.py +0 -0
  395. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_headless_frontend.py +0 -0
  396. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_v2_crud_diff.py +0 -0
  397. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_v2_dispatch.py +0 -0
  398. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_gateway_v2_session.py +0 -0
  399. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_guidance_fallback.py +0 -0
  400. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_run_manager.py +0 -0
  401. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_terminal.py +0 -0
  402. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_dock_bus.py +0 -0
  403. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_subagent.py +0 -0
  404. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/gateway/test_ui_events_todo.py +0 -0
  405. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/__init__.py +0 -0
  406. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/test_dock_formatting.py +0 -0
  407. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/test_scrollback_flush.py +0 -0
  408. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/test_ui_diff.py +0 -0
  409. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/output/test_ui_session_changes.py +0 -0
  410. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/__init__.py +0 -0
  411. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/test_dto.py +0 -0
  412. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/test_v2_envelope.py +0 -0
  413. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/test_v2_methods.py +0 -0
  414. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/test_v2_snapshot.py +0 -0
  415. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/protocol/test_v2_threads.py +0 -0
  416. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/test_file_picker.py +0 -0
  417. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/__init__.py +0 -0
  418. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/test_clipboard_image.py +0 -0
  419. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/test_clipboard_image_windows.py +0 -0
  420. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/test_clipboard_text.py +0 -0
  421. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/test_clipboard_text_windows.py +0 -0
  422. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_ui/tools/test_code_ide.py +0 -0
  423. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_wheel_build.py +0 -0
  424. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_workflow/__init__.py +0 -0
  425. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_workflow/test_auto_advance.py +0 -0
  426. {voidx-3.6.0 → voidx-3.7.1}/src/tests/test_workflow/test_workflow_reconcile.py +0 -0
  427. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/__init__.py +0 -0
  428. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/agents.py +0 -0
  429. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/__init__.py +0 -0
  430. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/compaction.py +0 -0
  431. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/compaction_coordinator.py +0 -0
  432. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/convergence.py +0 -0
  433. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/core/__init__.py +0 -0
  434. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/runtime.py +0 -0
  435. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/session_mixin.py +0 -0
  436. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/session_runtime.py +0 -0
  437. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/streaming.py +0 -0
  438. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/thread_context.py +0 -0
  439. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/title_mixin.py +0 -0
  440. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/todo_events.py +0 -0
  441. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_execution.py +0 -0
  442. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/__init__.py +0 -0
  443. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/ui.py +0 -0
  444. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/tool_executor/workflow.py +0 -0
  445. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/topology.py +0 -0
  446. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/transcript_mixin.py +0 -0
  447. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/turn_mixin.py +0 -0
  448. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/graph/workflow_utils.py +0 -0
  449. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/message_rows.py +0 -0
  450. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/message_trimming.py +0 -0
  451. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/__init__.py +0 -0
  452. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/code_ide.py +0 -0
  453. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/guide.py +0 -0
  454. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/init.py +0 -0
  455. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/lsp.py +0 -0
  456. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/mcp.py +0 -0
  457. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/session.py +0 -0
  458. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/skills.py +0 -0
  459. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/slash/upgrade.py +0 -0
  460. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/task_state.py +0 -0
  461. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/todo_state.py +0 -0
  462. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/tool_call_ids.py +0 -0
  463. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/tool_exchange_sanitizer.py +0 -0
  464. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/tool_filters.py +0 -0
  465. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/tool_messages.py +0 -0
  466. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/agent/tool_result_storage.py +0 -0
  467. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/__init__.py +0 -0
  468. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/defaults.py +0 -0
  469. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/enums.py +0 -0
  470. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/permissions.py +0 -0
  471. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_agent.py +0 -0
  472. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_api_keys.py +0 -0
  473. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_code_ide.py +0 -0
  474. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_custom.py +0 -0
  475. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_mcp.py +0 -0
  476. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_retry.py +0 -0
  477. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_skills.py +0 -0
  478. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_update.py +0 -0
  479. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_utils.py +0 -0
  480. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/config/settings_web.py +0 -0
  481. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/__init__.py +0 -0
  482. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/README.md +0 -0
  483. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/context.md +0 -0
  484. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/debug.md +0 -0
  485. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/mode.md +0 -0
  486. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/model.md +0 -0
  487. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/permission.md +0 -0
  488. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/preferences.md +0 -0
  489. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/quickstart.md +0 -0
  490. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/session.md +0 -0
  491. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/upgrade.md +0 -0
  492. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/data/documents/voidx-guide/web.md +0 -0
  493. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/__init__.py +0 -0
  494. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/context.py +0 -0
  495. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/message_markers.py +0 -0
  496. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/message_status.py +0 -0
  497. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/llm/usage.py +0 -0
  498. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/logging/__init__.py +0 -0
  499. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/logging/internal_error.py +0 -0
  500. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/logging/request_log.py +0 -0
  501. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/logging/tool_log.py +0 -0
  502. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/__init__.py +0 -0
  503. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/config.py +0 -0
  504. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/detector.py +0 -0
  505. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/detector_data.py +0 -0
  506. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/schema.py +0 -0
  507. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/lsp/service.py +0 -0
  508. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/__init__.py +0 -0
  509. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/__init__.py +0 -0
  510. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/client/errors.py +0 -0
  511. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp/schema.py +0 -0
  512. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp_servers/__init__.py +0 -0
  513. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/mcp_servers/web.py +0 -0
  514. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/__init__.py +0 -0
  515. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/cleanup.py +0 -0
  516. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/context_frames.py +0 -0
  517. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/jsonl_store.py +0 -0
  518. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/model_profiles.py +0 -0
  519. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/runtime_state.py +0 -0
  520. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/service.py +0 -0
  521. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/session.py +0 -0
  522. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/store.py +0 -0
  523. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/memory/subagents.py +0 -0
  524. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/__init__.py +0 -0
  525. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/sandbox.py +0 -0
  526. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/permission/wildcard.py +0 -0
  527. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/__init__.py +0 -0
  528. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/attachments.py +0 -0
  529. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/intent.py +0 -0
  530. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/reference_tokens.py +0 -0
  531. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/task_state.py +0 -0
  532. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/todo.py +0 -0
  533. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/runtime/ui_port.py +0 -0
  534. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/__init__.py +0 -0
  535. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/context.py +0 -0
  536. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/references.py +0 -0
  537. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/registry.py +0 -0
  538. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/schema.py +0 -0
  539. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/skills/service.py +0 -0
  540. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/__init__.py +0 -0
  541. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/core.py +0 -0
  542. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/hint/__init__.py +0 -0
  543. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/hint/file.py +0 -0
  544. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/hint/git.py +0 -0
  545. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/hint/search.py +0 -0
  546. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/bash/router.py +0 -0
  547. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/compact.py +0 -0
  548. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/replace_resolve.py +0 -0
  549. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/file/types.py +0 -0
  550. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/__init__.py +0 -0
  551. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/core.py +0 -0
  552. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/hint/__init__.py +0 -0
  553. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/hint/file.py +0 -0
  554. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/hint/search.py +0 -0
  555. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/router.py +0 -0
  556. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/powershell/safety.py +0 -0
  557. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/shell/__init__.py +0 -0
  558. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/shell/hint/__init__.py +0 -0
  559. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/task_status.py +0 -0
  560. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/task_tracker.py +0 -0
  561. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/web/__init__.py +0 -0
  562. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/tools/web/content.py +0 -0
  563. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/__init__.py +0 -0
  564. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/command_catalog.py +0 -0
  565. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/frontend.py +0 -0
  566. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/__init__.py +0 -0
  567. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/bootstrap.py +0 -0
  568. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/diff_review.py +0 -0
  569. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/frontend.py +0 -0
  570. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/run_manager.py +0 -0
  571. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/__init__.py +0 -0
  572. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/consumer.py +0 -0
  573. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/__init__.py +0 -0
  574. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/diff.py +0 -0
  575. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/integrations.py +0 -0
  576. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/session/method/terminal.py +0 -0
  577. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/gateway/terminal.py +0 -0
  578. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/__init__.py +0 -0
  579. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/agent_display.py +0 -0
  580. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/ansi_marker.py +0 -0
  581. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/capture.py +0 -0
  582. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/console/__init__.py +0 -0
  583. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/console/streaming.py +0 -0
  584. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/agent_placeholder.py +0 -0
  585. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/formatting.py +0 -0
  586. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes_permission.py +0 -0
  587. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/nodes_startup.py +0 -0
  588. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/stream.py +0 -0
  589. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/dock/todo.py +0 -0
  590. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/output/types.py +0 -0
  591. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/__init__.py +0 -0
  592. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/commands.py +0 -0
  593. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/requests.py +0 -0
  594. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/schema.py +0 -0
  595. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/transcript.py +0 -0
  596. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/v2/__init__.py +0 -0
  597. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/v2/envelope.py +0 -0
  598. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/v2/methods.py +0 -0
  599. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/v2/snapshot.py +0 -0
  600. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/protocol/v2/threads.py +0 -0
  601. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/__init__.py +0 -0
  602. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/attachment_tokens.py +0 -0
  603. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/clipboard_image.py +0 -0
  604. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/clipboard_text.py +0 -0
  605. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/code_ide.py +0 -0
  606. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/file_picker.py +0 -0
  607. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/tools/skill_picker.py +0 -0
  608. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/ui/transcript.py +0 -0
  609. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/__init__.py +0 -0
  610. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/auto_advance.py +0 -0
  611. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/context.py +0 -0
  612. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/policy.py +0 -0
  613. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/reconcile.py +0 -0
  614. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/render.py +0 -0
  615. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/route.py +0 -0
  616. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/runtime.py +0 -0
  617. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/schema.py +0 -0
  618. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/service.py +0 -0
  619. {voidx-3.6.0 → voidx-3.7.1}/src/voidx/workflow/types.py +0 -0
  620. {voidx-3.6.0 → voidx-3.7.1}/src/voidx.egg-info/dependency_links.txt +0 -0
  621. {voidx-3.6.0 → voidx-3.7.1}/src/voidx.egg-info/entry_points.txt +0 -0
  622. {voidx-3.6.0 → voidx-3.7.1}/src/voidx.egg-info/requires.txt +0 -0
  623. {voidx-3.6.0 → voidx-3.7.1}/src/voidx.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidx
3
- Version: 3.6.0
3
+ Version: 3.7.1
4
4
  Summary: A coding agent that quantifies everything and solves with tools, not fuzzy prompts.
5
5
  Author: chikhamx
6
6
  License: MIT
@@ -54,7 +54,7 @@ isolated environment — nothing else is needed on your machine.
54
54
  ### pip
55
55
 
56
56
  ```bash
57
- pip install voidx
57
+ python -m pip install voidx voidx-cli
58
58
  voidx
59
59
  ```
60
60
 
@@ -65,6 +65,24 @@ npm install -g @chikhamx/voidx
65
65
  voidx
66
66
  ```
67
67
 
68
+ ## Upgrade
69
+
70
+ Upgrade both Python packages together so the core and terminal UI stay on the
71
+ same version:
72
+
73
+ ```bash
74
+ python -m pip install --upgrade voidx voidx-cli
75
+ ```
76
+
77
+ For npm installations, upgrade the npm package instead:
78
+
79
+ ```bash
80
+ npm update -g @chikhamx/voidx
81
+ ```
82
+
83
+ The one-line installers can be rerun to repair or upgrade their managed
84
+ environment.
85
+
68
86
  ### From source
69
87
 
70
88
  ```bash
@@ -24,7 +24,7 @@ isolated environment — nothing else is needed on your machine.
24
24
  ### pip
25
25
 
26
26
  ```bash
27
- pip install voidx
27
+ python -m pip install voidx voidx-cli
28
28
  voidx
29
29
  ```
30
30
 
@@ -35,6 +35,24 @@ npm install -g @chikhamx/voidx
35
35
  voidx
36
36
  ```
37
37
 
38
+ ## Upgrade
39
+
40
+ Upgrade both Python packages together so the core and terminal UI stay on the
41
+ same version:
42
+
43
+ ```bash
44
+ python -m pip install --upgrade voidx voidx-cli
45
+ ```
46
+
47
+ For npm installations, upgrade the npm package instead:
48
+
49
+ ```bash
50
+ npm update -g @chikhamx/voidx
51
+ ```
52
+
53
+ The one-line installers can be rerun to repair or upgrade their managed
54
+ environment.
55
+
38
56
  ### From source
39
57
 
40
58
  ```bash
@@ -0,0 +1 @@
1
+ """Existing conftest."""
@@ -39,6 +39,10 @@ class FakeStreamingModel:
39
39
  self.messages = messages
40
40
  yield AIMessageChunk(content=[{"type": "thinking", "text": "think"}])
41
41
  yield AIMessageChunk(content="answer")
42
+ yield AIMessageChunk(
43
+ content="",
44
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
45
+ )
42
46
 
43
47
 
44
48
  class FakeUsageStreamingModel:
@@ -54,6 +58,10 @@ class FakeUsageStreamingModel:
54
58
  "total_tokens": 10,
55
59
  },
56
60
  )
61
+ yield AIMessageChunk(
62
+ content="",
63
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
64
+ )
57
65
 
58
66
 
59
67
  class FakeDuplicatedReasoningStreamingModel:
@@ -63,6 +71,10 @@ class FakeDuplicatedReasoningStreamingModel:
63
71
  additional_kwargs={"reasoning_content": "622"},
64
72
  )
65
73
  yield AIMessageChunk(content="final answer")
74
+ yield AIMessageChunk(
75
+ content="",
76
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
77
+ )
66
78
 
67
79
 
68
80
  class FakeDsmlStreamingModel:
@@ -130,6 +142,10 @@ class RepairsMalformedToolCallStreamingModel:
130
142
  ))
131
143
  return
132
144
  yield AIMessageChunk(content="repaired answer")
145
+ yield AIMessageChunk(
146
+ content="",
147
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
148
+ )
133
149
 
134
150
 
135
151
  class AlwaysMalformedToolCallStreamingModel:
@@ -208,6 +224,10 @@ class FailsOnceStreamingModel(FakeStreamingModel):
208
224
  raise ConnectionError("Connection error.")
209
225
  self.messages = messages
210
226
  yield AIMessageChunk(content="answer")
227
+ yield AIMessageChunk(
228
+ content="",
229
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
230
+ )
211
231
 
212
232
 
213
233
  class FakeRenderer:
@@ -1,6 +1,7 @@
1
1
  """Tests for call_llm compaction and retry."""
2
2
 
3
3
  import sys
4
+ import warnings
4
5
  from pathlib import Path
5
6
  from types import SimpleNamespace
6
7
 
@@ -17,7 +18,7 @@ from voidx.agent.runtime_context import RuntimeContextBuilder
17
18
  from voidx.agent.task_state import TaskState, TodoRunState
18
19
  from voidx.config import Config, ModelConfig
19
20
  from voidx.agent.graph.compaction_coordinator import CompactionResult, PreflightCompactionResult
20
- from voidx.llm.compaction import CompactionSelection
21
+ from voidx.llm.compaction import CompactionSelection, SUMMARY_TEMPLATE
21
22
  from voidx.llm.message_markers import is_guidance_message
22
23
  from voidx.memory.context_frames import load_context_frames
23
24
  from voidx.memory.session import MessageRow, create_session, delete_session, save_message
@@ -123,9 +124,48 @@ async def test_call_llm_injects_current_todo_runtime_context(tmp_path, monkeypat
123
124
 
124
125
 
125
126
  @pytest.mark.asyncio
126
- async def test_call_llm_updates_usage_stats(tmp_path, monkeypatch):
127
+ async def test_call_llm_updates_usage_stats_across_turn_control_calls(tmp_path, monkeypatch):
127
128
  import voidx.agent.graph.core.llm as graph_module
128
129
 
130
+ class TurnControlUsageStreamingModel:
131
+ def __init__(self):
132
+ self.calls = 0
133
+
134
+ def bind_tools(self, _tool_defs):
135
+ return self
136
+
137
+ async def astream(self, _messages):
138
+ self.calls += 1
139
+ if self.calls == 1:
140
+ yield AIMessageChunk(
141
+ content="answer",
142
+ usage_metadata={
143
+ "input_tokens": 7,
144
+ "output_tokens": 3,
145
+ "total_tokens": 10,
146
+ },
147
+ )
148
+ return
149
+ if self.calls == 2:
150
+ yield AIMessageChunk(
151
+ content="",
152
+ tool_calls=[
153
+ {
154
+ "name": "turn",
155
+ "args": {"operation": "stop", "intent": "", "goal": ""},
156
+ "id": "turn-usage",
157
+ "type": "tool_call",
158
+ }
159
+ ],
160
+ usage_metadata={
161
+ "input_tokens": 2,
162
+ "output_tokens": 1,
163
+ "total_tokens": 3,
164
+ },
165
+ )
166
+ return
167
+ pytest.fail(f"Unexpected LLM call {self.calls}")
168
+
129
169
  monkeypatch.setattr(graph_module, "StreamingRenderer", FakeRenderer)
130
170
 
131
171
  graph = VoidXGraph(
@@ -135,7 +175,7 @@ async def test_call_llm_updates_usage_stats(tmp_path, monkeypatch):
135
175
  ),
136
176
  api_key=None,
137
177
  )
138
- graph.model = FakeUsageStreamingModel()
178
+ graph.model = TurnControlUsageStreamingModel()
139
179
 
140
180
  result = await graph._call_llm({
141
181
  "messages": [HumanMessage(content="hi")],
@@ -144,11 +184,13 @@ async def test_call_llm_updates_usage_stats(tmp_path, monkeypatch):
144
184
  })
145
185
 
146
186
  assert result["step_count"] == 1
147
- assert graph._usage_stats.last_input_tokens == 7
148
- assert graph._usage_stats.last_output_tokens == 3
149
- assert graph._usage_stats.total_input_tokens == 7
150
- assert graph._usage_stats.total_output_tokens == 3
151
- assert graph._usage_stats.total_calls == 1
187
+ assert result["messages"][0].content == "answer"
188
+ assert graph.model.calls == 2
189
+ assert graph._usage_stats.last_input_tokens == 2
190
+ assert graph._usage_stats.last_output_tokens == 1
191
+ assert graph._usage_stats.total_input_tokens == 9
192
+ assert graph._usage_stats.total_output_tokens == 4
193
+ assert graph._usage_stats.total_calls == 2
152
194
 
153
195
 
154
196
  @pytest.mark.asyncio
@@ -224,6 +266,35 @@ def test_inline_compaction_guide_disabled_by_default(tmp_path):
224
266
  assert guide is None
225
267
 
226
268
 
269
+
270
+ def test_inline_compaction_guide_uses_shared_summary_template(tmp_path):
271
+ graph = VoidXGraph(
272
+ Config(
273
+ model=ModelConfig(provider="mimo", model="mimo-v2.5"),
274
+ workspace=str(tmp_path),
275
+ ),
276
+ api_key=None,
277
+ )
278
+ graph.config.inline_compaction_enabled = True
279
+ graph._compaction.usable_window = lambda: 1
280
+ graph._compaction.is_overflow = lambda _tokens: False
281
+ graph._compaction.select_details = lambda _messages: CompactionSelection(
282
+ head=[HumanMessage(content="old", id="old")],
283
+ tail_id="current",
284
+ keep_from=1,
285
+ mode="normal",
286
+ )
287
+
288
+ guide = graph._inline_compaction_guide_for([
289
+ HumanMessage(content="old", id="old"),
290
+ AIMessage(content="old answer"),
291
+ HumanMessage(content="current", id="current"),
292
+ ])
293
+
294
+ assert guide is not None
295
+ assert SUMMARY_TEMPLATE in str(guide.content)
296
+ assert "tail_anchor_id: current" in str(guide.content)
297
+
227
298
  @pytest.mark.asyncio
228
299
  async def test_call_llm_overflow_compaction_does_not_send_temporary_summary_message(tmp_path, monkeypatch):
229
300
  import voidx.agent.graph.core.llm as graph_module
@@ -280,6 +351,66 @@ async def test_call_llm_overflow_compaction_does_not_send_temporary_summary_mess
280
351
  )
281
352
 
282
353
 
354
+ @pytest.mark.asyncio
355
+ async def test_call_llm_coerces_todo_state_dict_before_compaction_dump(tmp_path, monkeypatch):
356
+ import voidx.agent.graph.core.llm as graph_module
357
+
358
+ monkeypatch.setattr(graph_module, "StreamingRenderer", FakeRenderer)
359
+ graph = VoidXGraph(
360
+ Config(
361
+ model=ModelConfig(provider="mimo", model="mimo-v2.5"),
362
+ workspace=str(tmp_path),
363
+ ),
364
+ api_key=None,
365
+ )
366
+ graph.model = FakeStreamingModel()
367
+ graph._compaction.is_overflow = lambda _tokens: True
368
+
369
+ async def preflight(messages, session_msgs=None, *, force=False, reason="threshold", ask=False):
370
+ result = CompactionResult(
371
+ summary="compacted",
372
+ removed_messages=list(messages[:1]),
373
+ live_messages=list(messages[1:]),
374
+ tail_id=getattr(messages[1], "id", None) if len(messages) > 1 else None,
375
+ metadata={"compaction_reason": reason},
376
+ )
377
+ return result, PreflightCompactionResult.from_compaction_result(result)
378
+
379
+ graph._preflight_compact_if_needed = preflight
380
+
381
+ todo_state = {
382
+ "summary": "0/1 done · 1 active · 0 pending",
383
+ "total": 1,
384
+ "done": 0,
385
+ "active": 1,
386
+ "pending": 0,
387
+ "active_items": [
388
+ {"id": "inspect", "content": "inspect warning", "status": "active"},
389
+ ],
390
+ "items": [
391
+ {"id": "inspect", "content": "inspect warning", "status": "active"},
392
+ ],
393
+ }
394
+
395
+ with warnings.catch_warnings(record=True) as caught:
396
+ warnings.simplefilter("always")
397
+ await graph._call_llm({
398
+ "messages": [
399
+ HumanMessage(content="old question", id="old_user"),
400
+ AIMessage(content="old answer"),
401
+ HumanMessage(content="current question", id="current_user"),
402
+ ],
403
+ "step_count": 0,
404
+ "persona": "voidx",
405
+ "todo_state": todo_state,
406
+ })
407
+
408
+ assert not any(
409
+ "PydanticSerializationUnexpectedValue" in str(warning.message)
410
+ for warning in caught
411
+ )
412
+
413
+
283
414
  @pytest.mark.asyncio
284
415
  async def test_call_llm_repairs_malformed_tool_call_once(tmp_path, monkeypatch):
285
416
  import voidx.agent.graph.core.llm as graph_module
@@ -360,6 +491,10 @@ class MalformedThenRepairsAfterCompactionStreamingModel:
360
491
  ))
361
492
  return
362
493
  yield AIMessageChunk(content="repaired after compaction")
494
+ yield AIMessageChunk(
495
+ content="",
496
+ tool_calls=[{"name": "turn", "args": {"operation": "stop", "intent": "", "goal": ""}, "id": "turn-1", "type": "tool_call"}],
497
+ )
363
498
 
364
499
 
365
500
  @pytest.mark.asyncio
@@ -627,3 +762,33 @@ async def test_call_llm_non_retryable_404_fail_fast(tmp_path, monkeypatch):
627
762
  assert result["should_continue"] is False
628
763
  assert result["step_count"] == 0
629
764
  assert result["messages"] == []
765
+
766
+
767
+ def test_llm_retry_delay_schedule():
768
+ """Verify the two-phase delay schedule for all 10 retry attempts."""
769
+ from voidx.agent.graph.core.helpers import _llm_retry_delay
770
+
771
+ delays = [_llm_retry_delay(i) for i in range(1, 11)]
772
+ assert delays == [2.0, 2.0, 2.0, 4.0, 8.0, 16.0, 32.0, 60.0, 60.0, 60.0]
773
+
774
+
775
+ def test_llm_retry_delay_fixed_phase():
776
+ """First two retries use fixed delay regardless of attempt number."""
777
+ from voidx.agent.graph.core.helpers import _llm_retry_delay
778
+
779
+ assert _llm_retry_delay(1) == 2.0
780
+ assert _llm_retry_delay(2) == 2.0
781
+
782
+
783
+ def test_llm_retry_delay_exponential_cap():
784
+ """Exponential phase doubles until capped at 60s."""
785
+ from voidx.agent.graph.core.helpers import _llm_retry_delay
786
+
787
+ assert _llm_retry_delay(3) == 2.0
788
+ assert _llm_retry_delay(4) == 4.0
789
+ assert _llm_retry_delay(5) == 8.0
790
+ assert _llm_retry_delay(6) == 16.0
791
+ assert _llm_retry_delay(7) == 32.0
792
+ assert _llm_retry_delay(8) == 60.0
793
+ assert _llm_retry_delay(9) == 60.0
794
+ assert _llm_retry_delay(10) == 60.0
@@ -182,7 +182,7 @@ class AlwaysFailsStreamingModel:
182
182
 
183
183
 
184
184
  @pytest.mark.asyncio
185
- async def test_call_llm_retries_five_times_then_renders_assistant_error_without_state_message(tmp_path, monkeypatch):
185
+ async def test_call_llm_exhausts_retries_then_renders_assistant_error(tmp_path, monkeypatch):
186
186
  import voidx.agent.graph.core.llm as graph_module
187
187
 
188
188
  async def no_sleep(_delay: float) -> None:
@@ -224,24 +224,29 @@ async def test_call_llm_retries_five_times_then_renders_assistant_error_without_
224
224
  test_dock.reset()
225
225
  set_dock(None)
226
226
 
227
- assert graph.model.calls == 6
227
+ assert graph.model.calls == 11
228
228
  assert result["should_continue"] is False
229
229
  assert result.get("messages", []) == []
230
230
  retry_events = [
231
231
  event for event in events
232
232
  if isinstance(event, StatusUpdated) and event.status_id == "llm:retry"
233
233
  ]
234
- assert [event.label for event in retry_events] == ["Retrying"] * 5
234
+ assert [event.label for event in retry_events] == ["Retrying"] * 10
235
235
  assert [event.detail for event in retry_events] == [
236
236
  "retrying in 2s: Connection error 1.",
237
- "retrying in 4s: Connection error 2.",
238
- "retrying in 6s: Connection error 3.",
239
- "retrying in 8s: Connection error 4.",
240
- "retrying in 10s: Connection error 5.",
237
+ "retrying in 2s: Connection error 2.",
238
+ "retrying in 2s: Connection error 3.",
239
+ "retrying in 4s: Connection error 4.",
240
+ "retrying in 8s: Connection error 5.",
241
+ "retrying in 16s: Connection error 6.",
242
+ "retrying in 32s: Connection error 7.",
243
+ "retrying in 60s: Connection error 8.",
244
+ "retrying in 60s: Connection error 9.",
245
+ "retrying in 60s: Connection error 10.",
241
246
  ]
242
247
  assert any(
243
248
  isinstance(event, AssistantStreamUpdated)
244
- and "LLM call failed after 6 attempts: Connection error 6." in event.text
249
+ and "LLM call failed after 11 attempts: Connection error 11." in event.text
245
250
  for event in events
246
251
  )
247
252
  assert any(isinstance(event, AssistantStreamCommitted) for event in events)
@@ -23,7 +23,16 @@ from voidx.memory.context_frames import load_context_frames
23
23
  from voidx.memory.session import MessageRow, create_session, delete_session, save_message
24
24
  from voidx.ui.output.console import StreamingRenderer
25
25
  from voidx.ui.output.dock import ANSI_LINE_PREFIX, BottomInputDock, set_dock
26
- from voidx.ui.output.events import AnsiAppended, DockEventConsumer, StatusFinished, StatusUpdated, ui_events
26
+ from voidx.ui.output.events import (
27
+ AnsiAppended,
28
+ DockEventConsumer,
29
+ GuidanceCommitted,
30
+ GuidanceSubmitted,
31
+ MessageAppended,
32
+ StatusFinished,
33
+ StatusUpdated,
34
+ ui_events,
35
+ )
27
36
  from voidx.workflow.runtime import WorkflowRunState, WorkflowRunStatus
28
37
  from tests.test_agent.graph.stream_llm_helpers import (
29
38
  _plain,
@@ -66,6 +75,111 @@ async def test_call_llm_guidance_does_not_create_main_agent_convergence_hint(tmp
66
75
  assert not any(is_step_hint_message(message) for message in model.messages)
67
76
 
68
77
 
78
+ @pytest.mark.asyncio
79
+ async def test_call_llm_guard_guidance_stays_hidden_from_ui_events(tmp_path, monkeypatch):
80
+ import voidx.agent.graph.core.llm as graph_module
81
+
82
+ monkeypatch.setattr(graph_module, "StreamingRenderer", FakeRenderer)
83
+
84
+ class RecordingEvents:
85
+ def __init__(self) -> None:
86
+ self.emitted = []
87
+
88
+ def emit_direct(self, event) -> bool:
89
+ self.emitted.append(event)
90
+ return True
91
+
92
+ async def emit(self, event) -> bool:
93
+ self.emitted.append(event)
94
+ return True
95
+
96
+ graph = VoidXGraph(
97
+ Config(
98
+ model=ModelConfig(provider="mimo", model="mimo-v2.5"),
99
+ workspace=str(tmp_path),
100
+ ),
101
+ api_key=None,
102
+ )
103
+ events = RecordingEvents()
104
+ graph._ui = SimpleNamespace(
105
+ console=Console(file=sys.stdout),
106
+ events=events,
107
+ ui=SimpleNamespace(
108
+ print=lambda *args, **kwargs: None,
109
+ error=lambda *args, **kwargs: None,
110
+ ),
111
+ via_events=lambda: True,
112
+ )
113
+ model = TrackingStreamingModel()
114
+ graph.model = model
115
+
116
+ graph.submit_guidance("No meaningful progress has been detected", source="guard")
117
+ result = await graph._call_llm({
118
+ "messages": [HumanMessage(content="finish the task")],
119
+ "step_count": 1,
120
+ "persona": "voidx",
121
+ })
122
+
123
+ assert result["step_count"] == 2
124
+ assert model.messages is not None
125
+ assert is_guidance_message(model.messages[-1])
126
+ assert model.messages[-1].content == "No meaningful progress has been detected"
127
+ assert not any(isinstance(event, GuidanceSubmitted | MessageAppended | GuidanceCommitted) for event in events.emitted)
128
+
129
+
130
+ @pytest.mark.asyncio
131
+ async def test_call_llm_user_guidance_commits_preview_without_persistent_message(tmp_path, monkeypatch):
132
+ import voidx.agent.graph.core.llm as graph_module
133
+
134
+ monkeypatch.setattr(graph_module, "StreamingRenderer", FakeRenderer)
135
+
136
+ class RecordingEvents:
137
+ def __init__(self) -> None:
138
+ self.emitted = []
139
+
140
+ def emit_direct(self, event) -> bool:
141
+ self.emitted.append(event)
142
+ return True
143
+
144
+ async def emit(self, event) -> bool:
145
+ self.emitted.append(event)
146
+ return True
147
+
148
+ graph = VoidXGraph(
149
+ Config(
150
+ model=ModelConfig(provider="mimo", model="mimo-v2.5"),
151
+ workspace=str(tmp_path),
152
+ ),
153
+ api_key=None,
154
+ )
155
+ events = RecordingEvents()
156
+ graph._ui = SimpleNamespace(
157
+ console=Console(file=sys.stdout),
158
+ events=events,
159
+ ui=SimpleNamespace(
160
+ print=lambda *args, **kwargs: None,
161
+ error=lambda *args, **kwargs: None,
162
+ ),
163
+ via_events=lambda: True,
164
+ )
165
+ model = TrackingStreamingModel()
166
+ graph.model = model
167
+
168
+ graph.submit_guidance("先写 spedc文档", source="user")
169
+ events.emitted.clear()
170
+ result = await graph._call_llm({
171
+ "messages": [HumanMessage(content="finish the task")],
172
+ "step_count": 1,
173
+ "persona": "voidx",
174
+ })
175
+
176
+ assert result["step_count"] == 2
177
+ assert model.messages is not None
178
+ assert is_guidance_message(model.messages[-1])
179
+ assert model.messages[-1].content == "先写 spedc文档"
180
+ assert events.emitted == [GuidanceCommitted(text="先写 spedc文档")]
181
+
182
+
69
183
  @pytest.mark.asyncio
70
184
  async def test_call_llm_context_frame_records_no_main_agent_convergence_hint(tmp_path, monkeypatch):
71
185
  import voidx.agent.graph.core.llm as graph_module
@@ -233,7 +347,8 @@ async def test_call_llm_keeps_bound_tools_fixed_across_active_workflow_node(tmp_
233
347
  assert "clarify" in tool_names
234
348
  assert "workflow" in tool_names
235
349
  assert ("bash" if os.name != "nt" else "powershell") in tool_names
236
- assert "file" in tool_names
350
+ assert "manage" in tool_names
351
+ assert "file" not in tool_names
237
352
  assert "write" in tool_names
238
353
  assert "replace" in tool_names
239
354
  assert "line" not in tool_names
@@ -139,7 +139,7 @@ async def test_compaction_uses_previous_summary_and_prunes_persisted_head(tmp_pa
139
139
  await save_message(MessageRow(session_id=session.id, role="assistant", content="old answer"))
140
140
  await save_message(MessageRow(session_id=session.id, role="user", content="tail question"))
141
141
 
142
- graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key="test", session=session)
142
+ graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key=None, session=session)
143
143
  graph._compaction_summary = "previous summary"
144
144
  graph._compaction.is_overflow = lambda _tokens: True
145
145
  graph._compaction.select_details = lambda messages: CompactionSelection(
@@ -189,7 +189,7 @@ async def test_compaction_uses_previous_summary_and_prunes_persisted_head(tmp_pa
189
189
  assert "current question" in initial_contents
190
190
  assert graph._compaction_summary == "updated summary"
191
191
 
192
- resumed = VoidXGraph(Config(workspace=str(tmp_path)), api_key="test", session=session)
192
+ resumed = VoidXGraph(Config(workspace=str(tmp_path)), api_key=None, session=session)
193
193
  await resumed._restore_runtime_state()
194
194
 
195
195
  assert resumed._compaction_summary == "updated summary"
@@ -205,7 +205,7 @@ async def test_run_once_passes_compacted_messages_to_graph(tmp_path):
205
205
  await save_message(MessageRow(session_id=session.id, role="assistant", content="old answer"))
206
206
  await save_message(MessageRow(session_id=session.id, role="user", content="tail question"))
207
207
 
208
- graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key="test", session=session)
208
+ graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key=None, session=session)
209
209
  graph._compaction.is_overflow = lambda _tokens: False
210
210
  graph._compaction.is_soft_overflow = lambda _tokens: True
211
211
  graph._compaction.select_preflight_details = lambda messages, *, model="": CompactionSelection(
@@ -257,7 +257,7 @@ async def test_run_once_finishes_analyzing_before_preflight_compaction_status(tm
257
257
  await save_message(MessageRow(session_id=session.id, role="assistant", content="old answer"))
258
258
  await save_message(MessageRow(session_id=session.id, role="user", content="tail question"))
259
259
 
260
- graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key="test", session=session)
260
+ graph = VoidXGraph(Config(workspace=str(tmp_path)), api_key=None, session=session)
261
261
  graph._compaction.is_overflow = lambda _tokens: False
262
262
  graph._compaction.is_soft_overflow = lambda _tokens: True
263
263
  graph._compaction.select_preflight_details = lambda messages, *, model="": CompactionSelection(