voidx 3.7.2__tar.gz → 3.7.4__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 (626) hide show
  1. {voidx-3.7.2/src/voidx.egg-info → voidx-3.7.4}/PKG-INFO +1 -1
  2. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_call_llm_compaction.py +29 -0
  3. voidx-3.7.4/src/tests/test_agent/graph/test_call_llm_structure.py +12 -0
  4. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_graph_authorization.py +83 -31
  5. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_runner.py +0 -1
  6. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_tool_execution_auth.py +23 -3
  7. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_turn_control_e2e.py +5 -0
  8. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_turn_control_integration.py +30 -16
  9. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_workflow_transactions_barrier.py +0 -1
  10. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/loop/test_manager.py +20 -2
  11. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_model.py +6 -6
  12. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_model_advanced.py +6 -6
  13. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission.py +16 -16
  14. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_phase2.py +5 -5
  15. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_phase4.py +15 -32
  16. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_phase5.py +7 -8
  17. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_phase6.py +7 -20
  18. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_tool_result_storage.py +62 -0
  19. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_config/test_config_advanced.py +15 -16
  20. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_llm_usage.py +25 -0
  21. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_permission/test_risk.py +54 -6
  22. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/test_skill_parsing.py +0 -1
  23. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/test_skill_references.py +0 -1
  24. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/test_workflow_advance.py +0 -5
  25. voidx-3.7.4/src/tests/test_tools/bash/test_auto_route_git.py +342 -0
  26. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/bash/test_router_git.py +24 -0
  27. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/bash/test_tool.py +98 -5
  28. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_dedup.py +103 -0
  29. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_line_insert.py +181 -0
  30. voidx-3.7.4/src/tests/test_tools/file/test_overlap.py +73 -0
  31. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_git_tool_destructive.py +2 -3
  32. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_git_tool_phase5.py +2 -2
  33. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_git_tool_raw_permissions.py +1 -2
  34. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_git_tool_schema_errors.py +0 -1
  35. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_git_tool_structured.py +4 -4
  36. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_powershell_tool.py +52 -2
  37. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_powershell_tool_phase6.py +3 -3
  38. voidx-3.7.4/src/tests/test_tools/test_shell_json_format.py +33 -0
  39. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_shell_tool_phase6.py +3 -3
  40. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_tool_schemas.py +2 -0
  41. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_v2_dispatch.py +3 -5
  42. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_v2_routing.py +50 -0
  43. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/__init__.py +1 -1
  44. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/goal_resolver.py +13 -4
  45. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/contracts.py +3 -2
  46. voidx-3.7.4/src/voidx/agent/graph/core/context.py +94 -0
  47. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/core/helpers.py +4 -3
  48. voidx-3.7.4/src/voidx/agent/graph/core/llm.py +548 -0
  49. voidx-3.7.4/src/voidx/agent/graph/core/loop.py +108 -0
  50. voidx-3.7.4/src/voidx/agent/graph/core/turn.py +353 -0
  51. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/permissions.py +15 -77
  52. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/run_loop.py +2 -2
  53. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/session_runtime.py +1 -1
  54. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/subagent.py +21 -7
  55. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/thread_context.py +3 -0
  56. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/executor.py +5 -2
  57. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/helpers.py +2 -1
  58. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/workflow.py +2 -1
  59. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/turn_control.py +7 -2
  60. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/turn_runner.py +11 -5
  61. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/wiring.py +0 -4
  62. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/loop/manager.py +5 -2
  63. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/loop/slash.py +2 -1
  64. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/prompts.py +7 -6
  65. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/runtime_context.py +22 -7
  66. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/handler.py +20 -42
  67. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/host.py +1 -1
  68. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/init.py +2 -1
  69. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/todo_state.py +5 -4
  70. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/tool_result_storage.py +34 -9
  71. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/__init__.py +0 -8
  72. voidx-3.7.4/src/voidx/config/enums.py +41 -0
  73. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/models.py +2 -6
  74. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings.py +0 -8
  75. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_permissions.py +7 -57
  76. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/permission.md +5 -5
  77. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/reference.md +1 -1
  78. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/usage.py +20 -1
  79. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/paths.py +2 -0
  80. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/__init__.py +4 -4
  81. voidx-3.7.4/src/voidx/permission/constants.py +177 -0
  82. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/context.py +20 -11
  83. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/engine.py +6 -6
  84. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/git_policy.py +13 -72
  85. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/grants.py +1 -0
  86. voidx-3.7.4/src/voidx/permission/presets.py +73 -0
  87. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/rules.py +10 -13
  88. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/sandbox.py +11 -39
  89. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/schema.py +9 -3
  90. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/service.py +36 -73
  91. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/shell_policy.py +13 -14
  92. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/intent.py +8 -0
  93. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/task_state.py +8 -2
  94. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/base.py +18 -1
  95. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/tool.py +5 -1
  96. voidx-3.7.4/src/voidx/tools/file/overlap.py +35 -0
  97. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/replace.py +120 -83
  98. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/safe_path.py +0 -2
  99. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/write.py +43 -6
  100. voidx-3.7.4/src/voidx/tools/git/__init__.py +7 -0
  101. voidx-3.7.4/src/voidx/tools/git/access.py +251 -0
  102. voidx-3.7.4/src/voidx/tools/git/constants.py +54 -0
  103. voidx-3.7.4/src/voidx/tools/git/handlers.py +349 -0
  104. voidx-3.7.4/src/voidx/tools/git/models.py +38 -0
  105. voidx-3.7.4/src/voidx/tools/git/parsers.py +247 -0
  106. voidx-3.7.4/src/voidx/tools/git/process.py +81 -0
  107. voidx-3.7.4/src/voidx/tools/git/results.py +90 -0
  108. voidx-3.7.4/src/voidx/tools/git/routing.py +145 -0
  109. voidx-3.7.4/src/voidx/tools/git/tool.py +109 -0
  110. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/tool.py +5 -1
  111. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/search.py +4 -4
  112. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/shell/common.py +22 -4
  113. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/shell/hint/git.py +15 -9
  114. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/command_catalog.py +3 -4
  115. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/commands.py +5 -9
  116. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/core.py +10 -1
  117. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/settings.py +4 -8
  118. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/events/bus.py +15 -3
  119. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/types.py +0 -1
  120. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/__init__.py +0 -2
  121. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/nodes.py +0 -4
  122. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/policy.py +0 -6
  123. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/render.py +0 -4
  124. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/schema.py +0 -10
  125. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/service.py +0 -1
  126. {voidx-3.7.2 → voidx-3.7.4/src/voidx.egg-info}/PKG-INFO +1 -1
  127. {voidx-3.7.2 → voidx-3.7.4}/src/voidx.egg-info/SOURCES.txt +19 -1
  128. voidx-3.7.2/src/voidx/agent/graph/core/llm.py +0 -800
  129. voidx-3.7.2/src/voidx/config/enums.py +0 -69
  130. voidx-3.7.2/src/voidx/permission/presets.py +0 -66
  131. voidx-3.7.2/src/voidx/tools/git.py +0 -1242
  132. {voidx-3.7.2 → voidx-3.7.4}/LICENSE +0 -0
  133. {voidx-3.7.2 → voidx-3.7.4}/README.md +0 -0
  134. {voidx-3.7.2 → voidx-3.7.4}/pyproject.toml +0 -0
  135. {voidx-3.7.2 → voidx-3.7.4}/setup.cfg +0 -0
  136. {voidx-3.7.2 → voidx-3.7.4}/src/tests/__init__.py +0 -0
  137. {voidx-3.7.2 → voidx-3.7.4}/src/tests/conftest.py +0 -0
  138. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/__init__.py +0 -0
  139. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/conftest.py +0 -0
  140. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/__init__.py +0 -0
  141. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/conftest.py +0 -0
  142. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/run_loop_helpers.py +0 -0
  143. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/stream_llm_helpers.py +0 -0
  144. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_call_llm_compaction_advanced.py +0 -0
  145. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_call_llm_tools.py +0 -0
  146. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_compaction_flow.py +0 -0
  147. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_compaction_flow_run_once.py +0 -0
  148. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_convergence.py +0 -0
  149. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_execute_tools_guard.py +0 -0
  150. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_execute_tools_todo.py +0 -0
  151. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_graph_setup_prompts.py +0 -0
  152. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_guards_tool_op.py +0 -0
  153. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_parallel_subagents.py +0 -0
  154. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_parallel_subagents_dedup.py +0 -0
  155. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_prepare_workflow.py +0 -0
  156. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_run_loop_startup.py +0 -0
  157. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_run_loop_title_lsp.py +0 -0
  158. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_run_loop_title_misc.py +0 -0
  159. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_run_loop_workflow.py +0 -0
  160. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_run_loop_workflow_advanced.py +0 -0
  161. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_runtime_guards.py +0 -0
  162. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_context_frames.py +0 -0
  163. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_crud.py +0 -0
  164. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_messages.py +0 -0
  165. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_persistence.py +0 -0
  166. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_run_once.py +0 -0
  167. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_runtime_state.py +0 -0
  168. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_session_transcript.py +0 -0
  169. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_stream_llm_sanitization.py +0 -0
  170. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_llm_retry.py +0 -0
  171. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_persistence.py +0 -0
  172. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_step_budget.py +0 -0
  173. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_step_budget_convergence.py +0 -0
  174. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_subagent_step_budget_final.py +0 -0
  175. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_todo_events.py +0 -0
  176. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_tool_result_preview.py +0 -0
  177. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_turn_runner_guidance_discard.py +0 -0
  178. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_turn_runner_idle_event.py +0 -0
  179. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_turn_stop_without_pending.py +0 -0
  180. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_workflow_done.py +0 -0
  181. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_workflow_review.py +0 -0
  182. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/graph/test_workflow_transactions.py +0 -0
  183. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/loop/test_prompt_source.py +0 -0
  184. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/__init__.py +0 -0
  185. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_init.py +0 -0
  186. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_loop.py +0 -0
  187. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_mcp.py +0 -0
  188. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_session.py +0 -0
  189. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_skills.py +0 -0
  190. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_tavily.py +0 -0
  191. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/slash/test_slash_upgrade.py +0 -0
  192. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_attachments.py +0 -0
  193. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_file_rwlock.py +0 -0
  194. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_goal_resolver.py +0 -0
  195. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_goal_resolver_advanced.py +0 -0
  196. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_guard_guidance.py +0 -0
  197. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_guide_command.py +0 -0
  198. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_message_trimming_parsers.py +0 -0
  199. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_message_trimming_rules.py +0 -0
  200. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_module_boundaries.py +0 -0
  201. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_append.py +0 -0
  202. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_permission_phase3.py +0 -0
  203. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_prompts.py +0 -0
  204. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_runtime_context_builder.py +0 -0
  205. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_runtime_context_prompts.py +0 -0
  206. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_runtime_context_skill_stripping.py +0 -0
  207. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_task_state.py +0 -0
  208. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_task_state_context_sync.py +0 -0
  209. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_task_state_rendering.py +0 -0
  210. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_todo_replay_sanitization.py +0 -0
  211. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_tool_exchange_sanitizer.py +0 -0
  212. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_tool_filters_gemini.py +0 -0
  213. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_tool_messages.py +0 -0
  214. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_turn_control.py +0 -0
  215. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_turn_control_prompt.py +0 -0
  216. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_turn_metrics.py +0 -0
  217. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_agent/test_turn_start.py +0 -0
  218. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_archive_script.py +0 -0
  219. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_config/__init__.py +0 -0
  220. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_config/test_config.py +0 -0
  221. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_config/test_retry_config.py +0 -0
  222. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_install_sh.py +0 -0
  223. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/conftest.py +0 -0
  224. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_compaction_retry.py +0 -0
  225. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_fallback_summary.py +0 -0
  226. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_gemini_provider.py +0 -0
  227. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_goal_resolver_retry.py +0 -0
  228. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_instruction_cache.py +0 -0
  229. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_llm_catalog.py +0 -0
  230. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_llm_catalog_fetchers.py +0 -0
  231. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_llm_provider.py +0 -0
  232. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_llm_provider_advanced.py +0 -0
  233. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_overflow_threshold.py +0 -0
  234. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_prune_args.py +0 -0
  235. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_request_log.py +0 -0
  236. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_streaming_sanitize.py +0 -0
  237. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_llm/test_token_counting.py +0 -0
  238. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_logging/test_external.py +0 -0
  239. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_logging/test_internal_error.py +0 -0
  240. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_logging/test_tool_log.py +0 -0
  241. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_lsp/__init__.py +0 -0
  242. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_lsp/test_lsp.py +0 -0
  243. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_lsp/test_lsp_advanced.py +0 -0
  244. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_mcp/__init__.py +0 -0
  245. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_mcp/test_mcp.py +0 -0
  246. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_memory/__init__.py +0 -0
  247. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_memory/test_main.py +0 -0
  248. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_memory/test_main_startup.py +0 -0
  249. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_memory/test_schema_migration.py +0 -0
  250. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_npm_package.py +0 -0
  251. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_permission/__init__.py +0 -0
  252. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_release_npm_wheel_sync.py +0 -0
  253. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_runtime/__init__.py +0 -0
  254. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_runtime/test_goal_resolution_refactor.py +0 -0
  255. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_runtime/test_processes.py +0 -0
  256. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_runtime/test_runtime_ui.py +0 -0
  257. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_selfupdate/__init__.py +0 -0
  258. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_selfupdate/test_selfupdate.py +0 -0
  259. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/__init__.py +0 -0
  260. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/conftest.py +0 -0
  261. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_skills/test_create_skill.py +0 -0
  262. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_test_runner.py +0 -0
  263. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/__init__.py +0 -0
  264. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/bash/__init__.py +0 -0
  265. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/bash/test_router_safety.py +0 -0
  266. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/bash/test_router_sed_grep.py +0 -0
  267. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/__init__.py +0 -0
  268. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_coverage_fingerprint.py +0 -0
  269. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_anchors.py +0 -0
  270. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_bounds_input.py +0 -0
  271. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_coverage.py +0 -0
  272. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_drift_fallback.py +0 -0
  273. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_drift_fallback_e2e.py +0 -0
  274. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_errors.py +0 -0
  275. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_llm_messages.py +0 -0
  276. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_replace.py +0 -0
  277. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_edit_trailing_newline.py +0 -0
  278. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_read.py +0 -0
  279. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_read_write.py +0 -0
  280. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_render_numbered_diff.py +0 -0
  281. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/file/test_write_file.py +0 -0
  282. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_clarify_tool.py +0 -0
  283. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_diffing.py +0 -0
  284. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_file_tools_redesign.py +0 -0
  285. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_infer_state_patch.py +0 -0
  286. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_interactive_tools.py +0 -0
  287. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_interactive_tools_write.py +0 -0
  288. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_load_doc_template.py +0 -0
  289. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_loop_integration.py +0 -0
  290. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_loop_registry.py +0 -0
  291. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_make_interact_callback.py +0 -0
  292. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_plan_checkpoint.py +0 -0
  293. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_replace_failure_logging.py +0 -0
  294. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_resolve_safe.py +0 -0
  295. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_retry.py +0 -0
  296. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_schedule_wakeup.py +0 -0
  297. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_search.py +0 -0
  298. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_skills_tool.py +0 -0
  299. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_state_update_from_executed_tools.py +0 -0
  300. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_task_tracker.py +0 -0
  301. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_todo_tool.py +0 -0
  302. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_tool_error_handling.py +0 -0
  303. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_tool_registry.py +0 -0
  304. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_tool_state_patch.py +0 -0
  305. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_user_interaction_models.py +0 -0
  306. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_web_mcp.py +0 -0
  307. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_webfetch.py +0 -0
  308. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_tools/test_workflow_tool.py +0 -0
  309. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/__init__.py +0 -0
  310. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/conftest.py +0 -0
  311. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/helpers.py +0 -0
  312. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_adapter.py +0 -0
  313. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_diff_review.py +0 -0
  314. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_headless_frontend.py +0 -0
  315. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_v2_crud_diff.py +0 -0
  316. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_v2_server.py +0 -0
  317. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_gateway_v2_session.py +0 -0
  318. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_guidance_fallback.py +0 -0
  319. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_run_manager.py +0 -0
  320. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_terminal.py +0 -0
  321. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_dock_bus.py +0 -0
  322. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_dock_prompts.py +0 -0
  323. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_dock_status.py +0 -0
  324. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_streaming.py +0 -0
  325. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_subagent.py +0 -0
  326. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_events_todo.py +0 -0
  327. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/gateway/test_ui_gateway.py +0 -0
  328. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/__init__.py +0 -0
  329. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_console_app.py +0 -0
  330. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_dock_formatting.py +0 -0
  331. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_fmt_args.py +0 -0
  332. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_output_browse.py +0 -0
  333. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_scrollback_flush.py +0 -0
  334. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_tool_display.py +0 -0
  335. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_tree_smoke.py +0 -0
  336. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_ui_diff.py +0 -0
  337. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/output/test_ui_session_changes.py +0 -0
  338. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/__init__.py +0 -0
  339. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/test_dto.py +0 -0
  340. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/test_v2_envelope.py +0 -0
  341. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/test_v2_methods.py +0 -0
  342. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/test_v2_snapshot.py +0 -0
  343. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/protocol/test_v2_threads.py +0 -0
  344. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/test_display_policy.py +0 -0
  345. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/test_file_picker.py +0 -0
  346. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/__init__.py +0 -0
  347. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/test_clipboard_image.py +0 -0
  348. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/test_clipboard_image_windows.py +0 -0
  349. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/test_clipboard_text.py +0 -0
  350. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/test_clipboard_text_windows.py +0 -0
  351. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_ui/tools/test_code_ide.py +0 -0
  352. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_voidx_entrypoint.py +0 -0
  353. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_wheel_build.py +0 -0
  354. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_wheel_verify_cwd.py +0 -0
  355. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_workflow/__init__.py +0 -0
  356. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_workflow/test_auto_advance.py +0 -0
  357. {voidx-3.7.2 → voidx-3.7.4}/src/tests/test_workflow/test_workflow_reconcile.py +0 -0
  358. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/__init__.py +0 -0
  359. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/agents.py +0 -0
  360. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/attachments.py +0 -0
  361. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/__init__.py +0 -0
  362. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/compaction.py +0 -0
  363. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/compaction_coordinator.py +0 -0
  364. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/convergence.py +0 -0
  365. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/core/__init__.py +0 -0
  366. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/core/voidx_graph.py +0 -0
  367. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/runtime.py +0 -0
  368. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/runtime_guards.py +0 -0
  369. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/session_mixin.py +0 -0
  370. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/streaming.py +0 -0
  371. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/title_mixin.py +0 -0
  372. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/todo_events.py +0 -0
  373. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_execution.py +0 -0
  374. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/__init__.py +0 -0
  375. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/guards.py +0 -0
  376. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/types.py +0 -0
  377. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/tool_executor/ui.py +0 -0
  378. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/topology.py +0 -0
  379. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/transcript_mixin.py +0 -0
  380. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/turn_metrics.py +0 -0
  381. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/turn_mixin.py +0 -0
  382. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/graph/workflow_utils.py +0 -0
  383. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/loop/__init__.py +0 -0
  384. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/loop/prompt_source.py +0 -0
  385. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/message_rows.py +0 -0
  386. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/message_trimming.py +0 -0
  387. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/__init__.py +0 -0
  388. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/code_ide.py +0 -0
  389. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/guide.py +0 -0
  390. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/lsp.py +0 -0
  391. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/mcp.py +0 -0
  392. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/model.py +0 -0
  393. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/profile.py +0 -0
  394. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/runtime.py +0 -0
  395. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/session.py +0 -0
  396. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/skills.py +0 -0
  397. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/slash/upgrade.py +0 -0
  398. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/state.py +0 -0
  399. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/task_state.py +0 -0
  400. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/tool_call_ids.py +0 -0
  401. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/tool_exchange_sanitizer.py +0 -0
  402. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/tool_filters.py +0 -0
  403. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/agent/tool_messages.py +0 -0
  404. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/defaults.py +0 -0
  405. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_agent.py +0 -0
  406. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_api_keys.py +0 -0
  407. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_code_ide.py +0 -0
  408. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_custom.py +0 -0
  409. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_mcp.py +0 -0
  410. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_retry.py +0 -0
  411. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_skills.py +0 -0
  412. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_update.py +0 -0
  413. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_utils.py +0 -0
  414. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/config/settings_web.py +0 -0
  415. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/__init__.py +0 -0
  416. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/README.md +0 -0
  417. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/api-doc.md +0 -0
  418. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/capability-spec.md +0 -0
  419. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/implementation-spec.md +0 -0
  420. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/prd.md +0 -0
  421. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/readme.md +0 -0
  422. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/rfc.md +0 -0
  423. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/tasks.md +0 -0
  424. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/templates/tech-design.md +0 -0
  425. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/README.md +0 -0
  426. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/context.md +0 -0
  427. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/debug.md +0 -0
  428. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/extension.md +0 -0
  429. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/mode.md +0 -0
  430. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/model.md +0 -0
  431. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/preferences.md +0 -0
  432. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/quickstart.md +0 -0
  433. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/session.md +0 -0
  434. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/upgrade.md +0 -0
  435. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/web.md +0 -0
  436. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/data/documents/voidx-guide/workflow.md +0 -0
  437. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/diffing.py +0 -0
  438. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/__init__.py +0 -0
  439. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/catalog.py +0 -0
  440. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/compaction.py +0 -0
  441. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/context.py +0 -0
  442. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/instruction.py +0 -0
  443. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/message_markers.py +0 -0
  444. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/message_status.py +0 -0
  445. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/provider.py +0 -0
  446. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/llm/service.py +0 -0
  447. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/logging/__init__.py +0 -0
  448. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/logging/external.py +0 -0
  449. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/logging/internal_error.py +0 -0
  450. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/logging/request_log.py +0 -0
  451. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/logging/tool_log.py +0 -0
  452. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/__init__.py +0 -0
  453. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/client.py +0 -0
  454. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/config.py +0 -0
  455. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/detector.py +0 -0
  456. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/detector_data.py +0 -0
  457. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/errors.py +0 -0
  458. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/manager.py +0 -0
  459. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/schema.py +0 -0
  460. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/lsp/service.py +0 -0
  461. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/main.py +0 -0
  462. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/__init__.py +0 -0
  463. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/__init__.py +0 -0
  464. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/base.py +0 -0
  465. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/errors.py +0 -0
  466. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/http_transport.py +0 -0
  467. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/sse_transport.py +0 -0
  468. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/client/stdio_transport.py +0 -0
  469. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/manager.py +0 -0
  470. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/schema.py +0 -0
  471. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp/tool.py +0 -0
  472. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp_servers/__init__.py +0 -0
  473. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/mcp_servers/web.py +0 -0
  474. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/__init__.py +0 -0
  475. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/cleanup.py +0 -0
  476. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/context_frames.py +0 -0
  477. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/jsonl_store.py +0 -0
  478. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/model_profiles.py +0 -0
  479. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/runtime_state.py +0 -0
  480. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/service.py +0 -0
  481. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/session.py +0 -0
  482. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/store.py +0 -0
  483. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/subagents.py +0 -0
  484. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/memory/transcript.py +0 -0
  485. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/evaluate.py +0 -0
  486. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/process_sandbox.py +0 -0
  487. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/risk.py +0 -0
  488. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/permission/wildcard.py +0 -0
  489. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/__init__.py +0 -0
  490. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/_win32_jobs.py +0 -0
  491. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/attachments.py +0 -0
  492. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/processes.py +0 -0
  493. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/reference_tokens.py +0 -0
  494. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/todo.py +0 -0
  495. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/ui.py +0 -0
  496. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/runtime/ui_port.py +0 -0
  497. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/selfupdate.py +0 -0
  498. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/__init__.py +0 -0
  499. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/context.py +0 -0
  500. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/references.py +0 -0
  501. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/registry.py +0 -0
  502. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/schema.py +0 -0
  503. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/skills/service.py +0 -0
  504. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/__init__.py +0 -0
  505. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/agent.py +0 -0
  506. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/__init__.py +0 -0
  507. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/core.py +0 -0
  508. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/hint/__init__.py +0 -0
  509. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/hint/file.py +0 -0
  510. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/hint/git.py +0 -0
  511. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/hint/search.py +0 -0
  512. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/router.py +0 -0
  513. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/bash/safety.py +0 -0
  514. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/checkpoint.py +0 -0
  515. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/clarify.py +0 -0
  516. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/compact.py +0 -0
  517. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/document.py +0 -0
  518. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/__init__.py +0 -0
  519. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/manage.py +0 -0
  520. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/read.py +0 -0
  521. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/replace_resolve.py +0 -0
  522. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/state.py +0 -0
  523. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/file/types.py +0 -0
  524. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/lsp.py +0 -0
  525. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/__init__.py +0 -0
  526. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/core.py +0 -0
  527. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/hint/__init__.py +0 -0
  528. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/hint/file.py +0 -0
  529. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/hint/search.py +0 -0
  530. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/router.py +0 -0
  531. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/safety.py +0 -0
  532. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/powershell/sandbox.py +0 -0
  533. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/registry.py +0 -0
  534. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/retry.py +0 -0
  535. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/schedule_wakeup.py +0 -0
  536. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/service.py +0 -0
  537. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/shell/__init__.py +0 -0
  538. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/shell/hint/__init__.py +0 -0
  539. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/skills.py +0 -0
  540. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/task_status.py +0 -0
  541. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/task_tracker.py +0 -0
  542. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/todo.py +0 -0
  543. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/web/__init__.py +0 -0
  544. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/web/content.py +0 -0
  545. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/web/fetch.py +0 -0
  546. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/web/mcp.py +0 -0
  547. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/web/search.py +0 -0
  548. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/tools/workflow.py +0 -0
  549. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/__init__.py +0 -0
  550. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/frontend.py +0 -0
  551. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/__init__.py +0 -0
  552. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/adapter.py +0 -0
  553. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/bootstrap.py +0 -0
  554. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/diff_review.py +0 -0
  555. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/frontend.py +0 -0
  556. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/run_manager.py +0 -0
  557. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/server.py +0 -0
  558. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/__init__.py +0 -0
  559. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/consumer.py +0 -0
  560. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/__init__.py +0 -0
  561. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/diff.py +0 -0
  562. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/integrations.py +0 -0
  563. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/sessions.py +0 -0
  564. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/session/method/terminal.py +0 -0
  565. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/gateway/terminal.py +0 -0
  566. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/__init__.py +0 -0
  567. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/agent_display.py +0 -0
  568. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/ansi_marker.py +0 -0
  569. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/browse.py +0 -0
  570. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/capture.py +0 -0
  571. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/console/__init__.py +0 -0
  572. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/console/app.py +0 -0
  573. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/console/formatting.py +0 -0
  574. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/console/streaming.py +0 -0
  575. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/diff.py +0 -0
  576. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/display_policy.py +0 -0
  577. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/__init__.py +0 -0
  578. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/agent_placeholder.py +0 -0
  579. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/app.py +0 -0
  580. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/formatting.py +0 -0
  581. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes.py +0 -0
  582. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes_checkpoint.py +0 -0
  583. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes_clarify.py +0 -0
  584. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes_permission.py +0 -0
  585. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes_startup.py +0 -0
  586. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/nodes_status.py +0 -0
  587. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/state.py +0 -0
  588. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/status.py +0 -0
  589. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/stream.py +0 -0
  590. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/dock/todo.py +0 -0
  591. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/events/__init__.py +0 -0
  592. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/events/consumers.py +0 -0
  593. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/events/schema.py +0 -0
  594. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/manage_display.py +0 -0
  595. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/tool_display.py +0 -0
  596. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/output/tree.py +0 -0
  597. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/__init__.py +0 -0
  598. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/commands.py +0 -0
  599. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/requests.py +0 -0
  600. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/schema.py +0 -0
  601. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/transcript.py +0 -0
  602. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/v2/__init__.py +0 -0
  603. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/v2/envelope.py +0 -0
  604. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/v2/methods.py +0 -0
  605. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/v2/snapshot.py +0 -0
  606. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/protocol/v2/threads.py +0 -0
  607. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/session.py +0 -0
  608. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/__init__.py +0 -0
  609. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/attachment_tokens.py +0 -0
  610. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/clipboard_image.py +0 -0
  611. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/clipboard_text.py +0 -0
  612. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/code_ide.py +0 -0
  613. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/file_picker.py +0 -0
  614. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/tools/skill_picker.py +0 -0
  615. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/ui/transcript.py +0 -0
  616. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/auto_advance.py +0 -0
  617. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/context.py +0 -0
  618. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/dag.py +0 -0
  619. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/reconcile.py +0 -0
  620. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/route.py +0 -0
  621. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/runtime.py +0 -0
  622. {voidx-3.7.2 → voidx-3.7.4}/src/voidx/workflow/types.py +0 -0
  623. {voidx-3.7.2 → voidx-3.7.4}/src/voidx.egg-info/dependency_links.txt +0 -0
  624. {voidx-3.7.2 → voidx-3.7.4}/src/voidx.egg-info/entry_points.txt +0 -0
  625. {voidx-3.7.2 → voidx-3.7.4}/src/voidx.egg-info/requires.txt +0 -0
  626. {voidx-3.7.2 → voidx-3.7.4}/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.7.2
3
+ Version: 3.7.4
4
4
  Summary: A coding agent that quantifies everything and solves with tools, not fuzzy prompts.
5
5
  Author: chikhamx
6
6
  License: MIT
@@ -19,6 +19,7 @@ from voidx.agent.task_state import TaskState, TodoRunState
19
19
  from voidx.config import Config, ModelConfig
20
20
  from voidx.agent.graph.compaction_coordinator import CompactionResult, PreflightCompactionResult
21
21
  from voidx.llm.compaction import CompactionSelection, SUMMARY_TEMPLATE
22
+ from voidx.llm.usage import estimate_context_tokens
22
23
  from voidx.llm.message_markers import is_guidance_message
23
24
  from voidx.memory.context_frames import load_context_frames
24
25
  from voidx.memory.session import MessageRow, create_session, delete_session, save_message
@@ -181,6 +182,7 @@ async def test_call_llm_updates_usage_stats_across_turn_control_calls(tmp_path,
181
182
  "messages": [HumanMessage(content="hi")],
182
183
  "step_count": 0,
183
184
  "persona": "voidx",
185
+ "turn_state": "running",
184
186
  })
185
187
 
186
188
  assert result["step_count"] == 1
@@ -188,11 +190,38 @@ async def test_call_llm_updates_usage_stats_across_turn_control_calls(tmp_path,
188
190
  assert graph.model.calls == 2
189
191
  assert graph._usage_stats.last_input_tokens == 2
190
192
  assert graph._usage_stats.last_output_tokens == 1
193
+ assert graph._usage_stats.context_tokens == 2
191
194
  assert graph._usage_stats.total_input_tokens == 9
192
195
  assert graph._usage_stats.total_output_tokens == 4
193
196
  assert graph._usage_stats.total_calls == 2
194
197
 
195
198
 
199
+ @pytest.mark.asyncio
200
+ async def test_call_llm_fallback_context_estimate_includes_tool_schema(tmp_path, monkeypatch):
201
+ import voidx.agent.graph.core.llm as graph_module
202
+
203
+ monkeypatch.setattr(graph_module, "StreamingRenderer", FakeRenderer)
204
+
205
+ graph = VoidXGraph(
206
+ Config(
207
+ model=ModelConfig(provider="openai", model="gpt-4o"),
208
+ workspace=str(tmp_path),
209
+ ),
210
+ api_key=None,
211
+ )
212
+ graph.model = FakeStreamingModel()
213
+
214
+ await graph._call_llm({
215
+ "messages": [HumanMessage(content="hi")],
216
+ "step_count": 0,
217
+ "persona": "voidx",
218
+ "turn_state": "running",
219
+ })
220
+
221
+ messages_only = estimate_context_tokens(graph.model.messages, graph.config.model.model)
222
+ assert graph._usage_stats.context_tokens > messages_only
223
+
224
+
196
225
  @pytest.mark.asyncio
197
226
  async def test_call_llm_persists_context_frame_for_session(tmp_path, monkeypatch):
198
227
  import voidx.agent.graph.core.llm as graph_module
@@ -0,0 +1,12 @@
1
+ """Structure tests for the call_llm refactor."""
2
+
3
+ import importlib
4
+
5
+
6
+ def test_call_llm_helpers_live_in_core_modules():
7
+ for module_name in (
8
+ "voidx.agent.graph.core.loop",
9
+ "voidx.agent.graph.core.turn",
10
+ "voidx.agent.graph.core.context",
11
+ ):
12
+ assert importlib.import_module(module_name)
@@ -145,7 +145,6 @@ def test_permission_decision_splits_readonly_and_implement_agents():
145
145
  @pytest.mark.asyncio
146
146
  async def test_graph_authorization_auto_allows_readonly_agent(tmp_path):
147
147
  graph = _graph(tmp_path)
148
- graph._permission.approval_policy = "untrusted"
149
148
  approved, denied = await graph._authorize_tool_calls(
150
149
  [{
151
150
  "name": "agent",
@@ -217,7 +216,7 @@ async def test_graph_authorization_respects_session_deny_for_safe_bash(tmp_path)
217
216
  @pytest.mark.asyncio
218
217
  async def test_graph_authorization_never_approves_mixed_blocked_batch(tmp_path):
219
218
  graph = _graph(tmp_path)
220
- graph._permission.permission_preset = "safe"
219
+ graph._permission.permission_mode = "safe"
221
220
  asked: list[list[object]] = []
222
221
 
223
222
  async def approve(tool_calls):
@@ -242,10 +241,59 @@ async def test_graph_authorization_never_approves_mixed_blocked_batch(tmp_path):
242
241
  assert [item.tool_call["id"] for item in asked[1]] == ["ask"]
243
242
 
244
243
 
244
+ @pytest.mark.asyncio
245
+ async def test_full_access_workflow_gate_advisory_allows_without_approval(tmp_path):
246
+ graph = _graph(tmp_path)
247
+ graph._permission.set_permission_mode("full_access")
248
+
249
+ async def fail_if_asked(_tool_calls):
250
+ pytest.fail("workflow gate should not prompt for approval under full_access")
251
+
252
+ graph._ask_tool_permission = fail_if_asked
253
+
254
+ approved, denied = await graph._authorize_tool_calls(
255
+ [{"name": "write", "args": {"file_path": "app.py", "content": "x"}, "id": "call_1"}],
256
+ plan_mode=False,
257
+ session_id="test",
258
+ workflow_runs=[
259
+ WorkflowRunState(name="brainstorm", status=WorkflowRunStatus.ACTIVE),
260
+ ],
261
+ )
262
+
263
+ assert [call["id"] for call in approved] == ["call_1"]
264
+ assert denied == []
265
+
266
+
267
+ @pytest.mark.asyncio
268
+ async def test_safe_mode_workflow_gate_still_prompts(tmp_path):
269
+ """Under safe mode, workflow gate advisory does not bypass permission approval."""
270
+ graph = _graph(tmp_path)
271
+ graph._permission.set_permission_mode("safe")
272
+ asked: list = []
273
+
274
+ async def approve(tool_calls):
275
+ asked.extend(tool_calls)
276
+ return "y"
277
+
278
+ graph._ask_tool_permission = approve
279
+
280
+ approved, denied = await graph._authorize_tool_calls(
281
+ [{"name": "write", "args": {"file_path": "app.py", "content": "x"}, "id": "call_1"}],
282
+ plan_mode=False,
283
+ session_id="test",
284
+ workflow_runs=[
285
+ WorkflowRunState(name="brainstorm", status=WorkflowRunStatus.ACTIVE),
286
+ ],
287
+ )
288
+
289
+ assert [call["id"] for call in approved] == ["call_1"]
290
+ assert denied == []
291
+ assert len(asked) > 0
292
+
293
+
245
294
  @pytest.mark.asyncio
246
295
  async def test_graph_authorization_asks_for_write_by_active_workflow_gate(tmp_path):
247
296
  graph = _graph(tmp_path)
248
- graph._permission.approval_policy = "on-request"
249
297
  asked: list[list[dict]] = []
250
298
 
251
299
  async def approve(tool_calls):
@@ -271,7 +319,13 @@ async def test_graph_authorization_asks_for_write_by_active_workflow_gate(tmp_pa
271
319
  @pytest.mark.asyncio
272
320
  async def test_graph_authorization_uses_current_workflow_gate_only(tmp_path):
273
321
  graph = _graph(tmp_path)
274
- graph._permission.approval_policy = "on-request"
322
+ asked: list[list[dict]] = []
323
+
324
+ async def approve(tool_calls):
325
+ asked.append(tool_calls)
326
+ return "y"
327
+
328
+ graph._ask_tool_permission = approve
275
329
 
276
330
  approved, denied = await graph._authorize_tool_calls(
277
331
  [{
@@ -288,14 +342,15 @@ async def test_graph_authorization_uses_current_workflow_gate_only(tmp_path):
288
342
  ],
289
343
  )
290
344
 
345
+ assert [[call["id"] for call in _asked_tool_calls(batch)] for batch in asked] == [["call_1"]]
291
346
  assert [call["id"] for call in approved] == ["call_1"]
292
347
  assert denied == []
293
348
 
294
349
 
295
350
  @pytest.mark.asyncio
296
- async def test_graph_authorization_allows_plan_gate_doc_paths_only(tmp_path):
351
+ async def test_graph_authorization_plan_gate_no_longer_bypasses_doc_paths(tmp_path):
352
+ """allowed_paths bypass removed: both docs and src edits go through normal permission."""
297
353
  graph = _graph(tmp_path)
298
- graph._permission.approval_policy = "on-request"
299
354
  asked: list[list[dict]] = []
300
355
 
301
356
  async def deny(tool_calls):
@@ -325,16 +380,22 @@ async def test_graph_authorization_allows_plan_gate_doc_paths_only(tmp_path):
325
380
  ],
326
381
  )
327
382
 
328
- assert [call["id"] for call in approved] == ["call_docs"]
329
- assert [[call["id"] for call in _asked_tool_calls(batch)] for batch in asked] == [["call_src"]]
330
- assert [call["id"] for call, _reason in denied] == ["call_src"]
331
- assert denied[0][1] == "User denied: replace"
383
+ assert approved == []
384
+ assert [call["id"] for call, _reason in denied] == ["call_docs", "call_src"]
385
+ assert all(reason == "User denied: replace" for _tc, reason in denied)
332
386
 
333
387
 
334
388
  @pytest.mark.asyncio
335
- async def test_graph_authorization_allowed_paths_match_nested_docs(tmp_path):
389
+ async def test_graph_authorization_nested_docs_go_through_normal_permission(tmp_path):
390
+ """allowed_paths bypass removed: nested docs edits go through normal permission."""
336
391
  graph = _graph(tmp_path)
337
- graph._permission.approval_policy = "on-request"
392
+ asked: list[list[dict]] = []
393
+
394
+ async def approve(tool_calls):
395
+ asked.append(tool_calls)
396
+ return "y"
397
+
398
+ graph._ask_tool_permission = approve
338
399
 
339
400
  approved, denied = await graph._authorize_tool_calls(
340
401
  [{
@@ -350,6 +411,7 @@ async def test_graph_authorization_allowed_paths_match_nested_docs(tmp_path):
350
411
  ],
351
412
  )
352
413
 
414
+ assert [[call["id"] for call in _asked_tool_calls(batch)] for batch in asked] == [["call_nested_docs"]]
353
415
  assert [call["id"] for call in approved] == ["call_nested_docs"]
354
416
  assert denied == []
355
417
 
@@ -357,8 +419,7 @@ async def test_graph_authorization_allowed_paths_match_nested_docs(tmp_path):
357
419
  @pytest.mark.asyncio
358
420
  async def test_graph_authorization_does_not_block_tools_outside_active_workflow_node_allowlist(tmp_path):
359
421
  graph = _graph(tmp_path)
360
- graph._permission.approval_policy = "on-request"
361
-
422
+
362
423
  approved, denied = await graph._authorize_tool_calls(
363
424
  [{
364
425
  "name": "todo",
@@ -380,7 +441,6 @@ async def test_graph_authorization_does_not_block_tools_outside_active_workflow_
380
441
  @pytest.mark.asyncio
381
442
  async def test_graph_authorization_asks_for_workflow_gate_tools_instead_of_denying(tmp_path):
382
443
  graph = _graph(tmp_path)
383
- graph._permission.approval_policy = "on-request"
384
444
  asked: list[list[dict]] = []
385
445
 
386
446
  async def approve(tool_calls):
@@ -411,7 +471,6 @@ async def test_graph_authorization_asks_for_workflow_gate_tools_instead_of_denyi
411
471
  @pytest.mark.asyncio
412
472
  async def test_graph_authorization_asks_for_persona_blocked_write(tmp_path):
413
473
  graph = _graph(tmp_path)
414
- graph._permission.approval_policy = "on-request"
415
474
  asked: list[list[dict]] = []
416
475
 
417
476
  async def approve(tool_calls):
@@ -434,7 +493,6 @@ async def test_graph_authorization_asks_for_persona_blocked_write(tmp_path):
434
493
  @pytest.mark.asyncio
435
494
  async def test_permission_result_uses_transient_output(tmp_path):
436
495
  graph = _graph(tmp_path)
437
- graph._permission.approval_policy = "untrusted"
438
496
  test_dock = BottomInputDock()
439
497
  set_dock(test_dock)
440
498
  test_dock.begin_capture()
@@ -520,9 +578,7 @@ async def test_permission_prompt_uses_dock_details_when_events_are_active(tmp_pa
520
578
  @pytest.mark.asyncio
521
579
  async def test_read_only_permission_prompt_limits_choices_to_once(tmp_path):
522
580
  graph = _graph(tmp_path)
523
- graph._permission.sandbox_mode = "read-only"
524
- graph._permission.permission_mode = "read-only"
525
- graph._permission.approval_policy = "untrusted"
581
+ graph._permission.set_permission_mode("read_only")
526
582
  captured_choices = None
527
583
 
528
584
  class FakeApp:
@@ -550,8 +606,7 @@ async def test_read_only_permission_prompt_limits_choices_to_once(tmp_path):
550
606
  @pytest.mark.asyncio
551
607
  async def test_permission_prompt_details_include_risk_and_scopes(tmp_path):
552
608
  graph = _graph(tmp_path)
553
- graph._permission.permission_mode = "default"
554
- graph._permission.approval_policy = "untrusted"
609
+ graph._permission.set_permission_mode("safe")
555
610
  received_details = None
556
611
 
557
612
  class FakeApp:
@@ -589,10 +644,9 @@ async def test_permission_prompt_details_include_risk_and_scopes(tmp_path):
589
644
  @pytest.mark.asyncio
590
645
  async def test_graph_authorization_attaches_approved_risk_token_to_approved_shell_call(tmp_path):
591
646
  graph = _graph(tmp_path)
592
- graph._permission.sandbox_mode = "read-only"
593
- graph._permission.permission_mode = "read-only"
594
- graph._permission.approval_policy = "untrusted"
595
-
647
+ graph._permission.set_permission_mode("read_only")
648
+ graph._permission.set_permission_mode("read_only")
649
+
596
650
  async def approve(_tool_calls):
597
651
  return "y"
598
652
 
@@ -618,8 +672,7 @@ async def test_graph_authorization_attaches_approved_risk_token_to_approved_shel
618
672
  @pytest.mark.asyncio
619
673
  async def test_blocked_permission_prompt_only_acknowledges_and_denies_execution(tmp_path):
620
674
  graph = _graph(tmp_path)
621
- graph._permission.permission_mode = "default"
622
- graph._permission.approval_policy = "untrusted"
675
+ graph._permission.set_permission_mode("safe")
623
676
  captured_choices = None
624
677
  captured_details = None
625
678
 
@@ -649,9 +702,8 @@ async def test_blocked_permission_prompt_only_acknowledges_and_denies_execution(
649
702
  @pytest.mark.asyncio
650
703
  async def test_blocked_permission_prompt_cannot_be_approved_with_yes(tmp_path):
651
704
  graph = _graph(tmp_path)
652
- graph._permission.permission_mode = "default"
653
- graph._permission.approval_policy = "untrusted"
654
-
705
+ graph._permission.set_permission_mode("safe")
706
+
655
707
  class FakeApp:
656
708
  async def ask_choice(self, _prompt, _choices, details=None):
657
709
  return "y"
@@ -323,7 +323,6 @@ async def test_subagent_runner_authorizes_with_child_interaction_mode(tmp_path,
323
323
  @pytest.mark.asyncio
324
324
  async def test_graph_authorization_does_not_treat_goal_as_read_only_mode(tmp_path):
325
325
  graph = _graph(tmp_path)
326
- graph._permission.approval_policy = "on-request"
327
326
  asked: list[list[dict]] = []
328
327
 
329
328
  async def approve(tool_calls):
@@ -135,7 +135,7 @@ def _tree_nodes(root):
135
135
  @pytest.mark.asyncio
136
136
  async def test_graph_on_request_auto_approves_need_ask_tools(tmp_path):
137
137
  graph = _graph(tmp_path)
138
- graph._permission.permission_preset = "full_access"
138
+ graph._permission.permission_mode = "full_access"
139
139
 
140
140
  approved, denied = await graph._authorize_tool_calls(
141
141
  [{"name": "write", "args": {"file_path": "app.py", "op": "append", "new_string": "x"}, "id": "call_1"}],
@@ -149,10 +149,30 @@ async def test_graph_on_request_auto_approves_need_ask_tools(tmp_path):
149
149
 
150
150
 
151
151
  @pytest.mark.asyncio
152
- async def test_graph_on_failure_asks_unsafe_bash_before_prompt(tmp_path):
152
+ async def test_full_access_auto_approves_write_without_implement_persona(tmp_path):
153
153
  graph = _graph(tmp_path)
154
- graph._permission.approval_policy = "on-failure"
154
+ graph._permission.permission_mode = "full_access"
155
+
156
+ async def fail_if_asked(_tool_calls):
157
+ pytest.fail("full_access should not prompt for workspace edit")
158
+
159
+ graph._ask_tool_permission = fail_if_asked
160
+
161
+ approved, denied = await graph._authorize_tool_calls(
162
+ [{"name": "replace", "args": {"file_path": "app.py", "bounds": [{"line_no": 1, "anchor": "x"}], "new_string": "y"}, "id": "call_1"}],
163
+ runtime_persona="coordinate",
164
+ plan_mode=False,
165
+ session_id="test",
166
+ )
167
+
168
+ assert [tc["name"] for tc in approved] == ["replace"]
169
+ assert denied == []
170
+
155
171
 
172
+ @pytest.mark.asyncio
173
+ async def test_graph_on_failure_asks_unsafe_bash_before_prompt(tmp_path):
174
+ graph = _graph(tmp_path)
175
+
156
176
  asked: list[dict] = []
157
177
 
158
178
  async def ask(tool_calls):
@@ -102,6 +102,7 @@ async def test_regular_tool_call_resets_missing_turn_count(tmp_path, monkeypatch
102
102
  "messages": [HumanMessage(content="hello")],
103
103
  "step_count": 0,
104
104
  "persona": "coordinate",
105
+ "turn_state": "running",
105
106
  })
106
107
  # The regular tool call should route to execute, not end
107
108
  assert result1["messages"][0].tool_calls
@@ -113,6 +114,7 @@ async def test_regular_tool_call_resets_missing_turn_count(tmp_path, monkeypatch
113
114
  "messages": [HumanMessage(content="hello"), *result1["messages"]],
114
115
  "step_count": 1,
115
116
  "persona": "coordinate",
117
+ "turn_state": result1.get("turn_state", "running"),
116
118
  })
117
119
  assert result2["messages"][0].content == "Final answer."
118
120
  assert not result2["messages"][0].tool_calls
@@ -170,6 +172,7 @@ async def test_turn_call_never_emits_permission_or_execution_events(tmp_path, mo
170
172
  "messages": [HumanMessage(content="hello")],
171
173
  "step_count": 0,
172
174
  "persona": "coordinate",
175
+ "turn_state": "running",
173
176
  })
174
177
 
175
178
  # Check that no tool permission or tool execution events were emitted
@@ -195,6 +198,7 @@ async def test_successful_barrier_emits_one_committed_stream(tmp_path, monkeypat
195
198
  "messages": [HumanMessage(content="hello")],
196
199
  "step_count": 0,
197
200
  "persona": "coordinate",
201
+ "turn_state": "running",
198
202
  })
199
203
 
200
204
  msgs = result["messages"]
@@ -221,6 +225,7 @@ async def test_regular_tool_continues_after_turn_prompt(tmp_path, monkeypatch):
221
225
  "messages": [HumanMessage(content="hello")],
222
226
  "step_count": 0,
223
227
  "persona": "coordinate",
228
+ "turn_state": "running",
224
229
  })
225
230
 
226
231
  assert result["messages"][0].tool_calls
@@ -1,7 +1,7 @@
1
1
  """Integration tests for turn control inside _call_llm."""
2
2
 
3
3
  import pytest
4
- from langchain_core.messages import AIMessage, AIMessageChunk, HumanMessage
4
+ from langchain_core.messages import AIMessage, AIMessageChunk, HumanMessage, ToolMessage
5
5
 
6
6
  from voidx.agent.graph import VoidXGraph
7
7
  from voidx.agent.graph.turn_control import TURN_TOOL_DEFINITION
@@ -291,11 +291,11 @@ async def test_regular_tool_call_routes_to_execute(tmp_path, monkeypatch):
291
291
  assert msgs[0].tool_calls[0]["name"] == "read"
292
292
 
293
293
 
294
- # ── Test 4: first plain-text triggers first completion prompt ───────────────
294
+ # ── Test 4: first plain-text answer can complete immediately ────────────────
295
295
 
296
296
 
297
297
  @pytest.mark.asyncio
298
- async def test_first_plain_text_triggers_first_prompt_then_turn(tmp_path, monkeypatch):
298
+ async def test_first_plain_text_commits_without_start_prompt(tmp_path, monkeypatch):
299
299
  model = ScriptedStreamingModel([
300
300
  [_text_chunk("Provisional answer.")],
301
301
  [_turn_call_chunk()],
@@ -311,11 +311,13 @@ async def test_first_plain_text_triggers_first_prompt_then_turn(tmp_path, monkey
311
311
  msgs = result["messages"]
312
312
  assert msgs[0].content == "Provisional answer."
313
313
  assert not msgs[0].tool_calls
314
- assert model.call_index == 2
314
+ assert result["turn_state"] == "committed"
315
+ assert model.call_index == 1
316
+ assert len(model.received_messages) == 1
315
317
 
316
318
 
317
319
  @pytest.mark.asyncio
318
- async def test_missing_turn_reprompt_keeps_full_tool_set_and_appends_turn_prompt(tmp_path, monkeypatch):
320
+ async def test_initial_plain_text_keeps_full_tool_set_without_reprompt(tmp_path, monkeypatch):
319
321
  model = ScriptedStreamingModel([
320
322
  [_text_chunk("Provisional answer.")],
321
323
  [_turn_call_chunk()],
@@ -329,12 +331,8 @@ async def test_missing_turn_reprompt_keeps_full_tool_set_and_appends_turn_prompt
329
331
  })
330
332
 
331
333
  assert result["messages"][0].content == "Provisional answer."
332
- assert model.call_index == 2
333
- turn_prompt_messages = model.received_messages[1]
334
- assert any(
335
- isinstance(msg, HumanMessage) and "operation='start'" in str(msg.content)
336
- for msg in turn_prompt_messages
337
- )
334
+ assert model.call_index == 1
335
+ assert len(model.received_messages) == 1
338
336
  tool_names = [tool["function"]["name"] for tool in model.bound_tools]
339
337
  assert "turn" in tool_names
340
338
  assert "read" in tool_names
@@ -352,6 +350,7 @@ async def test_regular_tool_after_turn_prompt_continues_without_committing_text(
352
350
  "messages": [HumanMessage(content="read x.py")],
353
351
  "step_count": 0,
354
352
  "persona": "coordinate",
353
+ "turn_state": "running",
355
354
  })
356
355
 
357
356
  assert result["messages"][0].tool_calls
@@ -384,7 +383,7 @@ async def test_decision_only_turn_with_text_is_rejected_before_stop(tmp_path, mo
384
383
 
385
384
 
386
385
  @pytest.mark.asyncio
387
- async def test_plain_text_prompts_start_then_stop_without_ui_leak(tmp_path, monkeypatch):
386
+ async def test_initial_plain_text_commits_without_hidden_ui_followups(tmp_path, monkeypatch):
388
387
  RecordingRenderer.reset()
389
388
  model = ScriptedStreamingModel([
390
389
  [_text_chunk("First provisional.")],
@@ -400,10 +399,12 @@ async def test_plain_text_prompts_start_then_stop_without_ui_leak(tmp_path, monk
400
399
  })
401
400
 
402
401
  visible_text = "".join(RecordingRenderer.visible_text)
403
- assert result["messages"][0].content == "Second provisional."
402
+ assert result["messages"][0].content == "First provisional."
404
403
  assert "First provisional." in visible_text
404
+ assert "Second provisional." not in visible_text
405
405
  assert RecordingRenderer.headless_values[0] is False
406
- assert all(RecordingRenderer.headless_values[1:])
406
+ assert RecordingRenderer.headless_values == [False]
407
+ assert model.call_index == 1
407
408
 
408
409
 
409
410
  # ── Test 6: second plain-text fallback keeps latest response ────────────────
@@ -422,6 +423,7 @@ async def test_invalid_turn_continue_recovers_with_regular_tool(tmp_path, monkey
422
423
  "messages": [HumanMessage(content="hello")],
423
424
  "step_count": 0,
424
425
  "persona": "coordinate",
426
+ "turn_state": "running",
425
427
  })
426
428
 
427
429
  assert result["messages"][0].tool_calls
@@ -512,8 +514,8 @@ async def test_turn_with_non_empty_args_is_rejected(tmp_path, monkeypatch):
512
514
  }],
513
515
  )
514
516
  model = ScriptedStreamingModel([
515
- [_text_chunk("answer")],
516
517
  [malformed_turn],
518
+ [_text_chunk("answer")],
517
519
  [_turn_call_chunk()],
518
520
  ])
519
521
  graph = _make_graph(tmp_path, model, monkeypatch)
@@ -623,7 +625,19 @@ async def test_start_prompt_injected_once_then_stop_prompt(tmp_path, monkeypatch
623
625
  graph = _make_graph(tmp_path, model, monkeypatch)
624
626
 
625
627
  result = await graph._call_llm({
626
- "messages": [HumanMessage(content="hello")],
628
+ "messages": [
629
+ HumanMessage(content="hello"),
630
+ AIMessage(
631
+ content="",
632
+ tool_calls=[{
633
+ "name": "read",
634
+ "args": {"file_path": "x.py"},
635
+ "id": "tc-prior",
636
+ "type": "tool_call",
637
+ }],
638
+ ),
639
+ ToolMessage(content="ok", tool_call_id="tc-prior", name="read"),
640
+ ],
627
641
  "step_count": 0,
628
642
  "persona": "coordinate",
629
643
  "turn_state": "initial",
@@ -293,7 +293,6 @@ async def test_multiple_barriers_apply_patches_in_order(tmp_path):
293
293
  @pytest.mark.asyncio
294
294
  async def test_workflow_transaction_reauthorizes_following_write(tmp_path):
295
295
  graph = _graph(tmp_path)
296
- graph._permission.approval_policy = "on-request"
297
296
  invalidations = 0
298
297
 
299
298
  class FakeApp:
@@ -33,6 +33,23 @@ async def test_fixed_loop_fires_after_interval(tmp_path) -> None:
33
33
  assert host.turns[:1] == ["tick"]
34
34
 
35
35
 
36
+ @pytest.mark.asyncio
37
+ async def test_first_fire_is_immediate(tmp_path) -> None:
38
+ host = FakeHost()
39
+ idle = asyncio.Event()
40
+ idle.set()
41
+ manager = LoopManager(host, idle_event=idle, workspace=str(tmp_path))
42
+
43
+ manager.start(PromptSource.from_raw("tick"), 60)
44
+ for _ in range(20):
45
+ if host.turns:
46
+ break
47
+ await asyncio.sleep(0.005)
48
+ await manager.cleanup()
49
+
50
+ assert host.turns[:1] == ["tick"]
51
+
52
+
36
53
  @pytest.mark.asyncio
37
54
  async def test_stop_cancels_active_loop_before_fire(tmp_path) -> None:
38
55
  host = FakeHost()
@@ -56,12 +73,13 @@ async def test_dynamic_wakeup_interrupts_default_sleep(tmp_path) -> None:
56
73
  manager = LoopManager(host, idle_event=idle, workspace=str(tmp_path), default_interval_seconds=10)
57
74
 
58
75
  manager.start(PromptSource.from_raw("tick"), None)
59
- await asyncio.sleep(0)
76
+ await asyncio.sleep(0.02)
77
+ assert host.turns == ["tick"]
60
78
  manager.schedule_wakeup(0.01)
61
79
  await asyncio.sleep(0.04)
62
80
  await manager.cleanup()
63
81
 
64
- assert host.turns == ["tick"]
82
+ assert host.turns == ["tick", "tick"]
65
83
 
66
84
 
67
85
 
@@ -15,7 +15,7 @@ from voidx.config import (
15
15
  McpServerConfig,
16
16
  ModelConfig,
17
17
  ParallelSubagentsConfig,
18
- PermissionPreset,
18
+ PermissionMode,
19
19
  Settings,
20
20
  UserProfile,
21
21
  )
@@ -565,7 +565,7 @@ async def test_usage_dispatch_reads_usage_stats():
565
565
 
566
566
 
567
567
  @pytest.mark.asyncio
568
- async def test_permission_preset_dispatch_updates_service_and_settings(tmp_path):
568
+ async def test_permission_mode_dispatch_updates_service_and_settings(tmp_path):
569
569
  settings = Settings(str(tmp_path))
570
570
  permission = PermissionService()
571
571
  graph = SimpleNamespace(
@@ -574,13 +574,13 @@ async def test_permission_preset_dispatch_updates_service_and_settings(tmp_path)
574
574
  _app=None,
575
575
  )
576
576
 
577
- assert await SlashHandler(graph).dispatch("/permission-preset full_access") is True
577
+ assert await SlashHandler(graph).dispatch("/permission full_access") is True
578
578
 
579
579
  reloaded = await Settings.create(str(tmp_path))
580
580
  cfg = await reloaded.build_config()
581
- assert permission.permission_preset == "full_access"
582
- assert cfg.permission_preset == PermissionPreset.FULL_ACCESS
583
- assert reloaded.get_permission_preset() == PermissionPreset.FULL_ACCESS
581
+ assert permission.permission_mode == "full_access"
582
+ assert cfg.permission_mode == PermissionMode.FULL_ACCESS
583
+ assert reloaded.get_permission_mode() == PermissionMode.FULL_ACCESS
584
584
  assert await SlashHandler(graph).dispatch("/permission-mode full-access") is False
585
585
  assert await SlashHandler(graph).dispatch("/approval never") is False
586
586
 
@@ -15,7 +15,7 @@ from voidx.config import (
15
15
  McpServerConfig,
16
16
  ModelConfig,
17
17
  ParallelSubagentsConfig,
18
- PermissionPreset,
18
+ PermissionMode,
19
19
  Settings,
20
20
  UserProfile,
21
21
  )
@@ -329,7 +329,7 @@ def test_model_ctx_command_is_in_palette():
329
329
  assert ("/model ctx", "Set context window size") in COMMANDS
330
330
 
331
331
  @pytest.mark.asyncio
332
- async def test_permission_preset_without_args_uses_prompt_app_choice(tmp_path):
332
+ async def test_permission_mode_without_args_uses_prompt_app_choice(tmp_path):
333
333
  settings = Settings(str(tmp_path))
334
334
  permission = PermissionService()
335
335
  app = FakeChoiceApp(result="project_trusted")
@@ -339,11 +339,11 @@ async def test_permission_preset_without_args_uses_prompt_app_choice(tmp_path):
339
339
  _app=app,
340
340
  )
341
341
 
342
- assert await SlashHandler(graph).dispatch("/permission-preset") is True
342
+ assert await SlashHandler(graph).dispatch("/permission") is True
343
343
 
344
- assert app.prompt == "Permission preset"
345
- assert permission.permission_preset == "project_trusted"
346
- assert settings.get_permission_preset() == PermissionPreset.PROJECT_TRUSTED
344
+ assert app.prompt == "Permission mode"
345
+ assert permission.permission_mode == "project_trusted"
346
+ assert settings.get_permission_mode() == PermissionMode.PROJECT_TRUSTED
347
347
 
348
348
 
349
349
  @pytest.mark.asyncio