feat(sdm): inject structural dependency mapping tags across codebase
Adds [C: caller] tags to functions/methods and [M: mutation] / [U: usage] tags to class variables based on cross-module call analysis.
This commit is contained in:
@@ -102,7 +102,7 @@ class BaseSimulation:
|
||||
|
||||
def get_value(self, tag: str) -> Any:
|
||||
"""
|
||||
[C: simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
|
||||
[C: simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
|
||||
"""
|
||||
return self.client.get_value(tag)
|
||||
|
||||
@@ -128,6 +128,7 @@ class BaseSimulation:
|
||||
|
||||
def run_sim(sim_class: type) -> None:
|
||||
"""
|
||||
|
||||
Helper to run a simulation class standalone.
|
||||
[C: simulation/sim_context.py:module, simulation/sim_execution.py:module, simulation/sim_tools.py:module]
|
||||
"""
|
||||
|
||||
@@ -60,6 +60,7 @@ class UserSimAgent:
|
||||
def generate_response(self, conversation_history: list[dict]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Generates a human-like response based on the conversation history.
|
||||
conversation_history: list of dicts with 'role' and 'content'
|
||||
[C: simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async]
|
||||
@@ -79,6 +80,7 @@ class UserSimAgent:
|
||||
def perform_action_with_delay(self, action_func: Callable, *args: Any, **kwargs: Any) -> Any:
|
||||
"""
|
||||
|
||||
|
||||
Executes an action with a human-like delay if enabled.
|
||||
[C: tests/test_user_agent.py:test_perform_action_with_delay]
|
||||
"""
|
||||
|
||||
+19
-7
@@ -61,7 +61,10 @@ def resolve_paths(base_dir: Path, entry: str) -> list[Path]:
|
||||
return sorted(filtered)
|
||||
|
||||
def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
|
||||
"""Groups FileItem objects by their relative directory path."""
|
||||
"""
|
||||
Groups FileItem objects by their relative directory path.
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_context_composition_phase3.py:test_group_files_by_dir]
|
||||
"""
|
||||
grouped = {}
|
||||
for f in files:
|
||||
path_str = f.path if hasattr(f, 'path') else str(f)
|
||||
@@ -76,7 +79,10 @@ def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
|
||||
return grouped
|
||||
|
||||
def compute_file_stats(abs_path: str) -> dict[str, int]:
|
||||
"""Computes lines and basic AST stats for a file."""
|
||||
"""
|
||||
Computes lines and basic AST stats for a file.
|
||||
[C: src/gui_2.py:App._stats_worker, tests/test_context_composition_phase3.py:test_compute_file_stats]
|
||||
"""
|
||||
stats = {"lines": 0, "ast_elements": 0}
|
||||
try:
|
||||
with open(abs_path, 'r', encoding='utf-8') as f:
|
||||
@@ -97,6 +103,7 @@ def build_discussion_section(history: list[Any]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Builds a markdown section for discussion history.
|
||||
Handles both legacy list[str] and new list[dict].
|
||||
"""
|
||||
@@ -133,6 +140,7 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Return a list of dicts describing each file, for use by ai_client when it
|
||||
wants to upload individual files rather than inline everything as markdown.
|
||||
|
||||
@@ -146,7 +154,7 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
||||
auto_aggregate : bool
|
||||
force_full : bool
|
||||
view_mode : str (summary, full, skeleton, outline, none)
|
||||
[C: src/app_controller.py:AppController._bg_task, src/orchestrator_pm.py:module, tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_tiered_context.py:test_build_file_items_with_tiers]
|
||||
[C: src/app_controller.py:AppController._bg_task, src/orchestrator_pm.py:module, tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_context_composition_phase6.py:test_view_mode_custom, tests/test_context_composition_phase6.py:test_view_mode_custom_empty_default_to_summary, tests/test_context_composition_phase6.py:test_view_mode_default_summary, tests/test_context_composition_phase6.py:test_view_mode_full, tests/test_context_composition_phase6.py:test_view_mode_none, tests/test_context_composition_phase6.py:test_view_mode_outline, tests/test_context_composition_phase6.py:test_view_mode_skeleton, tests/test_context_composition_phase6.py:test_view_mode_summary, tests/test_tiered_context.py:test_build_file_items_with_tiers, tests/test_tiered_context.py:test_build_files_section_with_dicts]
|
||||
"""
|
||||
with get_monitor().scope("build_file_items"):
|
||||
items: list[dict[str, Any]] = []
|
||||
@@ -245,8 +253,9 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
||||
def _build_files_section_from_items(file_items: list[dict[str, Any]]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Build the files markdown section from pre-read file items (avoids double I/O).
|
||||
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_ui_summary_only_removal.py:test_aggregate_from_items_respects_auto_aggregate]
|
||||
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_context_composition_phase6.py:test_files_section_rendering, tests/test_tiered_context.py:test_build_files_section_with_dicts, tests/test_ui_summary_only_removal.py:test_aggregate_from_items_respects_auto_aggregate]
|
||||
"""
|
||||
sections = []
|
||||
for item in file_items:
|
||||
@@ -323,6 +332,7 @@ def build_markdown_from_items(file_items: list[dict[str, Any]], screenshot_base_
|
||||
def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_dir: Path, screenshots: list[str], summary_only: bool = False, aggregation_strategy: str = "auto") -> str:
|
||||
"""
|
||||
|
||||
|
||||
Build markdown with only files + screenshots (no history). Used for stable caching.
|
||||
[C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_blacklist]
|
||||
"""
|
||||
@@ -331,6 +341,7 @@ def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_
|
||||
def build_discussion_text(history: list[str]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Build just the discussion history section text. Returns empty string if no history.
|
||||
[C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_includes_segregated_history]
|
||||
"""
|
||||
@@ -342,9 +353,10 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Tier 3 Context: Execution/Worker.
|
||||
Full content for focus_files and files with tier=3, summaries/skeletons for others.
|
||||
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_tiered_context.py:test_build_tier3_context_ast_skeleton, tests/test_tiered_context.py:test_build_tier3_context_exists, tests/test_tiered_context.py:test_tiered_context_by_tier_field]
|
||||
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_ast_masking_core.py:test_ast_masking_gencpp_samples, tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_tiered_context.py:test_build_tier3_context_ast_skeleton, tests/test_tiered_context.py:test_build_tier3_context_exists, tests/test_tiered_context.py:test_tiered_context_by_tier_field]
|
||||
"""
|
||||
with get_monitor().scope("build_tier3_context"):
|
||||
focus_set = set(focus_files)
|
||||
@@ -446,7 +458,7 @@ def build_markdown(base_dir: Path, files: list[str | dict[str, Any]], screenshot
|
||||
|
||||
def run(config: dict[str, Any], aggregation_strategy: str = "auto") -> tuple[str, Path, list[dict[str, Any]]]:
|
||||
"""
|
||||
[C: simulation/sim_base.py:run_sim, src/ai_client.py:_send_anthropic, src/ai_client.py:_send_deepseek, src/ai_client.py:_send_gemini, src/ai_client.py:_send_gemini_cli, src/ai_client.py:_send_minimax, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._start_track_logic, src/external_editor.py:_find_vscode_in_registry, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App.run, src/gui_2.py:main, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/project_manager.py:get_git_log, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
[C: simulation/sim_base.py:run_sim, src/ai_client.py:_send_anthropic, src/ai_client.py:_send_deepseek, src/ai_client.py:_send_gemini, src/ai_client.py:_send_gemini_cli, src/ai_client.py:_send_minimax, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._start_track_logic, src/external_editor.py:_find_vscode_in_registry, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App.run, src/gui_2.py:main, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
"""
|
||||
namespace = config.get("project", {}).get("name")
|
||||
if not namespace:
|
||||
@@ -472,7 +484,7 @@ def run(config: dict[str, Any], aggregation_strategy: str = "auto") -> tuple[str
|
||||
def main() -> None:
|
||||
# Load global config to find active project
|
||||
"""
|
||||
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, src/api_hooks.py:WebSocketServer._run_loop, src/gui_2.py:module, tests/mock_concurrent_mma.py:module, tests/mock_gemini_cli.py:module, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge.py:module, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_cli_tool_bridge_mapping.py:module, tests/test_discussion_takes.py:module, tests/test_external_editor_gui.py:module, tests/test_headless_service.py:TestHeadlessStartup.test_headless_flag_triggers_run, tests/test_headless_service.py:TestHeadlessStartup.test_normal_startup_calls_app_run, tests/test_mma_skeleton.py:module, tests/test_orchestrator_pm.py:module, tests/test_orchestrator_pm_history.py:module, tests/test_post_process.py:module, tests/test_presets.py:module, tests/test_project_serialization.py:module, tests/test_run_worker_lifecycle_abort.py:module, tests/test_symbol_lookup.py:module, tests/test_system_prompt_exposure.py:module, tests/test_theme_nerv_fx.py:module]
|
||||
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, src/ai_server.py:module, src/api_hooks.py:WebSocketServer._run_loop, src/gui_2.py:module, tests/mock_concurrent_mma.py:module, tests/mock_gemini_cli.py:module, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge.py:module, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_cli_tool_bridge_mapping.py:module, tests/test_discussion_takes.py:module, tests/test_external_editor_gui.py:module, tests/test_headless_service.py:TestHeadlessStartup.test_headless_flag_triggers_run, tests/test_headless_service.py:TestHeadlessStartup.test_normal_startup_calls_app_run, tests/test_mma_skeleton.py:module, tests/test_orchestrator_pm.py:module, tests/test_orchestrator_pm_history.py:module, tests/test_presets.py:module, tests/test_project_serialization.py:module, tests/test_run_worker_lifecycle_abort.py:module, tests/test_symbol_lookup.py:module, tests/test_system_prompt_exposure.py:module, tests/test_theme_nerv_fx.py:module]
|
||||
"""
|
||||
from src.paths import get_config_path
|
||||
config_path = get_config_path()
|
||||
|
||||
+44
-13
@@ -53,12 +53,18 @@ events: EventEmitter = EventEmitter()
|
||||
|
||||
class ProviderError(Exception):
|
||||
def __init__(self, kind: str, provider: str, original: Exception) -> None:
|
||||
"""
|
||||
[C: src/api_hooks.py:HookServerInstance.__init__, src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self.kind = kind
|
||||
self.provider = provider
|
||||
self.original = original
|
||||
super().__init__(str(original))
|
||||
|
||||
def ui_message(self) -> str:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
|
||||
"""
|
||||
labels = {
|
||||
"quota": "QUOTA EXHAUSTED",
|
||||
"rate_limit": "RATE LIMITED",
|
||||
@@ -74,8 +80,9 @@ class ProviderError(Exception):
|
||||
|
||||
def set_model_params(temp: float, max_tok: int, trunc_limit: int = 8000, top_p: float = 1.0) -> None:
|
||||
"""
|
||||
|
||||
Sets global generation parameters like temperature and max tokens.
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate]
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
|
||||
"""
|
||||
global _temperature, _max_tokens, _history_trunc_limit, _top_p
|
||||
_temperature = temp
|
||||
@@ -130,6 +137,7 @@ _tool_approval_modes: dict[str, str] = {}
|
||||
|
||||
def get_current_tier() -> Optional[str]:
|
||||
"""
|
||||
|
||||
Returns the current tier from thread-local storage.
|
||||
[C: src/app_controller.py:AppController._on_tool_log, tests/test_ai_client_concurrency.py:intercepted_append]
|
||||
"""
|
||||
@@ -137,6 +145,7 @@ def get_current_tier() -> Optional[str]:
|
||||
|
||||
def set_current_tier(tier: Optional[str]) -> None:
|
||||
"""
|
||||
|
||||
Sets the current tier in thread-local storage.
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_mma_agent_focus_phase1.py:reset_tier, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2]
|
||||
"""
|
||||
@@ -144,6 +153,7 @@ def set_current_tier(tier: Optional[str]) -> None:
|
||||
|
||||
def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
|
||||
"""
|
||||
|
||||
Returns the comms log callback (thread-local with global fallback).
|
||||
[C: src/multi_agent_conductor.py:run_worker_lifecycle]
|
||||
"""
|
||||
@@ -153,6 +163,7 @@ def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
|
||||
|
||||
def set_comms_log_callback(cb: Optional[Callable[[dict[str, Any]], None]]) -> None:
|
||||
"""
|
||||
|
||||
Sets the comms log callback (both global and thread-local).
|
||||
[C: src/app_controller.py:AppController._init_ai_and_hooks, src/multi_agent_conductor.py:run_worker_lifecycle]
|
||||
"""
|
||||
@@ -196,29 +207,30 @@ _project_context_marker: str = ""
|
||||
|
||||
def set_custom_system_prompt(prompt: str) -> None:
|
||||
"""
|
||||
|
||||
Sets a custom system prompt to be combined with the default instructions.
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp]
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp]
|
||||
"""
|
||||
global _custom_system_prompt
|
||||
_custom_system_prompt = prompt
|
||||
|
||||
def set_base_system_prompt(prompt: str) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
|
||||
"""
|
||||
global _base_system_prompt_override
|
||||
_base_system_prompt_override = prompt
|
||||
|
||||
def set_use_default_base_prompt(use_default: bool) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
|
||||
"""
|
||||
global _use_default_base_system_prompt
|
||||
_use_default_base_system_prompt = use_default
|
||||
|
||||
def set_project_context_marker(marker: str) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate]
|
||||
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
|
||||
"""
|
||||
global _project_context_marker
|
||||
_project_context_marker = marker
|
||||
@@ -297,7 +309,7 @@ def get_credentials_path() -> Path:
|
||||
|
||||
def _load_credentials() -> dict[str, Any]:
|
||||
"""
|
||||
[C: tests/test_deepseek_infra.py:test_credentials_error_mentions_deepseek, tests/test_minimax_provider.py:test_minimax_credentials_template]
|
||||
[C: src/ai_server.py:_send_anthropic, src/ai_server.py:_send_deepseek, src/ai_server.py:_send_gemini, src/ai_server.py:_send_minimax, src/ai_server.py:handle_command, tests/test_deepseek_infra.py:test_credentials_error_mentions_deepseek, tests/test_minimax_provider.py:test_minimax_credentials_template]
|
||||
"""
|
||||
cred_path = get_credentials_path()
|
||||
try:
|
||||
@@ -433,6 +445,7 @@ def _classify_minimax_error(exc: Exception) -> ProviderError:
|
||||
|
||||
def set_provider(provider: str, model: str) -> None:
|
||||
"""
|
||||
|
||||
Updates the active LLM provider and model name.
|
||||
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.do_fetch, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_model_selection, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_minimax_provider.py:test_minimax_default_model, tests/test_minimax_provider.py:test_minimax_model_selection, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_rag_integration.py:test_rag_integration, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script, tests/test_token_usage.py:test_token_usage_tracking]
|
||||
"""
|
||||
@@ -459,6 +472,7 @@ def set_provider(provider: str, model: str) -> None:
|
||||
|
||||
def get_provider() -> str:
|
||||
"""
|
||||
|
||||
Returns the current active provider name.
|
||||
[C: src/multi_agent_conductor.py:run_worker_lifecycle]
|
||||
"""
|
||||
@@ -466,6 +480,7 @@ def get_provider() -> str:
|
||||
|
||||
def cleanup() -> None:
|
||||
"""
|
||||
|
||||
Performs cleanup operations like deleting server-side Gemini caches.
|
||||
[C: src/app_controller.py:AppController.clear_cache, src/app_controller.py:AppController.shutdown, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking_cleanup, tests/test_log_registry.py:TestLogRegistry.tearDown, tests/test_project_serialization.py:TestProjectSerialization.tearDown]
|
||||
"""
|
||||
@@ -479,8 +494,9 @@ def cleanup() -> None:
|
||||
|
||||
def reset_session() -> None:
|
||||
"""
|
||||
|
||||
Clears conversation history and resets provider-specific session state.
|
||||
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_minimax_provider.py:test_minimax_history_bleed_stats, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
|
||||
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
|
||||
"""
|
||||
global _gemini_client, _gemini_chat, _gemini_cache
|
||||
global _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths
|
||||
@@ -546,8 +562,9 @@ _agent_tools: dict[str, bool] = {}
|
||||
|
||||
def set_agent_tools(tools: dict[str, bool]) -> None:
|
||||
"""
|
||||
|
||||
Configures which tools are enabled for the AI agent.
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches]
|
||||
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches]
|
||||
"""
|
||||
global _agent_tools, _CACHED_ANTHROPIC_TOOLS, _CACHED_DEEPSEEK_TOOLS
|
||||
_agent_tools = tools
|
||||
@@ -556,6 +573,7 @@ def set_agent_tools(tools: dict[str, bool]) -> None:
|
||||
|
||||
def set_tool_preset(preset_name: Optional[str]) -> None:
|
||||
"""
|
||||
|
||||
Loads a tool preset and applies it via set_agent_tools.
|
||||
[C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_bias_integration.py:test_set_tool_preset_with_objects, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_execution.py:test_tool_ask_approval, tests/test_tool_presets_execution.py:test_tool_auto_approval, tests/test_tool_presets_execution.py:test_tool_rejection]
|
||||
"""
|
||||
@@ -590,6 +608,7 @@ def set_tool_preset(preset_name: Optional[str]) -> None:
|
||||
|
||||
def set_bias_profile(profile_name: Optional[str]) -> None:
|
||||
"""
|
||||
|
||||
Sets the active tool bias profile for tuning model behavior.
|
||||
[C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_agent_tools_panel, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle]
|
||||
"""
|
||||
@@ -733,6 +752,7 @@ async def _execute_tool_calls_concurrently(
|
||||
) -> list[tuple[str, str, str, str]]: # tool_name, call_id, output, original_name
|
||||
"""
|
||||
|
||||
|
||||
Executes multiple tool calls concurrently using asyncio.gather.
|
||||
Returns a list of (tool_name, call_id, output, original_name).
|
||||
[C: tests/test_async_tools.py:test_execute_tool_calls_concurrently_exception_handling, tests/test_async_tools.py:test_execute_tool_calls_concurrently_timing]
|
||||
@@ -1178,6 +1198,9 @@ def _repair_anthropic_history(history: list[dict[str, Any]]) -> None:
|
||||
})
|
||||
|
||||
def _send_anthropic(md_content: str, user_message: str, base_dir: str, file_items: list[dict[str, Any]] | None = None, discussion_history: str = "", pre_tool_callback: Optional[Callable[[str, str, Optional[Callable[[str], str]]], Optional[str]]] = None, qa_callback: Optional[Callable[[str], str]] = None, stream_callback: Optional[Callable[[str], None]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
[C: src/ai_server.py:_handle_send]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client._send_anthropic")
|
||||
try:
|
||||
@@ -1424,7 +1447,7 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str,
|
||||
stream_callback: Optional[Callable[[str], None]] = None,
|
||||
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
[C: tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script]
|
||||
[C: src/ai_server.py:_handle_send, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script]
|
||||
"""
|
||||
global _gemini_chat, _gemini_cache, _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths
|
||||
monitor = performance_monitor.get_monitor()
|
||||
@@ -1656,6 +1679,9 @@ def _send_gemini_cli(md_content: str, user_message: str, base_dir: str,
|
||||
qa_callback: Optional[Callable[[str], str]] = None,
|
||||
stream_callback: Optional[Callable[[str], None]] = None,
|
||||
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
[C: src/ai_server.py:_handle_send]
|
||||
"""
|
||||
global _gemini_cli_adapter
|
||||
try:
|
||||
if _gemini_cli_adapter is None:
|
||||
@@ -1802,6 +1828,9 @@ def _send_deepseek(md_content: str, user_message: str, base_dir: str,
|
||||
qa_callback: Optional[Callable[[str], str]] = None,
|
||||
stream_callback: Optional[Callable[[str], None]] = None,
|
||||
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
[C: src/ai_server.py:_handle_send]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client._send_deepseek")
|
||||
try:
|
||||
@@ -2081,6 +2110,9 @@ def _send_minimax(md_content: str, user_message: str, base_dir: str,
|
||||
qa_callback: Optional[Callable[[str], str]] = None,
|
||||
stream_callback: Optional[Callable[[str], None]] = None,
|
||||
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
[C: src/ai_server.py:_handle_send]
|
||||
"""
|
||||
try:
|
||||
mcp_client.configure(file_items or [], [base_dir])
|
||||
creds = _load_credentials()
|
||||
@@ -2297,7 +2329,6 @@ def _send_minimax(md_content: str, user_message: str, base_dir: str,
|
||||
|
||||
def run_tier4_analysis(stderr: str) -> str:
|
||||
"""
|
||||
[C: src/native_orchestrator.py:NativeOrchestrator.analyze_error]
|
||||
"""
|
||||
if not stderr or not stderr.strip():
|
||||
return ""
|
||||
@@ -2346,7 +2377,7 @@ def run_tier4_patch_callback(stderr: str, base_dir: str) -> Optional[str]:
|
||||
|
||||
def run_tier4_patch_generation(error: str, file_context: str) -> str:
|
||||
"""
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4, src/native_orchestrator.py:NativeOrchestrator.run_tier4_patch, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_calls_ai, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_empty_error, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_returns_diff]
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_calls_ai, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_empty_error, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_returns_diff]
|
||||
"""
|
||||
if not error or not error.strip():
|
||||
return ""
|
||||
@@ -2424,7 +2455,7 @@ def send(
|
||||
rag_engine: Optional[Any] = None,
|
||||
) -> str:
|
||||
"""
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/api_hooks.py:WebSocketServer._handler, src/api_hooks.py:WebSocketServer.broadcast, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/native_orchestrator.py:NativeOrchestrator.execute_ticket, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_get_history_bleed_stats, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/api_hooks.py:WebSocketServer._handler, src/api_hooks.py:WebSocketServer.broadcast, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client.send")
|
||||
@@ -2500,7 +2531,7 @@ if os.environ.get("SLOP_TOOL_PRESET"):
|
||||
|
||||
def run_subagent_summarization(file_path: str, content: str, is_code: bool, outline: str) -> str:
|
||||
"""
|
||||
Performs a stateless summarization request using a sub-agent prompt. [C: src/summarize.py:summarise_file, tests/test_subagent_summarization.py:test_run_subagent_summarization_anthropic, tests/test_subagent_summarization.py:test_run_subagent_summarization_gemini]
|
||||
[C: src/summarize.py:summarise_file, tests/test_subagent_summarization.py:test_run_subagent_summarization_anthropic, tests/test_subagent_summarization.py:test_run_subagent_summarization_gemini]
|
||||
"""
|
||||
prompt_tmpl = mma_prompts.TIER4_SUMMARIZE_CODE_PROMPT if is_code else mma_prompts.TIER4_SUMMARIZE_TEXT_PROMPT
|
||||
prompt = prompt_tmpl.format(file_path=file_path, outline=outline, content=content)
|
||||
|
||||
+49
-12
@@ -46,6 +46,7 @@ class ApiHookClient:
|
||||
|
||||
def _make_request(self, method: str, path: str, data: dict | None = None, timeout: float = 5.0) -> dict[str, Any] | None:
|
||||
"""
|
||||
|
||||
Helper to make HTTP requests to the hook server.
|
||||
[C: tests/test_api_hook_client.py:test_unsupported_method_error]
|
||||
"""
|
||||
@@ -71,8 +72,9 @@ class ApiHookClient:
|
||||
|
||||
def wait_for_server(self, timeout: int = 15) -> bool:
|
||||
"""
|
||||
|
||||
Polls the health endpoint until the server responds or timeout occurs.
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_conductor_api_hook_integration.py:test_conductor_integrates_api_hook_client_for_verification, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_preset_windows_layout.py:test_api_hook_under_load, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_conductor_api_hook_integration.py:test_conductor_integrates_api_hook_client_for_verification, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_phase6_simulation.py:test_ast_inspector_modal_opens, tests/test_phase6_simulation.py:test_batch_operations_shift_click, tests/test_phase6_simulation.py:test_slice_editor_add_remove, tests/test_preset_windows_layout.py:test_api_hook_under_load, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
"""
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
@@ -84,8 +86,9 @@ class ApiHookClient:
|
||||
|
||||
def get_status(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Checks the health of the hook server.
|
||||
[C: tests/test_api_hook_client.py:test_get_status_success, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_preset_windows_layout.py:make_request, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls]
|
||||
[C: tests/test_api_hook_client.py:test_get_status_success, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_phase6_simulation.py:test_ast_inspector_modal_opens, tests/test_phase6_simulation.py:test_batch_operations_shift_click, tests/test_phase6_simulation.py:test_slice_editor_add_remove, tests/test_preset_windows_layout.py:make_request, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls]
|
||||
"""
|
||||
res = self._make_request('GET', '/status')
|
||||
if res is None:
|
||||
@@ -96,6 +99,7 @@ class ApiHookClient:
|
||||
|
||||
def post_project(self, project_data: dict) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Updates the current project configuration.
|
||||
[C: simulation/sim_context.py:ContextSimulation.run]
|
||||
"""
|
||||
@@ -103,6 +107,7 @@ class ApiHookClient:
|
||||
|
||||
def get_project(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves the current project state.
|
||||
[C: simulation/sim_context.py:ContextSimulation.run, tests/test_api_hook_client.py:test_get_project_success, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
@@ -110,6 +115,7 @@ class ApiHookClient:
|
||||
|
||||
def get_session(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves the current discussion session history.
|
||||
[C: simulation/ping_pong.py:main, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/sim_tools.py:ToolsSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_api_hook_client.py:test_get_session_success, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim]
|
||||
"""
|
||||
@@ -117,6 +123,7 @@ class ApiHookClient:
|
||||
|
||||
def post_session(self, session_entries: list[dict]) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Updates the session history.
|
||||
[C: tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
@@ -129,6 +136,7 @@ class ApiHookClient:
|
||||
|
||||
def clear_events(self) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
Retrieves and clears the event queue.
|
||||
[C: simulation/sim_base.py:BaseSimulation.setup]
|
||||
"""
|
||||
@@ -150,34 +158,39 @@ class ApiHookClient:
|
||||
|
||||
def post_gui(self, payload: dict) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Pushes an event to the GUI's AsyncEventQueue via the /api/gui endpoint.
|
||||
[C: tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_api_hook_client.py:test_post_gui_success, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_visual_mma.py:test_visual_mma_components]
|
||||
[C: tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_api_hook_client.py:test_post_gui_success, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works]
|
||||
"""
|
||||
return self._make_request('POST', '/api/gui', data=payload) or {}
|
||||
|
||||
def push_event(self, action: str, payload: dict) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Convenience to push a GUI task.
|
||||
[C: tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_auto_switch_sim.py:trigger_tier, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
[C: tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_auto_switch_sim.py:trigger_tier, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
"""
|
||||
return self.post_gui({"action": action, **payload})
|
||||
|
||||
def click(self, item: str, user_data: Any = None) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Simulates a button click.
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.load_prior_log, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_mma_v2.py:_drain_approvals, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.load_prior_log, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_drain_approvals, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
"""
|
||||
return self.post_gui({"action": "click", "item": item, "user_data": user_data})
|
||||
|
||||
def set_value(self, item: str, value: Any) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Sets the value of a GUI widget.
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.setup, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.setup, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
|
||||
"""
|
||||
return self.post_gui({"action": "set_value", "item": item, "value": value})
|
||||
|
||||
def select_tab(self, item: str, value: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Selects a specific tab in a tab bar.
|
||||
[C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_select_tab_integration]
|
||||
"""
|
||||
@@ -185,6 +198,7 @@ class ApiHookClient:
|
||||
|
||||
def select_list_item(self, item: str, value: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Selects an item in a listbox or combo.
|
||||
[C: simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.switch_discussion, tests/test_api_hook_extensions.py:test_select_list_item_integration, tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
@@ -192,27 +206,33 @@ class ApiHookClient:
|
||||
|
||||
def drag(self, src_item: str, dst_item: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Simulates a drag and drop operation.
|
||||
[C: tests/test_api_hook_client.py:test_drag_success]
|
||||
"""
|
||||
return self.push_event("drag", {"src_item": src_item, "dst_item": dst_item})
|
||||
|
||||
def right_click(self, item: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Simulates a right-click on an item.
|
||||
[C: tests/test_api_hook_client.py:test_right_click_success]
|
||||
"""
|
||||
return self.push_event("right_click", {"item": item})
|
||||
|
||||
def get_gui_state(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns the full GUI state available via the hook API.
|
||||
[C: tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_conductor_api_hook_integration.py:simulate_conductor_phase_completion, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_live_workflow.py:wait_for_value, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout]
|
||||
[C: tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_conductor_api_hook_integration.py:simulate_conductor_phase_completion, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_live_workflow.py:wait_for_value, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_mma.py:test_visual_mma_components]
|
||||
"""
|
||||
return self._make_request('GET', '/api/gui/state') or {}
|
||||
|
||||
def get_value(self, item: str) -> Any:
|
||||
"""
|
||||
|
||||
Gets the value of a GUI item via its mapped field.
|
||||
[C: simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.get_value, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_base.py:BaseSimulation.wait_for_element, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
|
||||
[C: simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.get_value, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_base.py:BaseSimulation.wait_for_element, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
|
||||
"""
|
||||
# Try state endpoint first (new preferred way)
|
||||
state = self.get_gui_state()
|
||||
@@ -235,6 +255,7 @@ class ApiHookClient:
|
||||
|
||||
def get_text_value(self, item_tag: str) -> str | None:
|
||||
"""
|
||||
|
||||
Wraps get_value and returns its string representation, or None.
|
||||
[C: tests/test_api_hook_client.py:test_get_text_value]
|
||||
"""
|
||||
@@ -243,6 +264,7 @@ class ApiHookClient:
|
||||
|
||||
def get_indicator_state(self, item_tag: str) -> dict[str, bool]:
|
||||
"""
|
||||
|
||||
Returns the visibility/active state of a status indicator.
|
||||
[C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_get_indicator_state_integration, tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
@@ -251,27 +273,31 @@ class ApiHookClient:
|
||||
|
||||
def get_gui_diagnostics(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves performance and diagnostic metrics.
|
||||
[C: tests/test_api_hook_client.py:test_get_performance_success, tests/test_hooks.py:test_live_hook_server_responses, tests/test_selectable_ui.py:test_selectable_label_stability]
|
||||
[C: tests/test_api_hook_client.py:test_get_performance_success, tests/test_hooks.py:test_live_hook_server_responses, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing]
|
||||
"""
|
||||
return self._make_request('GET', '/api/gui/diagnostics') or {}
|
||||
|
||||
def get_performance(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves performance metrics from the dedicated endpoint.
|
||||
[C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing]
|
||||
[C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability]
|
||||
"""
|
||||
return self._make_request('GET', '/api/performance') or {}
|
||||
|
||||
def get_mma_status(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves the dedicated MMA engine status.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:_poll_mma_status, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:_poll_mma_status, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_poll]
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:_poll_mma_status, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:_poll_mma_status, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_poll]
|
||||
"""
|
||||
return self._make_request('GET', '/api/gui/mma_status') or {}
|
||||
|
||||
def get_mma_workers(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves status for all active MMA workers.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:_poll_mma_workers]
|
||||
"""
|
||||
@@ -279,6 +305,7 @@ class ApiHookClient:
|
||||
|
||||
def get_context_state(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves the current file and screenshot context state.
|
||||
[C: tests/test_gui_context_presets.py:test_gui_context_preset_save_load]
|
||||
"""
|
||||
@@ -294,6 +321,7 @@ class ApiHookClient:
|
||||
|
||||
def get_node_status(self, node_id: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Retrieves status for a specific node in the MMA DAG.
|
||||
[C: tests/test_api_hook_client.py:test_get_node_status]
|
||||
"""
|
||||
@@ -302,6 +330,7 @@ class ApiHookClient:
|
||||
def request_confirmation(self, tool_name: str, args: dict) -> bool | None:
|
||||
"""
|
||||
|
||||
|
||||
Pushes a manual confirmation request and waits for response.
|
||||
Blocks for up to 60 seconds.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_sync_hooks.py:test_api_ask_client_error, tests/test_sync_hooks.py:test_api_ask_client_method, tests/test_sync_hooks.py:test_api_ask_client_rejection]
|
||||
@@ -314,8 +343,9 @@ class ApiHookClient:
|
||||
|
||||
def reset_session(self) -> None:
|
||||
"""
|
||||
|
||||
Resets the current session via button click.
|
||||
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_minimax_provider.py:test_minimax_history_bleed_stats, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
|
||||
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
|
||||
"""
|
||||
self.click("btn_reset")
|
||||
|
||||
@@ -328,6 +358,7 @@ class ApiHookClient:
|
||||
|
||||
def apply_patch(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Applies the pending patch.
|
||||
[C: tests/test_patch_modal.py:test_apply_callback]
|
||||
"""
|
||||
@@ -335,6 +366,7 @@ class ApiHookClient:
|
||||
|
||||
def reject_patch(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Rejects the pending patch.
|
||||
[C: tests/test_patch_modal.py:test_reject_callback, tests/test_patch_modal.py:test_reject_patch]
|
||||
"""
|
||||
@@ -346,6 +378,7 @@ class ApiHookClient:
|
||||
|
||||
def spawn_mma_worker(self, data: dict) -> dict:
|
||||
"""
|
||||
|
||||
Spawns a new MMA worker with the provided configuration.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
|
||||
"""
|
||||
@@ -357,6 +390,7 @@ class ApiHookClient:
|
||||
|
||||
def pause_mma_pipeline(self) -> dict:
|
||||
"""
|
||||
|
||||
Pauses the MMA execution pipeline.
|
||||
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
|
||||
"""
|
||||
@@ -368,6 +402,7 @@ class ApiHookClient:
|
||||
|
||||
def inject_context(self, data: dict) -> dict:
|
||||
"""
|
||||
|
||||
Injects custom file context into the application.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
|
||||
"""
|
||||
@@ -375,6 +410,7 @@ class ApiHookClient:
|
||||
|
||||
def mutate_mma_dag(self, data: dict) -> dict:
|
||||
"""
|
||||
|
||||
Mutates the MMA DAG (Directed Acyclic Graph) structure.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
|
||||
"""
|
||||
@@ -382,6 +418,7 @@ class ApiHookClient:
|
||||
|
||||
def approve_mma_ticket(self, ticket_id: str) -> dict:
|
||||
"""
|
||||
|
||||
Manually approves a specific ticket for execution in Step Mode.
|
||||
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
|
||||
"""
|
||||
|
||||
+4
-3
@@ -70,6 +70,7 @@ class HookServerInstance(ThreadingHTTPServer):
|
||||
"""Custom HTTPServer that carries a reference to the main App instance."""
|
||||
def __init__(self, server_address: tuple[str, int], RequestHandlerClass: type, app: Any) -> None:
|
||||
"""
|
||||
|
||||
Initializes the server instance with an app reference.
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
@@ -682,7 +683,7 @@ class HookServer:
|
||||
|
||||
def start(self) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_panel, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.init_state, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._update_context_file_stats, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
"""
|
||||
if self.thread and self.thread.is_alive():
|
||||
return
|
||||
@@ -760,7 +761,7 @@ class WebSocketServer:
|
||||
self._stop_event = asyncio.Event()
|
||||
async def main():
|
||||
"""
|
||||
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, src/gui_2.py:module, tests/mock_concurrent_mma.py:module, tests/mock_gemini_cli.py:module, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge.py:module, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_cli_tool_bridge_mapping.py:module, tests/test_discussion_takes.py:module, tests/test_external_editor_gui.py:module, tests/test_headless_service.py:TestHeadlessStartup.test_headless_flag_triggers_run, tests/test_headless_service.py:TestHeadlessStartup.test_normal_startup_calls_app_run, tests/test_mma_skeleton.py:module, tests/test_orchestrator_pm.py:module, tests/test_orchestrator_pm_history.py:module, tests/test_post_process.py:module, tests/test_presets.py:module, tests/test_project_serialization.py:module, tests/test_run_worker_lifecycle_abort.py:module, tests/test_symbol_lookup.py:module, tests/test_system_prompt_exposure.py:module, tests/test_theme_nerv_fx.py:module]
|
||||
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, src/gui_2.py:module, tests/mock_concurrent_mma.py:module, tests/mock_gemini_cli.py:module, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge.py:module, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_cli_tool_bridge_mapping.py:module, tests/test_discussion_takes.py:module, tests/test_external_editor_gui.py:module, tests/test_headless_service.py:TestHeadlessStartup.test_headless_flag_triggers_run, tests/test_headless_service.py:TestHeadlessStartup.test_normal_startup_calls_app_run, tests/test_mma_skeleton.py:module, tests/test_orchestrator_pm.py:module, tests/test_orchestrator_pm_history.py:module, tests/test_presets.py:module, tests/test_project_serialization.py:module, tests/test_run_worker_lifecycle_abort.py:module, tests/test_symbol_lookup.py:module, tests/test_system_prompt_exposure.py:module, tests/test_theme_nerv_fx.py:module]
|
||||
"""
|
||||
async with serve(self._handler, "127.0.0.1", self.port) as server:
|
||||
self.server = server
|
||||
@@ -769,7 +770,7 @@ class WebSocketServer:
|
||||
|
||||
def start(self) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_panel, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.init_state, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._update_context_file_stats, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
"""
|
||||
if self.thread and self.thread.is_alive():
|
||||
return
|
||||
|
||||
+98
-36
@@ -39,6 +39,7 @@ from src.file_cache import ASTParser
|
||||
|
||||
def parse_symbols(text: str) -> list[str]:
|
||||
"""
|
||||
|
||||
Finds all occurrences of '@SymbolName' in text and returns SymbolName.
|
||||
SymbolName can be a function, class, or method (e.g. @MyClass, @my_func, @MyClass.my_method).
|
||||
[C: tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_basic, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_edge_cases, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_methods, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_mixed, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_no_symbols]
|
||||
@@ -59,7 +60,7 @@ def get_symbol_definition(symbol: str, files: list[str]) -> tuple[str, str, int]
|
||||
class ConfirmDialog:
|
||||
def __init__(self, script: str, base_dir: str) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:ConfirmDialog.__init__]
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._uid = str(uuid.uuid4())
|
||||
self._script = str(script) if script is not None else ""
|
||||
@@ -70,7 +71,7 @@ class ConfirmDialog:
|
||||
|
||||
def wait(self) -> tuple[bool, str]:
|
||||
"""
|
||||
[C: src/app_controller.py:ConfirmDialog.wait]
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
@@ -83,7 +84,7 @@ class ConfirmDialog:
|
||||
class MMAApprovalDialog:
|
||||
def __init__(self, ticket_id: str, payload: str) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:MMAApprovalDialog.__init__]
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._payload = payload
|
||||
self._condition = threading.Condition()
|
||||
@@ -92,7 +93,7 @@ class MMAApprovalDialog:
|
||||
|
||||
def wait(self) -> tuple[bool, str]:
|
||||
"""
|
||||
[C: src/app_controller.py:MMAApprovalDialog.wait]
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
@@ -105,7 +106,7 @@ class MMAApprovalDialog:
|
||||
class MMASpawnApprovalDialog:
|
||||
def __init__(self, ticket_id: str, role: str, prompt: str, context_md: str) -> None:
|
||||
"""
|
||||
[C: src/app_controller.py:MMASpawnApprovalDialog.__init__]
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._prompt = prompt
|
||||
self._context_md = context_md
|
||||
@@ -116,7 +117,7 @@ class MMASpawnApprovalDialog:
|
||||
|
||||
def wait(self) -> dict[str, Any]:
|
||||
"""
|
||||
[C: src/app_controller.py:MMASpawnApprovalDialog.wait]
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
@@ -134,6 +135,7 @@ class MMASpawnApprovalDialog:
|
||||
#region: API Handlers
|
||||
async def _api_get_key(controller: 'AppController', header_key: str) -> str:
|
||||
"""
|
||||
|
||||
Validates the API key from the request header against configuration.
|
||||
[SDM: src/app_controller.py:_api_get_key]
|
||||
"""
|
||||
@@ -149,6 +151,7 @@ async def _api_get_key(controller: 'AppController', header_key: str) -> str:
|
||||
|
||||
def _api_health(controller: 'AppController') -> dict[str, str]:
|
||||
"""
|
||||
|
||||
Returns the health status of the API.
|
||||
[SDM: src/app_controller.py:_api_health]
|
||||
"""
|
||||
@@ -156,6 +159,7 @@ def _api_health(controller: 'AppController') -> dict[str, str]:
|
||||
|
||||
def _api_get_gui_state(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns the current GUI state for specific fields.
|
||||
[SDM: src/app_controller.py:_api_get_gui_state]
|
||||
"""
|
||||
@@ -172,6 +176,7 @@ def _api_get_gui_state(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_get_mma_status(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Dedicated endpoint for MMA-related status.
|
||||
[SDM: src/app_controller.py:_api_get_mma_status]
|
||||
"""
|
||||
@@ -190,6 +195,7 @@ def _api_get_mma_status(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_post_gui(controller: 'AppController', req: dict) -> dict[str, str]:
|
||||
"""
|
||||
|
||||
Pushes a GUI task to the event queue.
|
||||
[SDM: src/app_controller.py:_api_post_gui]
|
||||
"""
|
||||
@@ -198,6 +204,7 @@ def _api_post_gui(controller: 'AppController', req: dict) -> dict[str, str]:
|
||||
|
||||
def _api_get_api_session(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns current discussion session entries.
|
||||
[SDM: src/app_controller.py:_api_get_api_session]
|
||||
"""
|
||||
@@ -206,6 +213,7 @@ def _api_get_api_session(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_post_api_session(controller: 'AppController', req: dict) -> dict[str, str]:
|
||||
"""
|
||||
|
||||
Updates session entries.
|
||||
[SDM: src/app_controller.py:_api_post_api_session]
|
||||
"""
|
||||
@@ -216,6 +224,7 @@ def _api_post_api_session(controller: 'AppController', req: dict) -> dict[str, s
|
||||
|
||||
def _api_get_api_project(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns current project data.
|
||||
[SDM: src/app_controller.py:_api_get_api_project]
|
||||
"""
|
||||
@@ -223,6 +232,7 @@ def _api_get_api_project(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_get_performance(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns performance monitor metrics.
|
||||
[SDM: src/app_controller.py:_api_get_performance]
|
||||
"""
|
||||
@@ -230,6 +240,7 @@ def _api_get_performance(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_get_diagnostics(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Alias for performance metrics.
|
||||
[SDM: src/app_controller.py:_api_get_diagnostics]
|
||||
"""
|
||||
@@ -237,6 +248,7 @@ def _api_get_diagnostics(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_status(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns the current status of the application.
|
||||
[SDM: src/app_controller.py:_api_status]
|
||||
"""
|
||||
@@ -249,6 +261,7 @@ def _api_status(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Triggers an AI generation request using the current project context.
|
||||
[SDM: src/app_controller.py:_api_generate]
|
||||
"""
|
||||
@@ -313,6 +326,7 @@ def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str
|
||||
|
||||
async def _api_stream(controller: 'AppController', req: GenerateRequest) -> Any:
|
||||
"""
|
||||
|
||||
Placeholder for streaming AI generation responses (Not yet implemented).
|
||||
[SDM: src/app_controller.py:_api_stream]
|
||||
"""
|
||||
@@ -320,6 +334,7 @@ async def _api_stream(controller: 'AppController', req: GenerateRequest) -> Any:
|
||||
|
||||
def _api_pending_actions(controller: 'AppController') -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
Lists all pending PowerShell scripts awaiting confirmation.
|
||||
[SDM: src/app_controller.py:_api_pending_actions]
|
||||
"""
|
||||
@@ -331,6 +346,7 @@ def _api_pending_actions(controller: 'AppController') -> list[dict[str, Any]]:
|
||||
|
||||
def _api_confirm_action(controller: 'AppController', action_id: str, req: ConfirmRequest) -> dict[str, str]:
|
||||
"""
|
||||
|
||||
Approves or rejects a pending action.
|
||||
[SDM: src/app_controller.py:_api_confirm_action]
|
||||
"""
|
||||
@@ -348,6 +364,7 @@ def _api_confirm_action(controller: 'AppController', action_id: str, req: Confir
|
||||
|
||||
def _api_list_sessions(controller: 'AppController') -> list[str]:
|
||||
"""
|
||||
|
||||
Lists all session IDs.
|
||||
[SDM: src/app_controller.py:_api_list_sessions]
|
||||
"""
|
||||
@@ -358,6 +375,7 @@ def _api_list_sessions(controller: 'AppController') -> list[str]:
|
||||
|
||||
def _api_get_session(controller: 'AppController', session_id: str) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns the content of the comms.log for a specific session.
|
||||
[SDM: src/app_controller.py:_api_get_session]
|
||||
"""
|
||||
@@ -368,6 +386,7 @@ def _api_get_session(controller: 'AppController', session_id: str) -> dict[str,
|
||||
|
||||
def _api_delete_session(controller: 'AppController', session_id: str) -> dict[str, str]:
|
||||
"""
|
||||
|
||||
Deletes a specific session directory.
|
||||
[SDM: src/app_controller.py:_api_delete_session]
|
||||
"""
|
||||
@@ -380,6 +399,7 @@ def _api_delete_session(controller: 'AppController', session_id: str) -> dict[st
|
||||
|
||||
def _api_get_context(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns the current aggregated project context.
|
||||
[SDM: src/app_controller.py:_api_get_context]
|
||||
"""
|
||||
@@ -398,6 +418,7 @@ def _api_get_context(controller: 'AppController') -> dict[str, Any]:
|
||||
|
||||
def _api_token_stats(controller: 'AppController') -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Returns current token usage and budget statistics.
|
||||
[SDM: src/app_controller.py:_api_token_stats]
|
||||
"""
|
||||
@@ -618,6 +639,9 @@ def _handle_mma_spawn_approval(controller: 'AppController', task: dict):
|
||||
class AutoSpawnDialog:
|
||||
def __init__(self, t): self.t = t
|
||||
def wait(self):
|
||||
"""
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
return {'approved': True, 'abort': False, 'prompt': self.t.get("prompt"), 'context_md': self.t.get("context_md")}
|
||||
task["dialog_container"][0] = AutoSpawnDialog(task)
|
||||
return
|
||||
@@ -707,13 +731,14 @@ def _handle_hide_patch_modal(controller: 'AppController', task: dict):
|
||||
|
||||
class AppController:
|
||||
"""
|
||||
|
||||
The headless controller for the Manual Slop application.
|
||||
Owns the application state and manages background services.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
[C: src/app_controller.py:AppController.__init__]
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
# --- Locks ---
|
||||
self._send_thread_lock: threading.Lock = threading.Lock()
|
||||
@@ -1103,8 +1128,9 @@ class AppController:
|
||||
|
||||
def _update_inject_preview(self) -> None:
|
||||
"""
|
||||
|
||||
Updates the preview content based on the selected file and injection mode.
|
||||
[C: src/gui_2.py:App._gui_func, tests/test_skeleton_injection.py:test_update_inject_preview_full, tests/test_skeleton_injection.py:test_update_inject_preview_skeleton, tests/test_skeleton_injection.py:test_update_inject_preview_truncation]
|
||||
[C: src/gui_2.py:App._render_text_viewer_window, tests/test_skeleton_injection.py:test_update_inject_preview_full, tests/test_skeleton_injection.py:test_update_inject_preview_skeleton, tests/test_skeleton_injection.py:test_update_inject_preview_truncation]
|
||||
"""
|
||||
if not self._inject_file_path:
|
||||
self._inject_preview = ""
|
||||
@@ -1349,8 +1375,9 @@ class AppController:
|
||||
|
||||
def _process_pending_gui_tasks(self) -> None:
|
||||
"""
|
||||
|
||||
Processes pending GUI tasks from the queue on the main render thread.
|
||||
[C: src/gui_2.py:App._gui_func, tests/test_api_hook_extensions.py:test_app_processes_new_actions, tests/test_gui_updates.py:test_gui_updates_on_event, tests/test_live_gui_integration_v2.py:test_user_request_error_handling, tests/test_live_gui_integration_v2.py:test_user_request_integration_flow, tests/test_mma_orchestration_gui.py:test_handle_ai_response_fallback, tests/test_mma_orchestration_gui.py:test_handle_ai_response_with_stream_id, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_mma_spawn_approval, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_show_track_proposal, tests/test_process_pending_gui_tasks.py:test_gcli_path_updates_adapter, tests/test_process_pending_gui_tasks.py:test_redundant_calls_in_process_pending_gui_tasks]
|
||||
[C: src/gui_2.py:App._render_main_interface, tests/test_api_hook_extensions.py:test_app_processes_new_actions, tests/test_gui_updates.py:test_gui_updates_on_event, tests/test_live_gui_integration_v2.py:test_user_request_error_handling, tests/test_live_gui_integration_v2.py:test_user_request_integration_flow, tests/test_mma_orchestration_gui.py:test_handle_ai_response_fallback, tests/test_mma_orchestration_gui.py:test_handle_ai_response_with_stream_id, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_mma_spawn_approval, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_show_track_proposal, tests/test_process_pending_gui_tasks.py:test_gcli_path_updates_adapter, tests/test_process_pending_gui_tasks.py:test_process_pending_gui_tasks_drag, tests/test_process_pending_gui_tasks.py:test_process_pending_gui_tasks_right_click, tests/test_process_pending_gui_tasks.py:test_redundant_calls_in_process_pending_gui_tasks]
|
||||
"""
|
||||
now = time.time()
|
||||
if hasattr(self, 'event_queue') and hasattr(self.event_queue, 'websocket_server') and self.event_queue.websocket_server:
|
||||
@@ -1377,8 +1404,9 @@ class AppController:
|
||||
|
||||
def _process_pending_history_adds(self) -> None:
|
||||
"""
|
||||
|
||||
Synchronizes pending history entries to the active discussion and project state.
|
||||
[C: src/gui_2.py:App._gui_func]
|
||||
[C: src/gui_2.py:App._render_main_interface]
|
||||
"""
|
||||
with self._pending_history_adds_lock:
|
||||
items = self._pending_history_adds[:]
|
||||
@@ -1405,8 +1433,9 @@ class AppController:
|
||||
|
||||
def _process_pending_tool_calls(self) -> bool:
|
||||
"""
|
||||
|
||||
Drains pending tool calls into the tool log. Returns True if any were processed.
|
||||
[C: src/gui_2.py:App._gui_func]
|
||||
[C: src/gui_2.py:App._render_main_interface]
|
||||
"""
|
||||
with self._pending_tool_calls_lock:
|
||||
items = self._pending_tool_calls[:]
|
||||
@@ -1452,8 +1481,9 @@ class AppController:
|
||||
|
||||
def init_state(self):
|
||||
"""
|
||||
|
||||
Initializes the application state from configurations.
|
||||
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._render_paths_panel, src/gui_2.py:App._save_paths, tests/test_app_controller_mcp.py:test_app_controller_mcp_loading, tests/test_app_controller_mcp.py:test_app_controller_mcp_project_override, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_init_state_loads_prompts]
|
||||
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._save_paths, src/gui_2.py:App._set_external_editor_default, tests/test_app_controller_mcp.py:test_app_controller_mcp_loading, tests/test_app_controller_mcp.py:test_app_controller_mcp_project_override, tests/test_context_composition_decoupled.py:test_do_generate_uses_context_files, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_init_state_loads_prompts]
|
||||
"""
|
||||
self.active_tickets = []
|
||||
self.ui_separate_task_dag = False
|
||||
@@ -1638,7 +1668,7 @@ class AppController:
|
||||
|
||||
def cb_load_prior_log(self, path: Optional[str] = None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_log_management]
|
||||
[C: src/gui_2.py:App._render_log_management, src/gui_2.py:App.cb_load_prior_log]
|
||||
"""
|
||||
if not path:
|
||||
return
|
||||
@@ -1822,7 +1852,7 @@ class AppController:
|
||||
|
||||
def cb_exit_prior_session(self):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_comms_history_panel, src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_comms_history_panel, src/gui_2.py:App._render_prior_session_view]
|
||||
"""
|
||||
self.is_viewing_prior_session = False
|
||||
if self._current_session_usage:
|
||||
@@ -1942,6 +1972,7 @@ class AppController:
|
||||
def start_services(self, app: Any = None):
|
||||
"""
|
||||
|
||||
|
||||
Starts background threads.
|
||||
[C: src/gui_2.py:App.__init__]
|
||||
"""
|
||||
@@ -1953,6 +1984,7 @@ class AppController:
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Stops background threads and cleans up resources.
|
||||
[C: src/gui_2.py:App.run, src/gui_2.py:App.shutdown, tests/conftest.py:app_instance, tests/conftest.py:mock_app]
|
||||
"""
|
||||
@@ -2056,6 +2088,7 @@ class AppController:
|
||||
def _handle_request_event(self, event: events.UserRequestEvent) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Processes a UserRequestEvent by calling the AI client.
|
||||
[C: tests/test_live_gui_integration_v2.py:test_user_request_error_handling, tests/test_live_gui_integration_v2.py:test_user_request_integration_flow, tests/test_rag_integration.py:test_rag_integration]
|
||||
"""
|
||||
@@ -2380,8 +2413,10 @@ class AppController:
|
||||
|
||||
def create_api(self) -> FastAPI:
|
||||
"""
|
||||
|
||||
Creates and configures the FastAPI application for headless mode.
|
||||
[SDM: src/app_controller.py:AppController.create_api]
|
||||
[C: src/gui_2.py:App.run, tests/test_headless_service.py:TestHeadlessAPI.setUp]
|
||||
"""
|
||||
api = FastAPI(title="Manual Slop Headless API")
|
||||
API_KEY_NAME = "X-API-KEY"
|
||||
@@ -2393,12 +2428,21 @@ class AppController:
|
||||
return _api_health(self)
|
||||
@api.get("/api/gui/state", dependencies=[Depends(get_api_key)])
|
||||
def get_gui_state() -> dict[str, Any]:
|
||||
"""
|
||||
[C: tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_conductor_api_hook_integration.py:simulate_conductor_phase_completion, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_live_workflow.py:wait_for_value, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_mma.py:test_visual_mma_components]
|
||||
"""
|
||||
return _api_get_gui_state(self)
|
||||
@api.get("/api/gui/mma_status", dependencies=[Depends(get_api_key)])
|
||||
def get_mma_status() -> dict[str, Any]:
|
||||
"""
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:_poll_mma_status, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:_poll_mma_status, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_poll]
|
||||
"""
|
||||
return _api_get_mma_status(self)
|
||||
@api.post("/api/gui", dependencies=[Depends(get_api_key)])
|
||||
def post_gui(req: dict) -> dict[str, str]:
|
||||
"""
|
||||
[C: tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_api_hook_client.py:test_post_gui_success, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works]
|
||||
"""
|
||||
return _api_post_gui(self, req)
|
||||
@api.get("/api/session", dependencies=[Depends(get_api_key)])
|
||||
def get_api_session() -> dict[str, Any]:
|
||||
@@ -2411,6 +2455,9 @@ class AppController:
|
||||
return _api_get_api_project(self)
|
||||
@api.get("/api/performance", dependencies=[Depends(get_api_key)])
|
||||
def get_performance() -> dict[str, Any]:
|
||||
"""
|
||||
[C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability]
|
||||
"""
|
||||
return _api_get_performance(self)
|
||||
@api.get("/api/gui/diagnostics", dependencies=[Depends(get_api_key)])
|
||||
def get_diagnostics() -> dict[str, Any]:
|
||||
@@ -2435,12 +2482,18 @@ class AppController:
|
||||
return _api_list_sessions(self)
|
||||
@api.get("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
|
||||
def get_session(session_id: str) -> dict[str, Any]:
|
||||
"""
|
||||
[C: simulation/ping_pong.py:main, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/sim_tools.py:ToolsSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_api_hook_client.py:test_get_session_success, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim]
|
||||
"""
|
||||
return _api_get_session(self, session_id)
|
||||
@api.delete("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
|
||||
def delete_session(session_id: str) -> dict[str, str]:
|
||||
return _api_delete_session(self, session_id)
|
||||
@api.get("/api/v1/context", dependencies=[Depends(get_api_key)])
|
||||
def get_context() -> dict[str, Any]:
|
||||
"""
|
||||
[C: src/fuzzy_anchor.py:FuzzyAnchor.create_slice]
|
||||
"""
|
||||
return _api_get_context(self)
|
||||
@api.get("/api/v1/token_stats", dependencies=[Depends(get_api_key)])
|
||||
def token_stats() -> dict[str, Any]:
|
||||
@@ -2529,7 +2582,7 @@ class AppController:
|
||||
def _refresh_from_project(self) -> None:
|
||||
# Deserialize FileItems in files.paths
|
||||
"""
|
||||
[C: tests/test_mma_dashboard_refresh.py:test_mma_dashboard_initialization_refresh, tests/test_mma_dashboard_refresh.py:test_mma_dashboard_refresh]
|
||||
[C: tests/test_mma_dashboard_refresh.py:test_mma_dashboard_initialization_refresh, tests/test_mma_dashboard_refresh.py:test_mma_dashboard_refresh, tests/test_view_presets.py:test_load_presets_from_project_legacy_dict, tests/test_view_presets.py:test_load_presets_from_project_list]
|
||||
"""
|
||||
raw_paths = self.project.get("files", {}).get("paths", [])
|
||||
self.files = []
|
||||
@@ -2721,7 +2774,7 @@ class AppController:
|
||||
|
||||
def _cb_save_view_preset(self, name: str, f_item: models.FileItem) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_files_panel]
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_view_presets.py:test_save_view_preset]
|
||||
"""
|
||||
preset = models.NamedViewPreset(
|
||||
name=name,
|
||||
@@ -2739,7 +2792,7 @@ class AppController:
|
||||
|
||||
def _cb_apply_view_preset(self, name: str, f_item: models.FileItem) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_files_panel]
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_view_presets.py:test_apply_view_preset]
|
||||
"""
|
||||
preset = next((vp for vp in self.view_presets if vp.name == name), None)
|
||||
if preset:
|
||||
@@ -2749,7 +2802,7 @@ class AppController:
|
||||
|
||||
def _cb_delete_view_preset(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_files_panel]
|
||||
[C: tests/test_view_presets.py:test_delete_view_preset]
|
||||
"""
|
||||
self.view_presets = [vp for vp in self.view_presets if vp.name != name]
|
||||
self._flush_to_project()
|
||||
@@ -2757,7 +2810,7 @@ class AppController:
|
||||
|
||||
def _cb_load_track(self, track_id: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_dashboard]
|
||||
[C: src/gui_2.py:App._render_mma_track_browser]
|
||||
"""
|
||||
state = project_manager.load_track_state(track_id, self.active_project_root)
|
||||
if state:
|
||||
@@ -2802,7 +2855,7 @@ class AppController:
|
||||
|
||||
def _get_discussion_names(self) -> list[str]:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
@@ -2810,7 +2863,7 @@ class AppController:
|
||||
|
||||
def _switch_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_takes_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_takes_panel, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
self._flush_disc_entries_to_project()
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
@@ -2831,7 +2884,7 @@ class AppController:
|
||||
|
||||
def _flush_disc_entries_to_project(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
history_strings = [project_manager.entry_to_str(e) for e in self.disc_entries]
|
||||
if self.active_track and self._track_discussion_active:
|
||||
@@ -2846,7 +2899,7 @@ class AppController:
|
||||
|
||||
def _create_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_metadata, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel]
|
||||
"""
|
||||
disc_sec = self.project.setdefault("discussion", {})
|
||||
discussions = disc_sec.setdefault("discussions", {})
|
||||
@@ -2860,7 +2913,7 @@ class AppController:
|
||||
|
||||
def _branch_discussion(self, index: int) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_entry]
|
||||
"""
|
||||
self._flush_disc_entries_to_project()
|
||||
# Generate a unique branch name
|
||||
@@ -2877,7 +2930,7 @@ class AppController:
|
||||
self._switch_discussion(new_name)
|
||||
def _rename_discussion(self, old_name: str, new_name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_metadata]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
@@ -2893,7 +2946,7 @@ class AppController:
|
||||
|
||||
def _delete_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_panel]
|
||||
[C: src/gui_2.py:App._render_discussion_metadata]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
@@ -2909,7 +2962,7 @@ class AppController:
|
||||
|
||||
def _handle_mma_respond(self, approved: bool, payload: str | None = None, abort: bool = False, prompt: str | None = None, context_md: str | None = None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._handle_approve_mma_step, src/gui_2.py:App._handle_approve_spawn]
|
||||
[C: src/gui_2.py:App._handle_approve_mma_step, src/gui_2.py:App._handle_approve_spawn, src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
if self._pending_mma_approvals:
|
||||
task = self._pending_mma_approvals.pop(0)
|
||||
@@ -2938,8 +2991,9 @@ class AppController:
|
||||
def _handle_approve_ask(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Responds with approval for a pending /api/ask request.
|
||||
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._gui_func]
|
||||
[C: src/gui_2.py:App._handle_approve_ask, src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
if not self._ask_request_id: return
|
||||
request_id = self._ask_request_id
|
||||
@@ -2960,8 +3014,9 @@ class AppController:
|
||||
def _handle_reject_ask(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Responds with rejection for a pending /api/ask request.
|
||||
[C: src/gui_2.py:App._gui_func]
|
||||
[C: src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
if not self._ask_request_id: return
|
||||
request_id = self._ask_request_id
|
||||
@@ -2982,6 +3037,7 @@ class AppController:
|
||||
def _handle_reset_session(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Logic for resetting the AI session and GUI state.
|
||||
[C: src/gui_2.py:App._render_message_panel]
|
||||
"""
|
||||
@@ -3035,6 +3091,7 @@ class AppController:
|
||||
def _handle_md_only(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Logic for the 'MD Only' action.
|
||||
[C: src/gui_2.py:App._render_message_panel]
|
||||
"""
|
||||
@@ -3057,6 +3114,7 @@ class AppController:
|
||||
def _handle_generate_send(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Logic for the 'Gen + Send' action.
|
||||
[C: src/gui_2.py:App._render_message_panel, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel, tests/test_gui_events_v2.py:test_handle_generate_send_pushes_event, tests/test_symbol_parsing.py:test_handle_generate_send_appends_definitions, tests/test_symbol_parsing.py:test_handle_generate_send_no_symbols]
|
||||
"""
|
||||
@@ -3182,7 +3240,7 @@ class AppController:
|
||||
|
||||
def _flush_to_project(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._show_menus]
|
||||
[C: src/gui_2.py:App._render_discussion_entry_controls, src/gui_2.py:App._render_main_interface, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._show_menus, tests/test_view_presets.py:test_save_view_preset]
|
||||
"""
|
||||
proj = self.project
|
||||
proj.setdefault("output", {})["output_dir"] = self.ui_output_dir
|
||||
@@ -3222,7 +3280,7 @@ class AppController:
|
||||
|
||||
def _flush_to_config(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._render_theme_panel, src/gui_2.py:App._show_menus, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_flush_saves_prompts]
|
||||
[C: src/gui_2.py:App._render_discussion_entry_controls, src/gui_2.py:App._render_main_interface, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._render_theme_panel, src/gui_2.py:App._show_menus, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_flush_saves_prompts]
|
||||
"""
|
||||
self.config["ai"] = {
|
||||
"provider": self.current_provider,
|
||||
@@ -3266,8 +3324,9 @@ class AppController:
|
||||
def _do_generate(self) -> tuple[str, Path, list[dict[str, Any]], str, str]:
|
||||
"""
|
||||
|
||||
|
||||
Returns (full_md, output_path, file_items, stable_md, discussion_text).
|
||||
[C: src/gui_2.py:App._show_menus, tests/test_tiered_aggregation.py:test_app_controller_do_generate_uses_persona_strategy]
|
||||
[C: src/gui_2.py:App._show_menus, tests/test_context_composition_decoupled.py:test_do_generate_uses_context_files, tests/test_tiered_aggregation.py:test_app_controller_do_generate_uses_persona_strategy]
|
||||
"""
|
||||
self._flush_to_project()
|
||||
self._flush_to_config()
|
||||
@@ -3301,7 +3360,7 @@ class AppController:
|
||||
|
||||
def _cb_plan_epic(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_mma_orchestration_gui.py:test_cb_plan_epic_launches_thread]
|
||||
[C: src/gui_2.py:App._render_mma_epic_planner, tests/test_mma_orchestration_gui.py:test_cb_plan_epic_launches_thread]
|
||||
"""
|
||||
def _bg_task() -> None:
|
||||
try:
|
||||
@@ -3540,6 +3599,7 @@ class AppController:
|
||||
def kill_worker(self, worker_id: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Aborts a running worker.
|
||||
[C: src/gui_2.py:App._cb_kill_ticket, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread]
|
||||
"""
|
||||
@@ -3564,6 +3624,7 @@ class AppController:
|
||||
def inject_context(self, data: dict) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Programmatic context injection.
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
|
||||
"""
|
||||
@@ -3613,7 +3674,7 @@ class AppController:
|
||||
|
||||
def _cb_run_conductor_setup(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_gui_phase3.py:test_conductor_setup_scan]
|
||||
[C: src/gui_2.py:App._render_mma_conductor_setup, tests/test_gui_phase3.py:test_conductor_setup_scan]
|
||||
"""
|
||||
base = paths.get_conductor_dir(project_path=self.active_project_root)
|
||||
if not base.exists():
|
||||
@@ -3643,7 +3704,7 @@ class AppController:
|
||||
|
||||
def _cb_create_track(self, name: str, desc: str, track_type: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_gui_phase3.py:test_create_track]
|
||||
[C: src/gui_2.py:App._render_mma_track_browser, tests/test_gui_phase3.py:test_create_track]
|
||||
"""
|
||||
if not name: return
|
||||
date_suffix = datetime.now().strftime("%Y%m%d")
|
||||
@@ -3671,7 +3732,7 @@ class AppController:
|
||||
|
||||
def _push_mma_state_update(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._cb_block_ticket, src/gui_2.py:App._cb_unblock_ticket, src/gui_2.py:App._render_mma_dashboard, src/gui_2.py:App._render_task_dag_panel, src/gui_2.py:App._render_ticket_queue, src/gui_2.py:App._reorder_ticket, src/gui_2.py:App.bulk_block, src/gui_2.py:App.bulk_execute, src/gui_2.py:App.bulk_skip, tests/test_gui_phase4.py:test_push_mma_state_update]
|
||||
[C: src/gui_2.py:App._cb_block_ticket, src/gui_2.py:App._cb_unblock_ticket, src/gui_2.py:App._render_mma_ticket_editor, src/gui_2.py:App._render_task_dag_panel, src/gui_2.py:App._render_ticket_queue, src/gui_2.py:App._reorder_ticket, src/gui_2.py:App.bulk_block, src/gui_2.py:App.bulk_execute, src/gui_2.py:App.bulk_skip, tests/test_gui_phase4.py:test_push_mma_state_update]
|
||||
"""
|
||||
if not self.active_track:
|
||||
return
|
||||
@@ -3696,6 +3757,7 @@ class AppController:
|
||||
def _load_active_tickets(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Populates self.active_tickets based on the current execution mode.
|
||||
[C: tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads]
|
||||
"""
|
||||
|
||||
@@ -21,6 +21,7 @@ class BeadsClient:
|
||||
|
||||
def init_repo(self) -> None:
|
||||
"""
|
||||
|
||||
Initialize the mock repository.
|
||||
[C: tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads, tests/test_mcp_client_beads.py:test_bd_mcp_tools]
|
||||
"""
|
||||
@@ -30,6 +31,7 @@ class BeadsClient:
|
||||
|
||||
def is_initialized(self) -> bool:
|
||||
"""
|
||||
|
||||
Check if the repository is initialized.
|
||||
[C: src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query]
|
||||
"""
|
||||
@@ -37,6 +39,7 @@ class BeadsClient:
|
||||
|
||||
def create_bead(self, title: str, description: str) -> str:
|
||||
"""
|
||||
|
||||
Create a new bead and return its ID.
|
||||
[C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads]
|
||||
"""
|
||||
@@ -49,6 +52,7 @@ class BeadsClient:
|
||||
|
||||
def update_bead(self, bead_id: str, status: str) -> bool:
|
||||
"""
|
||||
|
||||
Update the status of an existing bead.
|
||||
[C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query]
|
||||
"""
|
||||
@@ -62,6 +66,7 @@ class BeadsClient:
|
||||
|
||||
def list_beads(self) -> List[Bead]:
|
||||
"""
|
||||
|
||||
List all beads.
|
||||
[C: src/gui_2.py:App._render_beads_tab, src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query]
|
||||
"""
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ class BackgroundShader:
|
||||
|
||||
def render(self, width: float, height: float):
|
||||
"""
|
||||
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_heavy_text, src/gui_2.py:App._render_markdown_test, src/gui_2.py:App._render_response_panel, src/gui_2.py:App._render_snapshot_tab, src/markdown_helper.py:MarkdownRenderer._render_code_block, src/markdown_helper.py:MarkdownRenderer.render, src/markdown_helper.py:render, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._render_heavy_text, src/gui_2.py:App._render_markdown_test, src/gui_2.py:App._render_prior_session_view, src/gui_2.py:App._render_response_panel, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App._render_text_viewer_window, src/markdown_helper.py:MarkdownRenderer._render_code_block, src/markdown_helper.py:MarkdownRenderer.render, src/markdown_helper.py:render, src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
"""
|
||||
if not self.enabled or width <= 0 or height <= 0:
|
||||
return
|
||||
|
||||
@@ -42,9 +42,10 @@ from typing import Any
|
||||
def generate_tickets(track_brief: str, module_skeletons: str) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Tier 2 (Tech Lead) call.
|
||||
Breaks down a Track Brief and module skeletons into discrete Tier 3 Tickets.
|
||||
[C: src/native_orchestrator.py:NativeOrchestrator.generate_tickets, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_failure, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_success, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_success, tests/test_orchestration_logic.py:test_generate_tickets]
|
||||
[C: tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_failure, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_success, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_success, tests/test_orchestration_logic.py:test_generate_tickets]
|
||||
"""
|
||||
# 1. Set Tier 2 Model (Tech Lead - Flash)
|
||||
# 2. Construct Prompt
|
||||
@@ -98,6 +99,7 @@ from src.models import Ticket
|
||||
def topological_sort(tickets: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Sorts a list of tickets based on their 'depends_on' field.
|
||||
Raises ValueError if a circular dependency or missing internal dependency is detected.
|
||||
[C: tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_complex, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_cycle, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_empty, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_linear, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_missing_dependency, tests/test_conductor_tech_lead.py:test_topological_sort_vlog, tests/test_dag_engine.py:test_topological_sort, tests/test_dag_engine.py:test_topological_sort_cycle, tests/test_orchestration_logic.py:test_topological_sort, tests/test_orchestration_logic.py:test_topological_sort_circular, tests/test_perf_dag.py:test_dag_edge_cases, tests/test_perf_dag.py:test_dag_performance]
|
||||
|
||||
+2
-1
@@ -47,9 +47,10 @@ MODEL_PRICING = [
|
||||
def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float:
|
||||
"""
|
||||
|
||||
|
||||
Estimate the cost of a model call based on input and output tokens.
|
||||
Returns the total cost in USD.
|
||||
[C: src/gui_2.py:App._render_mma_dashboard, src/gui_2.py:App._render_token_budget_panel, tests/test_cost_tracker.py:test_estimate_cost]
|
||||
[C: src/gui_2.py:App._render_mma_track_summary, src/gui_2.py:App._render_mma_usage_section, src/gui_2.py:App._render_token_budget_panel, tests/test_cost_tracker.py:test_estimate_cost]
|
||||
"""
|
||||
if not model:
|
||||
return 0.0
|
||||
|
||||
@@ -33,6 +33,7 @@ from src.performance_monitor import get_monitor
|
||||
class TrackDAG:
|
||||
"""
|
||||
|
||||
|
||||
Manages a Directed Acyclic Graph of implementation tickets.
|
||||
Provides methods for dependency resolution, cycle detection, and topological sorting.
|
||||
"""
|
||||
@@ -40,6 +41,7 @@ class TrackDAG:
|
||||
def __init__(self, tickets: List[Ticket]) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Initializes the TrackDAG with a list of Ticket objects.
|
||||
Args:
|
||||
tickets: A list of Ticket instances defining the graph nodes and edges.
|
||||
@@ -51,6 +53,7 @@ class TrackDAG:
|
||||
def cascade_blocks(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Transitively marks `todo` tickets as `blocked` if any dependency is `blocked`.
|
||||
Propagates 'blocked' status from initially blocked nodes to their dependents.
|
||||
[C: tests/test_perf_dag.py:test_dag_performance]
|
||||
@@ -88,6 +91,7 @@ class TrackDAG:
|
||||
def get_ready_tasks(self) -> List[Ticket]:
|
||||
"""
|
||||
|
||||
|
||||
Returns a list of tickets that are in 'todo' status and whose dependencies are all 'completed'.
|
||||
Returns:
|
||||
A list of Ticket objects ready for execution.
|
||||
@@ -102,6 +106,7 @@ class TrackDAG:
|
||||
def has_cycle(self) -> bool:
|
||||
"""
|
||||
|
||||
|
||||
Performs an iterative Depth-First Search to detect cycles in the dependency graph.
|
||||
Returns:
|
||||
True if a cycle is detected, False otherwise.
|
||||
@@ -135,6 +140,7 @@ class TrackDAG:
|
||||
def topological_sort(self) -> List[str]:
|
||||
"""
|
||||
|
||||
|
||||
Returns a list of ticket IDs in topological order (dependencies before dependents).
|
||||
Uses Kahn's algorithm for efficient O(V+E) sorting and cycle detection.
|
||||
Returns:
|
||||
@@ -171,6 +177,7 @@ class TrackDAG:
|
||||
class ExecutionEngine:
|
||||
"""
|
||||
|
||||
|
||||
A state machine that governs the progression of tasks within a TrackDAG.
|
||||
Handles automatic queueing and manual task approval.
|
||||
"""
|
||||
@@ -178,6 +185,7 @@ class ExecutionEngine:
|
||||
def __init__(self, dag: TrackDAG, auto_queue: bool = False) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Initializes the ExecutionEngine.
|
||||
Args:
|
||||
dag: The TrackDAG instance to manage.
|
||||
@@ -190,6 +198,7 @@ class ExecutionEngine:
|
||||
def tick(self) -> List[Ticket]:
|
||||
"""
|
||||
|
||||
|
||||
Evaluates the DAG and returns a list of tasks that are currently 'ready' for execution.
|
||||
If auto_queue is enabled, tasks without 'step_mode' will be marked as 'in_progress'.
|
||||
Returns:
|
||||
@@ -204,6 +213,7 @@ class ExecutionEngine:
|
||||
def approve_task(self, task_id: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Manually transitions a task from 'todo' to 'in_progress' if its dependencies are met.
|
||||
Args:
|
||||
task_id: The ID of the task to approve.
|
||||
@@ -216,6 +226,7 @@ class ExecutionEngine:
|
||||
def update_task_status(self, task_id: str, status: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Force-updates the status of a specific task.
|
||||
Args:
|
||||
task_id: The ID of the task.
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ def parse_hunk_header(line: str) -> Optional[tuple[int, int, int, int]]:
|
||||
|
||||
def parse_diff(diff_text: str) -> List[DiffFile]:
|
||||
"""
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_diff_viewer.py:test_diff_line_classification, tests/test_diff_viewer.py:test_parse_diff_empty, tests/test_diff_viewer.py:test_parse_diff_none, tests/test_diff_viewer.py:test_parse_diff_with_context, tests/test_diff_viewer.py:test_parse_multiple_files, tests/test_diff_viewer.py:test_parse_simple_diff, tests/test_diff_viewer.py:test_render_diff_text_immediate]
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_diff_viewer.py:test_diff_line_classification, tests/test_diff_viewer.py:test_parse_diff_empty, tests/test_diff_viewer.py:test_parse_diff_none, tests/test_diff_viewer.py:test_parse_diff_with_context, tests/test_diff_viewer.py:test_parse_multiple_files, tests/test_diff_viewer.py:test_parse_simple_diff]
|
||||
"""
|
||||
if not diff_text or not diff_text.strip():
|
||||
return []
|
||||
|
||||
+16
-4
File diff suppressed because one or more lines are too long
+18
-1
@@ -47,6 +47,7 @@ _ast_cache: Dict[str, Tuple[float, tree_sitter.Tree]] = {}
|
||||
class ASTParser:
|
||||
"""
|
||||
|
||||
|
||||
Parser for extracting AST-based views of source code.
|
||||
Currently supports Python.
|
||||
"""
|
||||
@@ -69,6 +70,7 @@ class ASTParser:
|
||||
|
||||
def parse(self, code: str) -> tree_sitter.Tree:
|
||||
"""
|
||||
|
||||
Parse the given code and return the tree-sitter Tree.
|
||||
[C: src/mcp_client.py:_search_file, src/mcp_client.py:derive_code_path, src/mcp_client.py:py_check_syntax, src/mcp_client.py:py_get_class_summary, src/mcp_client.py:py_get_definition, src/mcp_client.py:py_get_docstring, src/mcp_client.py:py_get_imports, src/mcp_client.py:py_get_signature, src/mcp_client.py:py_get_symbol_info, src/mcp_client.py:py_get_var_declaration, src/mcp_client.py:py_set_signature, src/mcp_client.py:py_set_var_declaration, src/mcp_client.py:py_update_definition, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/rag_engine.py:RAGEngine._chunk_code, src/summarize.py:_summarise_python, tests/test_ast_parser.py:test_ast_parser_parse, tests/test_tree_sitter_setup.py:test_tree_sitter_python_setup]
|
||||
"""
|
||||
@@ -185,6 +187,7 @@ class ASTParser:
|
||||
def get_skeleton(self, code: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a skeleton of a Python file (preserving docstrings, stripping function bodies).
|
||||
[C: src/mcp_client.py:py_get_skeleton, src/mcp_client.py:ts_c_get_skeleton, src/mcp_client.py:ts_cpp_get_skeleton, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_skeleton_c, tests/test_ast_parser.py:test_ast_parser_get_skeleton_cpp, tests/test_ast_parser.py:test_ast_parser_get_skeleton_python, tests/test_context_pruner.py:test_ast_caching, tests/test_context_pruner.py:test_performance_large_file]
|
||||
"""
|
||||
@@ -238,6 +241,7 @@ class ASTParser:
|
||||
def get_curated_view(self, code: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a curated skeleton of a Python file.
|
||||
Preserves function bodies if they have @core_logic decorator or # [HOT] comment.
|
||||
Otherwise strips bodies but preserves docstrings.
|
||||
@@ -317,6 +321,7 @@ class ASTParser:
|
||||
def get_targeted_view(self, code: str, function_names: List[str], path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a targeted view of the code including only the specified functions
|
||||
and their dependencies up to depth 2.
|
||||
[C: src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_targeted_view, tests/test_context_pruner.py:test_class_targeted_extraction, tests/test_context_pruner.py:test_targeted_extraction]
|
||||
@@ -482,6 +487,7 @@ class ASTParser:
|
||||
#region: Symbol Extraction
|
||||
def get_definition(self, code: str, name: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
Returns the full source code for a specific definition by name.
|
||||
Supports 'ClassName::method' or 'method' for C++.
|
||||
[C: src/mcp_client.py:trace, src/mcp_client.py:ts_c_get_definition, src/mcp_client.py:ts_cpp_get_definition, tests/test_ast_parser.py:test_ast_parser_get_definition_c, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp_template]
|
||||
@@ -492,6 +498,9 @@ class ASTParser:
|
||||
parts = re.split(r'::|\.', name)
|
||||
|
||||
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
|
||||
"""
|
||||
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
|
||||
"""
|
||||
if not target_parts:
|
||||
return None
|
||||
target = target_parts[0]
|
||||
@@ -578,6 +587,7 @@ class ASTParser:
|
||||
def get_signature(self, code: str, name: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns only the signature part of a function or method.
|
||||
For C/C++, this is the code from the start of the definition until the block start '{'.
|
||||
[C: src/mcp_client.py:ts_c_get_signature, src/mcp_client.py:ts_cpp_get_signature, tests/test_ast_parser.py:test_ast_parser_get_signature_c, tests/test_ast_parser.py:test_ast_parser_get_signature_cpp]
|
||||
@@ -588,6 +598,9 @@ class ASTParser:
|
||||
parts = re.split(r'::|\.', name)
|
||||
|
||||
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
|
||||
"""
|
||||
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
|
||||
"""
|
||||
if not target_parts:
|
||||
return None
|
||||
target = target_parts[0]
|
||||
@@ -687,6 +700,7 @@ class ASTParser:
|
||||
def get_code_outline(self, code: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a hierarchical outline of the code (classes, structs, functions, methods).
|
||||
[C: src/mcp_client.py:ts_c_get_code_outline, src/mcp_client.py:ts_cpp_get_code_outline, tests/test_ast_parser.py:test_ast_parser_get_code_outline_c, tests/test_ast_parser.py:test_ast_parser_get_code_outline_cpp]
|
||||
"""
|
||||
@@ -728,6 +742,7 @@ class ASTParser:
|
||||
def update_definition(self, code: str, name: str, new_content: str, path: Optional[str] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Surgically replace the definition of a class or function by name.
|
||||
[C: src/mcp_client.py:ts_c_update_definition, src/mcp_client.py:ts_cpp_update_definition, tests/test_ast_parser.py:test_ast_parser_update_definition_cpp]
|
||||
"""
|
||||
@@ -737,6 +752,9 @@ class ASTParser:
|
||||
parts = re.split(r'::|\.', name)
|
||||
|
||||
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
|
||||
"""
|
||||
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
|
||||
"""
|
||||
if not target_parts:
|
||||
return None
|
||||
target = target_parts[0]
|
||||
@@ -830,4 +848,3 @@ def reset_client() -> None:
|
||||
def get_file_id(path: Path) -> Optional[str]:
|
||||
return None
|
||||
#endregion: Module Level Utilities
|
||||
|
||||
|
||||
+7
-1
@@ -16,7 +16,10 @@ class FuzzyAnchor:
|
||||
|
||||
@classmethod
|
||||
def create_slice(cls, text: str, start_line: int, end_line: int) -> dict:
|
||||
"""start_line and end_line are 1-based."""
|
||||
"""
|
||||
start_line and end_line are 1-based.
|
||||
[C: src/gui_2.py:App._populate_auto_slices, src/gui_2.py:App._render_text_viewer_window, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_create_slice_basic, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_anchor_mismatch_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_exact_match, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_deleted_before_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_inserted_before, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_multiple_lines_changed, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations]
|
||||
"""
|
||||
lines = text.splitlines()
|
||||
s_idx = max(0, start_line - 1)
|
||||
e_idx = min(len(lines), end_line)
|
||||
@@ -33,6 +36,9 @@ class FuzzyAnchor:
|
||||
|
||||
@classmethod
|
||||
def resolve_slice(cls, text: str, slice_data: dict) -> Optional[Tuple[int, int]]:
|
||||
"""
|
||||
[C: tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_anchor_mismatch_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_exact_match, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_deleted_before_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_inserted_before, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_multiple_lines_changed]
|
||||
"""
|
||||
lines = text.splitlines()
|
||||
# 1. Try exact match
|
||||
s_idx = slice_data["start_line"] - 1
|
||||
|
||||
@@ -45,10 +45,12 @@ from typing import Optional, Callable, Any
|
||||
class GeminiCliAdapter:
|
||||
"""
|
||||
|
||||
|
||||
Adapter for the Gemini CLI that parses streaming JSON output.
|
||||
"""
|
||||
def __init__(self, binary_path: str = "gemini"):
|
||||
"""
|
||||
|
||||
Initializes the adapter with the path to the gemini CLI executable.
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
@@ -61,9 +63,10 @@ class GeminiCliAdapter:
|
||||
model: str | None = None, stream_callback: Optional[Callable[[str], None]] = None) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
|
||||
Sends a message to the Gemini CLI and processes the streaming JSON output.
|
||||
Uses non-blocking line-by-line reading to allow stream_callback.
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/multi_agent_conductor.py:run_worker_lifecycle, src/native_orchestrator.py:NativeOrchestrator.execute_ticket, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_get_history_bleed_stats, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
|
||||
"""
|
||||
start_time = time.time()
|
||||
command_parts = [self.binary_path]
|
||||
@@ -192,6 +195,7 @@ class GeminiCliAdapter:
|
||||
def count_tokens(self, contents: list[str]) -> int:
|
||||
"""
|
||||
|
||||
|
||||
Provides a character-based token estimation for the Gemini CLI.
|
||||
Uses 4 chars/token as a conservative average.
|
||||
[C: tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_count_tokens_fallback]
|
||||
|
||||
+49
-4
@@ -265,8 +265,9 @@ class App:
|
||||
|
||||
def run(self) -> None:
|
||||
"""
|
||||
|
||||
Initializes the ImGui runner and starts the main application loop.
|
||||
[C: simulation/sim_base.py:run_sim, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/project_manager.py:get_git_log, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
[C: simulation/sim_base.py:run_sim, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
"""
|
||||
if "--headless" in sys.argv:
|
||||
print("Headless mode active")
|
||||
@@ -544,6 +545,7 @@ class App:
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
|
||||
Cleanly shuts down the app's background tasks and saves state.
|
||||
[C: tests/conftest.py:app_instance, tests/conftest.py:mock_app]
|
||||
"""
|
||||
@@ -1026,6 +1028,7 @@ class App:
|
||||
|
||||
def _handle_history_logic(self) -> None:
|
||||
"""
|
||||
|
||||
Logic for capturing UI state for undo/redo.
|
||||
"""
|
||||
if self._is_applying_snapshot:
|
||||
@@ -2567,6 +2570,9 @@ class App:
|
||||
#region: Context Management
|
||||
|
||||
def _render_files_and_media(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_fast_render.py:test_render_files_and_media_fast]
|
||||
"""
|
||||
avail = imgui.get_content_region_avail().y
|
||||
if not hasattr(self, 'files_screenshots_split'): self.files_screenshots_split = 0.65
|
||||
split_y = int(avail * self.files_screenshots_split)
|
||||
@@ -2787,6 +2793,9 @@ class App:
|
||||
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_screenshots_panel")
|
||||
|
||||
def _render_context_composition_panel(self) -> None:
|
||||
"""
|
||||
[C: tests/test_auto_slices.py:test_add_all_triggers_auto_slices, tests/test_gui_fast_render.py:test_render_context_composition_panel_fast]
|
||||
"""
|
||||
if imgui.collapsing_header("Context Composition##panel"):
|
||||
total_lines, total_ast = self._update_context_file_stats()
|
||||
self._render_context_batch_actions(total_lines, total_ast)
|
||||
@@ -2799,6 +2808,9 @@ class App:
|
||||
self._render_context_presets()
|
||||
|
||||
def _render_ast_inspector_modal(self) -> None:
|
||||
"""
|
||||
[C: tests/test_ast_inspector_extended.py:test_ast_inspector_line_range_parsing]
|
||||
"""
|
||||
if self._show_ast_inspector:
|
||||
imgui.open_popup('AST Inspector')
|
||||
self._show_ast_inspector = False
|
||||
@@ -2933,6 +2945,9 @@ class App:
|
||||
if not opened: self.ui_inspecting_ast_file = None
|
||||
|
||||
def _render_add_context_files_modal(self) -> None:
|
||||
"""
|
||||
[C: tests/test_auto_slices.py:test_add_selected_triggers_auto_slices]
|
||||
"""
|
||||
if imgui.begin_popup_modal("Select Context Files", None, imgui.WindowFlags_.always_auto_resize)[0]:
|
||||
imgui.text("Select files from project to add to context:")
|
||||
if imgui.begin_child("ctx_picker_list", imgui.ImVec2(600, 300), True):
|
||||
@@ -3018,6 +3033,9 @@ class App:
|
||||
if imgui.button(f"Delete##{name}"): self.delete_context_preset(name)
|
||||
|
||||
def _populate_auto_slices(self, f_item: models.FileItem) -> None:
|
||||
"""
|
||||
[C: tests/test_auto_slices.py:test_populate_auto_slices_basic]
|
||||
"""
|
||||
from src import mcp_client
|
||||
import re
|
||||
mcp_client.configure([{"path": f_item.path}])
|
||||
@@ -3415,7 +3433,7 @@ class App:
|
||||
|
||||
def _render_discussion_panel(self) -> None:
|
||||
"""
|
||||
[C: tests/test_discussion_takes_gui.py:test_render_discussion_tabs, tests/test_discussion_takes_gui.py:test_switching_discussion_via_tabs, tests/test_gui_discussion_tabs.py:test_discussion_tabs_rendered, tests/test_gui_phase4.py:test_track_discussion_toggle, tests/test_gui_symbol_navigation.py:test_render_discussion_panel_symbol_lookup]
|
||||
[C: tests/test_discussion_takes_gui.py:test_render_discussion_tabs, tests/test_discussion_takes_gui.py:test_switching_discussion_via_tabs, tests/test_gui_discussion_tabs.py:test_discussion_tabs_rendered, tests/test_gui_fast_render.py:test_render_discussion_panel_fast, tests/test_gui_phase4.py:test_track_discussion_toggle, tests/test_gui_symbol_navigation.py:test_render_discussion_panel_symbol_lookup]
|
||||
"""
|
||||
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_discussion_panel")
|
||||
self._render_thinking_indicator()
|
||||
@@ -3654,6 +3672,7 @@ class App:
|
||||
|
||||
def _render_synthesis_panel(self) -> None:
|
||||
"""
|
||||
|
||||
Renders a panel for synthesizing multiple discussion takes.
|
||||
[C: tests/test_gui_synthesis.py:test_render_synthesis_panel]
|
||||
"""
|
||||
@@ -4678,7 +4697,10 @@ def hello():
|
||||
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"Error loading beads: {e}")
|
||||
|
||||
def _render_mma_dashboard(self) -> None:
|
||||
"""Main MMA dashboard interface."""
|
||||
"""
|
||||
Main MMA dashboard interface.
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_ask_dialog_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_mma_approval_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_spawn_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_no_approval_badge_when_idle]
|
||||
"""
|
||||
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_mma_dashboard")
|
||||
self._render_mma_focus_selector()
|
||||
imgui.separator()
|
||||
@@ -4708,6 +4730,9 @@ def hello():
|
||||
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_mma_dashboard")
|
||||
|
||||
def _render_mma_focus_selector(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
imgui.text("Focus Agent:"); imgui.same_line()
|
||||
focus_label = self.ui_focus_agent or "All"
|
||||
if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview):
|
||||
@@ -4795,6 +4820,9 @@ def hello():
|
||||
imgui.end_popup()
|
||||
|
||||
def _render_mma_track_summary(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
is_nerv = theme.is_nerv_active()
|
||||
track_name = self.active_track.description if self.active_track else "None"
|
||||
if getattr(self, "ui_project_execution_mode", "native") == "beads": track_name = "Beads Graph"
|
||||
@@ -4823,15 +4851,24 @@ def hello():
|
||||
imgui.text_colored(C_LBL, "ETA:"); imgui.same_line(); imgui.text_colored(C_VAL, f"~{int(eta_mins)}m ({remaining} tickets remaining)")
|
||||
|
||||
def _render_mma_epic_planner(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
imgui.text_colored(C_LBL, 'Epic Planning (Tier 1)')
|
||||
_, self.ui_epic_input = imgui.input_text_multiline('##epic_input', self.ui_epic_input, imgui.ImVec2(-1, 80))
|
||||
if imgui.button('Plan Epic (Tier 1)', imgui.ImVec2(-1, 0)): self._cb_plan_epic()
|
||||
|
||||
def _render_mma_conductor_setup(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
if imgui.button("Run Setup Scan"): self._cb_run_conductor_setup()
|
||||
if self.ui_conductor_setup_summary: imgui.input_text_multiline("##setup_summary", self.ui_conductor_setup_summary, imgui.ImVec2(-1, 120), imgui.InputTextFlags_.read_only)
|
||||
|
||||
def _render_mma_track_browser(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
imgui.text("Track Browser")
|
||||
if imgui.begin_table("mma_tracks_table", 4, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable):
|
||||
imgui.table_setup_column("Title"); imgui.table_setup_column("Status"); imgui.table_setup_column("Progress"); imgui.table_setup_column("Actions"); imgui.table_headers_row()
|
||||
@@ -4858,6 +4895,9 @@ def hello():
|
||||
self.ui_new_track_name = ""; self.ui_new_track_desc = ""
|
||||
|
||||
def _render_mma_global_controls(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
changed, self.mma_step_mode = imgui.checkbox("Step Mode (HITL)", self.mma_step_mode)
|
||||
imgui.same_line(); imgui.text(f"Status: {self.mma_status.upper()}")
|
||||
if self.controller and hasattr(self.controller, 'engine') and self.controller.engine and hasattr(self.controller.engine, '_pause_event'):
|
||||
@@ -4876,6 +4916,9 @@ def hello():
|
||||
if imgui.button("Go to Approval"): pass
|
||||
|
||||
def _render_mma_usage_section(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
imgui.text("Tier Usage (Tokens & Cost)")
|
||||
if imgui.begin_table("mma_usage", 5, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg):
|
||||
imgui.table_setup_column("Tier"); imgui.table_setup_column("Model"); imgui.table_setup_column("Input"); imgui.table_setup_column("Output"); imgui.table_setup_column("Est. Cost"); imgui.table_headers_row()
|
||||
@@ -4939,6 +4982,9 @@ def hello():
|
||||
if imgui.button(f"Delete##{self.ui_selected_ticket_id}"): self.active_tickets = [t for t in self.active_tickets if str(t.get('id', '')) != self.ui_selected_ticket_id]; self.ui_selected_ticket_id = None; self._push_mma_state_update()
|
||||
|
||||
def _render_mma_agent_streams(self) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
|
||||
"""
|
||||
imgui.text("Agent Streams")
|
||||
if imgui.begin_tab_bar("mma_streams_tabs"):
|
||||
for tier, label, sep_flag_attr in [("Tier 1", "Tier 1", "ui_separate_tier1"), ("Tier 2", "Tier 2 (Tech Lead)", "ui_separate_tier2"), ("Tier 3", None, "ui_separate_tier3"), ("Tier 4", "Tier 4 (QA)", "ui_separate_tier4")]:
|
||||
@@ -5145,4 +5191,3 @@ def main() -> None:
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
+12
-7
@@ -21,7 +21,7 @@ class UISnapshot:
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""
|
||||
[C: src/models.py:ExternalEditorConfig.to_dict, src/models.py:MCPConfiguration.to_dict, src/models.py:RAGConfig.to_dict, src/models.py:ToolPreset.to_dict, src/models.py:Track.to_dict, src/models.py:TrackState.to_dict, src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
||||
[C: src/models.py:ContextPreset.to_dict, src/models.py:ExternalEditorConfig.to_dict, src/models.py:MCPConfiguration.to_dict, src/models.py:RAGConfig.to_dict, src/models.py:ToolPreset.to_dict, src/models.py:Track.to_dict, src/models.py:TrackState.to_dict, src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_context_presets_models.py:test_context_preset_serialization, tests/test_context_presets_models.py:test_file_view_preset_serialization, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_round_trip_annotations, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_serialization_with_annotations, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_history_manager.py:TestHistoryManager.test_snapshot_roundtrip, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
||||
"""
|
||||
return {
|
||||
"ai_input": self.ai_input,
|
||||
@@ -42,7 +42,7 @@ class UISnapshot:
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "UISnapshot":
|
||||
"""
|
||||
[C: src/models.py:ExternalEditorConfig.from_dict, src/models.py:MCPConfiguration.from_dict, src/models.py:RAGConfig.from_dict, src/models.py:ToolPreset.from_dict, src/models.py:Track.from_dict, src/models.py:TrackState.from_dict, src/models.py:load_mcp_config, src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
||||
[C: src/models.py:ContextPreset.from_dict, src/models.py:ExternalEditorConfig.from_dict, src/models.py:MCPConfiguration.from_dict, src/models.py:RAGConfig.from_dict, src/models.py:ToolPreset.from_dict, src/models.py:Track.from_dict, src/models.py:TrackState.from_dict, src/models.py:load_mcp_config, src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_context_presets_models.py:test_context_preset_from_dict_legacy, tests/test_context_presets_models.py:test_context_preset_serialization, tests/test_context_presets_models.py:test_file_view_preset_serialization, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_deserialization_with_annotations, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_round_trip_annotations, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_history_manager.py:TestHistoryManager.test_snapshot_roundtrip, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
||||
"""
|
||||
return cls(
|
||||
ai_input=data.get("ai_input", ""),
|
||||
@@ -78,9 +78,10 @@ class HistoryManager:
|
||||
def push(self, state: typing.Any, description: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Pushes a new state to the undo stack and clears the redo stack.
|
||||
If the undo stack exceeds max_capacity, the oldest state is removed.
|
||||
[C: tests/test_history.py:test_jump_to_undo, tests/test_history.py:test_max_capacity, tests/test_history.py:test_push_state, tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo]
|
||||
[C: tests/test_history.py:test_jump_to_undo, tests/test_history.py:test_max_capacity, tests/test_history.py:test_push_state, tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions, tests/test_history_manager.py:TestHistoryManager.test_jump_to_undo, tests/test_history_manager.py:TestHistoryManager.test_push_and_undo, tests/test_history_manager.py:TestHistoryManager.test_push_clears_redo_stack, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo]
|
||||
"""
|
||||
entry = HistoryEntry(state=state, description=description)
|
||||
self._undo_stack.append(entry)
|
||||
@@ -91,9 +92,10 @@ class HistoryManager:
|
||||
def undo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]:
|
||||
"""
|
||||
|
||||
|
||||
Undoes the last action by moving the current_state to the redo stack
|
||||
and returning the top of the undo stack.
|
||||
[C: tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo]
|
||||
[C: tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_push_and_undo, tests/test_history_manager.py:TestHistoryManager.test_push_clears_redo_stack, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo, tests/test_history_manager.py:TestHistoryManager.test_undo_no_history_returns_none]
|
||||
"""
|
||||
if not self._undo_stack:
|
||||
return None
|
||||
@@ -105,9 +107,10 @@ class HistoryManager:
|
||||
def redo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]:
|
||||
"""
|
||||
|
||||
|
||||
Redoes the last undone action by moving the current_state to the undo stack
|
||||
and returning the top of the redo stack.
|
||||
[C: tests/test_history.py:test_undo_redo]
|
||||
[C: tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_redo_no_history_returns_none, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo]
|
||||
"""
|
||||
if not self._redo_stack:
|
||||
return None
|
||||
@@ -126,8 +129,9 @@ class HistoryManager:
|
||||
|
||||
def get_history(self) -> typing.List[typing.Dict[str, typing.Any]]:
|
||||
"""
|
||||
|
||||
Returns a list of descriptions and timestamps for the undo stack.
|
||||
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state]
|
||||
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions]
|
||||
"""
|
||||
return [
|
||||
{"description": e.description, "timestamp": e.timestamp}
|
||||
@@ -137,9 +141,10 @@ class HistoryManager:
|
||||
def jump_to_undo(self, index: int, current_state: typing.Any, current_description: str = "Before Jump") -> typing.Optional[HistoryEntry]:
|
||||
"""
|
||||
|
||||
|
||||
Jumps to a specific state in the undo stack by moving subsequent states
|
||||
and the current_state to the redo stack.
|
||||
[C: tests/test_history.py:test_jump_to_undo]
|
||||
[C: tests/test_history.py:test_jump_to_undo, tests/test_history_manager.py:TestHistoryManager.test_jump_to_undo]
|
||||
"""
|
||||
if index < 0 or index >= len(self._undo_stack):
|
||||
return None
|
||||
|
||||
@@ -5,6 +5,9 @@ from imgui_bundle import imgui_node_editor
|
||||
def child(id_str: str, size_x: float = 0, size_y: float = 0, flags: int = 0): return _ScopeChild(id_str, size_x, size_y, flags)
|
||||
class _ScopeChild:
|
||||
def __init__(self, id_str: str, size_x: float | imgui.ImVec2, size_y: float, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._id = id_str
|
||||
# Check if size_x is likely an ImVec2 without using isinstance (which breaks with mocks)
|
||||
if hasattr(size_x, 'x') and hasattr(size_x, 'y'):
|
||||
@@ -30,6 +33,9 @@ class _ScopeGroup:
|
||||
def id(str_id: str): return _ScopeId(str_id)
|
||||
class _ScopeId:
|
||||
def __init__(self, str_id: str):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._id = str_id
|
||||
def __enter__(self):
|
||||
imgui.push_id(self._id)
|
||||
@@ -40,6 +46,9 @@ class _ScopeId:
|
||||
def menu(label: str): return _ScopeMenu(label)
|
||||
class _ScopeMenu:
|
||||
def __init__(self, label: str):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._label = label
|
||||
self._active = False
|
||||
def __enter__(self):
|
||||
@@ -53,6 +62,9 @@ class _ScopeMenu:
|
||||
def menu_bar(): return _ScopeMenuBar()
|
||||
class _ScopeMenuBar:
|
||||
def __init__(self):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._active = False
|
||||
def __enter__(self):
|
||||
self._active = imgui.begin_menu_bar()
|
||||
@@ -65,6 +77,9 @@ class _ScopeMenuBar:
|
||||
def node(name: str): return _ScopeNode(name)
|
||||
class _ScopeNode:
|
||||
def __init__(self, name: str):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._name = name
|
||||
def __enter__(self):
|
||||
return imgui_node_editor.begin(self._name)
|
||||
@@ -75,6 +90,9 @@ class _ScopeNode:
|
||||
def popup(id_str: str): return _ScopePopup(id_str)
|
||||
class _ScopePopup:
|
||||
def __init__(self, id_str: str):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._id = id_str
|
||||
self._active = False
|
||||
def __enter__(self):
|
||||
@@ -88,6 +106,9 @@ class _ScopePopup:
|
||||
def popup_modal(name: str, visible: bool = True, flags: int = 0): return _ScopePopupModal(name, visible, flags)
|
||||
class _ScopePopupModal:
|
||||
def __init__(self, name: str, visible: bool, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._name = name
|
||||
self._visible = visible
|
||||
self._flags = flags
|
||||
@@ -104,6 +125,9 @@ class _ScopePopupModal:
|
||||
def style_color(col: int, val: Any): return _ScopeStyleColor(col, val)
|
||||
class _ScopeStyleColor:
|
||||
def __init__(self, col: int, val: Any):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._col = col
|
||||
self._val = val
|
||||
def __enter__(self):
|
||||
@@ -115,6 +139,9 @@ class _ScopeStyleColor:
|
||||
def style_var(var: int, val: Any): return _ScopeStyleVar(var, val)
|
||||
class _ScopeStyleVar:
|
||||
def __init__(self, var: int, val: Any):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._var = var
|
||||
self._val = val
|
||||
def __enter__(self):
|
||||
@@ -126,6 +153,9 @@ class _ScopeStyleVar:
|
||||
def table(name: str, columns: int, flags: int = 0): return _ScopeTable(name, columns, flags)
|
||||
class _ScopeTable:
|
||||
def __init__(self, name: str, columns: int, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._name = name
|
||||
self._columns = columns
|
||||
self._flags = flags
|
||||
@@ -141,6 +171,9 @@ class _ScopeTable:
|
||||
def tab_bar(id_str: str, flags: int = 0): return _ScopeTabBar(id_str, flags)
|
||||
class _ScopeTabBar:
|
||||
def __init__(self, id_str: str, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._id = id_str
|
||||
self._flags = flags
|
||||
self._active = False
|
||||
@@ -155,6 +188,9 @@ class _ScopeTabBar:
|
||||
def tab_item(label: str, flags: int = 0): return _ScopeTabItem(label, flags)
|
||||
class _ScopeTabItem:
|
||||
def __init__(self, label: str, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._label = label
|
||||
self._flags = flags
|
||||
self._expanded = False
|
||||
@@ -170,6 +206,9 @@ class _ScopeTabItem:
|
||||
def text_wrap(wrap_pos: float = 0.0): return _ScopeTextWrap(wrap_pos)
|
||||
class _ScopeTextWrap:
|
||||
def __init__(self, wrap_pos: float):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._wrap_pos = wrap_pos
|
||||
def __enter__(self):
|
||||
imgui.push_text_wrap_pos(self._wrap_pos)
|
||||
@@ -188,6 +227,9 @@ class _ScopeTooltip:
|
||||
def tree_node_ex(label: str, flags: int = 0): return _ScopeTreeNodeEx(label, flags)
|
||||
class _ScopeTreeNodeEx:
|
||||
def __init__(self, label: str, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._label = label
|
||||
self._flags = flags
|
||||
self._opened = False
|
||||
@@ -202,6 +244,9 @@ class _ScopeTreeNodeEx:
|
||||
def window(name: str, visible: bool = True, flags: int = 0): return _ScopeWindow(name, visible, flags)
|
||||
class _ScopeWindow:
|
||||
def __init__(self, name: str, visible: bool, flags: int):
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._name = name
|
||||
self._visible = visible
|
||||
self._flags = flags
|
||||
|
||||
@@ -8,6 +8,7 @@ from src.log_registry import LogRegistry
|
||||
class LogPruner:
|
||||
"""
|
||||
|
||||
|
||||
Handles the automated deletion of old and insignificant session logs.
|
||||
Ensures that only whitelisted or significant sessions (based on size/content)
|
||||
are preserved long-term.
|
||||
@@ -16,6 +17,7 @@ class LogPruner:
|
||||
def __init__(self, log_registry: LogRegistry, logs_dir: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Initializes the LogPruner.
|
||||
|
||||
Args:
|
||||
@@ -29,6 +31,7 @@ class LogPruner:
|
||||
def prune(self, max_age_days: int = 1, min_size_kb: int = 2) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Prunes old and small session directories from the logs directory.
|
||||
|
||||
Deletes session directories that meet the following criteria:
|
||||
|
||||
+9
-1
@@ -48,6 +48,7 @@ from typing import Any
|
||||
class LogRegistry:
|
||||
"""
|
||||
|
||||
|
||||
Manages a persistent registry of session logs using a TOML file.
|
||||
Tracks session paths, start times, whitelisting status, and metadata.
|
||||
"""
|
||||
@@ -55,6 +56,7 @@ class LogRegistry:
|
||||
def __init__(self, registry_path: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Initializes the LogRegistry with a path to the registry file.
|
||||
|
||||
Args:
|
||||
@@ -73,6 +75,7 @@ class LogRegistry:
|
||||
def load_registry(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Loads the registry data from the TOML file into memory.
|
||||
Handles date/time conversions from TOML-native formats to strings for consistency.
|
||||
"""
|
||||
@@ -102,6 +105,7 @@ class LogRegistry:
|
||||
def save_registry(self) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Serializes and saves the current registry data to the TOML file.
|
||||
Converts internal datetime objects to ISO format strings for compatibility.
|
||||
[C: tests/test_logging_e2e.py:test_logging_e2e]
|
||||
@@ -137,6 +141,7 @@ class LogRegistry:
|
||||
def register_session(self, session_id: str, path: str, start_time: datetime | str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Registers a new session in the registry.
|
||||
|
||||
Args:
|
||||
@@ -163,6 +168,7 @@ class LogRegistry:
|
||||
def update_session_metadata(self, session_id: str, message_count: int, errors: int, size_kb: int, whitelisted: bool, reason: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Updates metadata fields for an existing session.
|
||||
|
||||
Args:
|
||||
@@ -197,6 +203,7 @@ class LogRegistry:
|
||||
def is_session_whitelisted(self, session_id: str) -> bool:
|
||||
"""
|
||||
|
||||
|
||||
Checks if a specific session is marked as whitelisted.
|
||||
|
||||
Args:
|
||||
@@ -215,6 +222,7 @@ class LogRegistry:
|
||||
def update_auto_whitelist_status(self, session_id: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Analyzes session logs and updates whitelisting status based on heuristics.
|
||||
Sessions are automatically whitelisted if they contain error keywords,
|
||||
have a high message count, or exceed a size threshold.
|
||||
@@ -275,6 +283,7 @@ class LogRegistry:
|
||||
def get_old_non_whitelisted_sessions(self, cutoff_datetime: datetime) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Retrieves a list of sessions that are older than a specific cutoff time
|
||||
and are not marked as whitelisted.
|
||||
Also includes non-whitelisted sessions that are empty (message_count=0 or size_kb=0).
|
||||
@@ -316,4 +325,3 @@ class LogRegistry:
|
||||
'start_time': start_time_raw
|
||||
})
|
||||
return old_sessions
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from typing import Optional, Dict, Callable
|
||||
class MarkdownRenderer:
|
||||
"""
|
||||
|
||||
|
||||
Hybrid Markdown renderer that uses imgui_md for text/headers
|
||||
and ImGuiColorTextEdit for syntax-highlighted code blocks.
|
||||
"""
|
||||
@@ -67,8 +68,9 @@ class MarkdownRenderer:
|
||||
|
||||
def render(self, text: str, context_id: str = "default") -> None:
|
||||
"""
|
||||
|
||||
Render Markdown text with code block interception.
|
||||
[C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
[C: src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
"""
|
||||
if not text:
|
||||
return
|
||||
@@ -167,7 +169,7 @@ def get_renderer() -> MarkdownRenderer:
|
||||
|
||||
def render(text: str, context_id: str = "default") -> None:
|
||||
"""
|
||||
[C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
[C: src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
|
||||
"""
|
||||
get_renderer().render(text, context_id)
|
||||
|
||||
|
||||
+29
-5
@@ -102,12 +102,13 @@ perf_monitor_callback: Optional[Callable[[], dict[str, Any]]] = None
|
||||
def configure(file_items: list[dict[str, Any]], extra_base_dirs: list[str] | None = None) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Build the allowlist from aggregate file_items.
|
||||
Called by ai_client before each send so the list reflects the current project.
|
||||
|
||||
file_items : list of dicts from aggregate.build_file_items()
|
||||
extra_base_dirs : additional directory roots to allow traversal of
|
||||
[C: tests/conftest.py:reset_ai_client, tests/test_arch_boundary_phase1.py:TestArchBoundaryPhase1.test_mcp_client_whitelist_enforcement, tests/test_mcp_client_beads.py:test_bd_mcp_tools]
|
||||
[C: tests/conftest.py:reset_ai_client, tests/test_arch_boundary_phase1.py:TestArchBoundaryPhase1.test_mcp_client_whitelist_enforcement, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_py_struct_tools.py:test_mcp_dispatch_errors, tests/test_py_struct_tools.py:test_mcp_dispatch_integration]
|
||||
"""
|
||||
global _allowed_paths, _base_dirs, _primary_base_dir
|
||||
_allowed_paths = set()
|
||||
@@ -131,6 +132,7 @@ def configure(file_items: list[dict[str, Any]], extra_base_dirs: list[str] | Non
|
||||
def _is_allowed(path: Path) -> bool:
|
||||
"""
|
||||
|
||||
|
||||
Return True if `path` is within the allowlist.
|
||||
A path is allowed if:
|
||||
- it is explicitly in _allowed_paths, OR
|
||||
@@ -180,6 +182,7 @@ def _is_allowed(path: Path) -> bool:
|
||||
def _resolve_and_check(raw_path: str) -> tuple[Path | None, str]:
|
||||
"""
|
||||
|
||||
|
||||
Resolve raw_path and verify it passes the allowlist check.
|
||||
Returns (resolved_path, error_string). error_string is empty on success.
|
||||
"""
|
||||
@@ -243,6 +246,7 @@ def list_directory(path: str) -> str:
|
||||
def search_files(path: str, pattern: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Search for files matching a glob pattern within path.
|
||||
pattern examples: '*.py', '**/*.toml', 'src/**/*.rs'
|
||||
"""
|
||||
@@ -274,6 +278,7 @@ def search_files(path: str, pattern: str) -> str:
|
||||
def get_file_summary(path: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Return the heuristic summary for a file (same as the initial context block).
|
||||
For .py files: imports, classes, methods, functions, constants.
|
||||
For .toml: table keys. For .md: headings. Others: line count + preview.
|
||||
@@ -294,6 +299,7 @@ def get_file_summary(path: str) -> str:
|
||||
def py_get_skeleton(path: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a skeleton of a Python file (preserving docstrings, stripping function bodies).
|
||||
"""
|
||||
p, err = _resolve_and_check(path)
|
||||
@@ -314,6 +320,7 @@ def py_get_skeleton(path: str) -> str:
|
||||
|
||||
def ts_c_get_skeleton(path: str) -> str:
|
||||
"""
|
||||
|
||||
Returns a skeleton of a C file.
|
||||
[C: tests/test_ts_c_tools.py:test_ts_c_get_skeleton]
|
||||
"""
|
||||
@@ -331,8 +338,9 @@ def ts_c_get_skeleton(path: str) -> str:
|
||||
|
||||
def ts_cpp_get_skeleton(path: str) -> str:
|
||||
"""
|
||||
|
||||
Returns a skeleton of a C++ file.
|
||||
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_skeleton]
|
||||
[C: tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_skeleton]
|
||||
"""
|
||||
p, err = _resolve_and_check(path)
|
||||
if err: return err
|
||||
@@ -349,6 +357,7 @@ def ts_cpp_get_skeleton(path: str) -> str:
|
||||
def py_get_code_outline(path: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns a hierarchical outline of a code file (classes, functions, methods with line ranges).
|
||||
"""
|
||||
p, err = _resolve_and_check(path)
|
||||
@@ -367,6 +376,7 @@ def py_get_code_outline(path: str) -> str:
|
||||
|
||||
def ts_c_get_code_outline(path: str) -> str:
|
||||
"""
|
||||
|
||||
Returns a hierarchical outline of a C file.
|
||||
[C: tests/test_ts_c_tools.py:test_ts_c_get_code_outline]
|
||||
"""
|
||||
@@ -384,8 +394,9 @@ def ts_c_get_code_outline(path: str) -> str:
|
||||
|
||||
def ts_cpp_get_code_outline(path: str) -> str:
|
||||
"""
|
||||
|
||||
Returns a hierarchical outline of a C++ file.
|
||||
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_code_outline]
|
||||
[C: tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_code_outline]
|
||||
"""
|
||||
p, err = _resolve_and_check(path)
|
||||
if err: return err
|
||||
@@ -415,8 +426,9 @@ def ts_c_get_definition(path: str, name: str) -> str:
|
||||
|
||||
def ts_cpp_get_definition(path: str, name: str) -> str:
|
||||
"""
|
||||
|
||||
Returns the source code for a specific definition in a C++ file.
|
||||
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp]
|
||||
[C: tests/test_ast_masking_core.py:test_ast_masking_gencpp_samples, tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp]
|
||||
"""
|
||||
p, err = _resolve_and_check(path)
|
||||
if err: return err
|
||||
@@ -478,6 +490,7 @@ def ts_c_update_definition(path: str, name: str, new_content: str) -> str:
|
||||
|
||||
def ts_cpp_update_definition(path: str, name: str, new_content: str) -> str:
|
||||
"""
|
||||
|
||||
Surgically replace the definition of a class or function in a C++ file.
|
||||
[C: tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp]
|
||||
"""
|
||||
@@ -537,6 +550,7 @@ def set_file_slice(path: str, start_line: int, end_line: int, new_content: str)
|
||||
def edit_file(path: str, old_string: str, new_string: str, replace_all: bool = False) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Replace exact string match in a file. Preserves indentation and line endings.
|
||||
Drop-in replacement for native edit tool that destroys 1-space indentation.
|
||||
"""
|
||||
@@ -595,6 +609,7 @@ def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
|
||||
def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
|
||||
"""
|
||||
|
||||
|
||||
Returns (source_code, line_number) for a specific class, function, or method definition.
|
||||
If not found, returns an error string.
|
||||
"""
|
||||
@@ -622,6 +637,7 @@ def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
|
||||
def py_get_definition(path: str, name: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns the source code for a specific class, function, or method definition.
|
||||
path: Path to the code file.
|
||||
name: Name of the definition to retrieve (e.g., 'MyClass', 'my_function', 'MyClass.my_method').
|
||||
@@ -797,6 +813,7 @@ def py_set_var_declaration(path: str, name: str, new_declaration: str) -> str:
|
||||
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
|
||||
"""
|
||||
|
||||
|
||||
Returns the git diff for a file or directory.
|
||||
base_rev: The base revision (default: HEAD)
|
||||
head_rev: The head revision (optional)
|
||||
@@ -1151,6 +1168,7 @@ def fetch_url(url: str) -> str:
|
||||
|
||||
def get_ui_performance() -> str:
|
||||
"""
|
||||
|
||||
Returns current UI performance metrics (FPS, Frame Time, CPU, Input Lag).
|
||||
[C: tests/test_mcp_perf_tool.py:test_mcp_perf_tool_retrieval]
|
||||
"""
|
||||
@@ -1262,6 +1280,7 @@ class ExternalMCPManager:
|
||||
|
||||
async def add_server(self, config: models.MCPServerConfig):
|
||||
"""
|
||||
|
||||
Add and start a new MCP server from a configuration object.
|
||||
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external]
|
||||
"""
|
||||
@@ -1274,6 +1293,7 @@ class ExternalMCPManager:
|
||||
|
||||
async def stop_all(self):
|
||||
"""
|
||||
|
||||
Stop all managed MCP servers and clear the registry.
|
||||
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
|
||||
"""
|
||||
@@ -1283,6 +1303,7 @@ class ExternalMCPManager:
|
||||
|
||||
def get_all_tools(self) -> dict:
|
||||
"""
|
||||
|
||||
Retrieve a dictionary of all tools available across all managed servers.
|
||||
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
|
||||
"""
|
||||
@@ -1298,6 +1319,7 @@ class ExternalMCPManager:
|
||||
|
||||
async def async_dispatch(self, tool_name: str, tool_input: dict) -> str:
|
||||
"""
|
||||
|
||||
Dispatch a tool call to the appropriate external MCP server asynchronously.
|
||||
[C: src/rag_engine.py:RAGEngine._async_search_mcp, tests/test_external_mcp.py:test_external_mcp_real_process]
|
||||
"""
|
||||
@@ -1310,6 +1332,7 @@ _external_mcp_manager = ExternalMCPManager()
|
||||
|
||||
def get_external_mcp_manager() -> ExternalMCPManager:
|
||||
"""
|
||||
|
||||
Retrieve the global ExternalMCPManager instance.
|
||||
[C: tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
|
||||
"""
|
||||
@@ -1319,8 +1342,9 @@ def get_external_mcp_manager() -> ExternalMCPManager:
|
||||
def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Dispatch an MCP tool call by name. Returns the result as a string.
|
||||
[C: tests/test_gemini_cli_edge_cases.py:test_gemini_cli_parameter_resilience, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_mcp_ts_integration.py:test_ts_c_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_update_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_update_definition_dispatch]
|
||||
[C: tests/test_gemini_cli_edge_cases.py:test_gemini_cli_parameter_resilience, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_mcp_ts_integration.py:test_ts_c_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_update_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_update_definition_dispatch, tests/test_py_struct_tools.py:test_mcp_dispatch_errors, tests/test_py_struct_tools.py:test_mcp_dispatch_integration]
|
||||
"""
|
||||
# Handle aliases
|
||||
path = str(tool_input.get("path", tool_input.get("file_path", tool_input.get("dir_path", ""))))
|
||||
|
||||
+147
File diff suppressed because one or more lines are too long
@@ -48,6 +48,7 @@ from src.dag_engine import TrackDAG, ExecutionEngine
|
||||
class WorkerPool:
|
||||
"""
|
||||
|
||||
|
||||
Manages a pool of worker threads with a concurrency limit.
|
||||
"""
|
||||
def __init__(self, max_workers: int = 4):
|
||||
@@ -59,6 +60,7 @@ class WorkerPool:
|
||||
def spawn(self, ticket_id: str, target: Callable, args: tuple) -> Optional[threading.Thread]:
|
||||
"""
|
||||
|
||||
|
||||
Spawns a new worker thread if the pool is not full.
|
||||
Returns the thread object or None if full.
|
||||
[C: tests/test_parallel_execution.py:test_worker_pool_completion_cleanup, tests/test_parallel_execution.py:test_worker_pool_limit, tests/test_parallel_execution.py:test_worker_pool_tracking]
|
||||
@@ -108,6 +110,7 @@ class WorkerPool:
|
||||
class ConductorEngine:
|
||||
"""
|
||||
|
||||
|
||||
Orchestrates the execution of tickets within a track.
|
||||
"""
|
||||
|
||||
@@ -148,6 +151,7 @@ class ConductorEngine:
|
||||
|
||||
def pause(self) -> None:
|
||||
"""
|
||||
|
||||
Pauses the pipeline execution.
|
||||
[C: tests/test_pipeline_pause.py:test_pause_method, tests/test_pipeline_pause.py:test_resume_method]
|
||||
"""
|
||||
@@ -155,6 +159,7 @@ class ConductorEngine:
|
||||
|
||||
def resume(self) -> None:
|
||||
"""
|
||||
|
||||
Resumes the pipeline execution.
|
||||
[C: tests/test_pipeline_pause.py:test_resume_method]
|
||||
"""
|
||||
@@ -162,6 +167,7 @@ class ConductorEngine:
|
||||
|
||||
def approve_task(self, task_id: str) -> None:
|
||||
"""
|
||||
|
||||
Manually transition todo to in_progress and mark engine dirty.
|
||||
[C: tests/test_execution_engine.py:test_execution_engine_approve_task, tests/test_execution_engine.py:test_execution_engine_step_mode]
|
||||
"""
|
||||
@@ -170,6 +176,7 @@ class ConductorEngine:
|
||||
|
||||
def update_task_status(self, task_id: str, status: str) -> None:
|
||||
"""
|
||||
|
||||
Force-update ticket status and mark engine dirty.
|
||||
[C: tests/test_arch_boundary_phase3.py:TestArchBoundaryPhase3.test_manual_unblock_restores_todo, tests/test_execution_engine.py:test_execution_engine_auto_queue, tests/test_execution_engine.py:test_execution_engine_basic_flow, tests/test_execution_engine.py:test_execution_engine_status_persistence, tests/test_execution_engine.py:test_execution_engine_update_nonexistent_task]
|
||||
"""
|
||||
@@ -178,6 +185,7 @@ class ConductorEngine:
|
||||
|
||||
def kill_worker(self, ticket_id: str) -> None:
|
||||
"""
|
||||
|
||||
Sets the abort event for a worker and attempts to join its thread.
|
||||
[C: tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread]
|
||||
"""
|
||||
@@ -213,6 +221,7 @@ class ConductorEngine:
|
||||
def parse_json_tickets(self, json_str: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Parses a JSON string of ticket definitions (Godot ECS Flat List format)
|
||||
and populates the Track's ticket list.
|
||||
[C: tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_orchestration_logic.py:test_conductor_engine_parse_json_tickets]
|
||||
@@ -244,11 +253,12 @@ class ConductorEngine:
|
||||
def run(self, md_content: str = "", max_ticks: Optional[int] = None) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Main execution loop using the DAG engine.
|
||||
Args:
|
||||
md_content: The full markdown context (history + files) for AI workers.
|
||||
max_ticks: Optional limit on number of iterations (for testing).
|
||||
[C: simulation/sim_base.py:run_sim, src/project_manager.py:get_git_commit, src/project_manager.py:get_git_log, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
[C: simulation/sim_base.py:run_sim, src/project_manager.py:get_git_commit, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
"""
|
||||
tick_count = 0
|
||||
while True:
|
||||
@@ -368,6 +378,7 @@ def _queue_put(event_queue: events.AsyncEventQueue, event_name: str, payload) ->
|
||||
def confirm_execution(payload: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> bool:
|
||||
"""
|
||||
|
||||
|
||||
Pushes an approval request to the GUI and waits for response.
|
||||
"""
|
||||
dialog_container = [None]
|
||||
@@ -391,6 +402,7 @@ def confirm_execution(payload: str, event_queue: events.AsyncEventQueue, ticket_
|
||||
def confirm_spawn(role: str, prompt: str, context_md: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> Tuple[bool, str, str]:
|
||||
"""
|
||||
|
||||
|
||||
Pushes a spawn approval request to the GUI and waits for response.
|
||||
Returns (approved, modified_prompt, modified_context)
|
||||
[C: tests/test_spawn_interception_v2.py:run_confirm]
|
||||
@@ -432,6 +444,7 @@ def confirm_spawn(role: str, prompt: str, context_md: str, event_queue: events.A
|
||||
def run_worker_lifecycle(ticket: Ticket, context: WorkerContext, context_files: List[str] | None = None, event_queue: events.AsyncEventQueue | None = None, engine: Optional['ConductorEngine'] = None, md_content: str = "") -> None:
|
||||
"""
|
||||
|
||||
|
||||
Simulates the lifecycle of a single agent working on a ticket.
|
||||
Calls the AI client and updates the ticket status based on the response.
|
||||
Args:
|
||||
|
||||
@@ -12,6 +12,7 @@ from src import paths
|
||||
def get_track_history_summary() -> str:
|
||||
"""
|
||||
|
||||
|
||||
Scans conductor/archive/ and conductor/tracks/ to build a summary of past work.
|
||||
[C: tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary_missing_files]
|
||||
"""
|
||||
@@ -59,6 +60,7 @@ def get_track_history_summary() -> str:
|
||||
def generate_tracks(user_request: str, project_config: dict[str, Any], file_items: list[dict[str, Any]], history_summary: Optional[str] = None) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Tier 1 (Strategic PM) call.
|
||||
Analyzes the project state and user request to generate a list of Tracks.
|
||||
[C: tests/test_orchestration_logic.py:test_generate_tracks, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_malformed_json, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_markdown_wrapped, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_success, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_generate_tracks_with_history]
|
||||
|
||||
@@ -39,6 +39,9 @@ class CodeOutliner:
|
||||
pass
|
||||
|
||||
def outline(self, code: str) -> str:
|
||||
"""
|
||||
[C: tests/test_outline_tool.py:test_code_outliner_imgui_scopes, tests/test_outline_tool.py:test_code_outliner_nested_ifs, tests/test_outline_tool.py:test_code_outliner_type_hints]
|
||||
"""
|
||||
code = code.lstrip(chr(0xFEFF))
|
||||
try:
|
||||
tree = ast.parse(code)
|
||||
@@ -55,6 +58,9 @@ class CodeOutliner:
|
||||
|
||||
count = [0]
|
||||
def walk(node: ast.AST, indent: int = 0) -> None:
|
||||
"""
|
||||
[C: src/summarize.py:_summarise_python]
|
||||
"""
|
||||
count[0] += 1
|
||||
if count[0] > 100000:
|
||||
raise Exception("Infinite loop detected! " + str(type(node)))
|
||||
|
||||
@@ -184,6 +184,9 @@ def get_track_state_dir(track_id: str, project_path: Optional[str] = None) -> Pa
|
||||
return get_tracks_dir(project_path) / track_id
|
||||
|
||||
def get_archive_dir(project_path: Optional[str] = None) -> Path:
|
||||
"""
|
||||
[C: tests/test_paths.py:test_conductor_dir_project_relative]
|
||||
"""
|
||||
return get_conductor_dir(project_path) / "archive"
|
||||
|
||||
def _resolve_path_info(env_var: str, config_key: str, default: str) -> dict[str, Any]:
|
||||
@@ -210,6 +213,7 @@ def get_full_path_info() -> dict[str, dict[str, Any]]:
|
||||
|
||||
def reset_resolved() -> None:
|
||||
"""
|
||||
|
||||
For testing only - clear cached resolutions.
|
||||
[C: tests/conftest.py:reset_paths, tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_gui_phase3.py:test_conductor_setup_scan, tests/test_paths.py:reset_paths, tests/test_project_paths.py:test_get_all_tracks_project_specific, tests/test_project_paths.py:test_get_conductor_dir_default, tests/test_project_paths.py:test_get_conductor_dir_project_specific_with_toml]
|
||||
"""
|
||||
|
||||
@@ -87,6 +87,7 @@ def get_monitor() -> PerformanceMonitor:
|
||||
class PerformanceMonitor:
|
||||
"""
|
||||
|
||||
|
||||
Tracks application performance metrics like FPS, frame time, and CPU usage.
|
||||
Supports thread-safe tracking for individual components with efficient moving averages.
|
||||
"""
|
||||
@@ -233,6 +234,7 @@ class PerformanceMonitor:
|
||||
|
||||
def get_metrics(self) -> dict[str, float]:
|
||||
"""
|
||||
|
||||
Returns current metrics and their moving averages. Thread-safe.
|
||||
[C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_perf_dag.py:test_dag_performance, tests/test_performance_monitor.py:test_perf_monitor_basic_timing, tests/test_performance_monitor.py:test_perf_monitor_component_timing, tests/test_performance_monitor.py:test_perf_monitor_extended_metrics, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager]
|
||||
"""
|
||||
@@ -269,8 +271,9 @@ class PerformanceMonitor:
|
||||
|
||||
def get_history(self, key: str) -> List[float]:
|
||||
"""
|
||||
|
||||
Returns a snapshot of the full history buffer for a specific metric key.
|
||||
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state]
|
||||
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions]
|
||||
"""
|
||||
with self._lock:
|
||||
if key in self._history:
|
||||
@@ -281,6 +284,7 @@ class PerformanceMonitor:
|
||||
|
||||
def scope(self, name: str) -> PerformanceScope:
|
||||
"""
|
||||
|
||||
Returns a context manager for timing a component.
|
||||
[C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager]
|
||||
"""
|
||||
|
||||
@@ -26,6 +26,7 @@ class PersonaManager:
|
||||
|
||||
def load_all(self) -> Dict[str, Persona]:
|
||||
"""
|
||||
|
||||
Merges global and project personas into a single dictionary.
|
||||
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
|
||||
"""
|
||||
|
||||
@@ -19,6 +19,7 @@ class PresetManager:
|
||||
|
||||
def load_all(self) -> Dict[str, Preset]:
|
||||
"""
|
||||
|
||||
Merges global and project presets into a single dictionary.
|
||||
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
|
||||
"""
|
||||
@@ -45,6 +46,7 @@ class PresetManager:
|
||||
|
||||
def save_preset(self, preset: Preset, scope: str = "project") -> None:
|
||||
"""
|
||||
|
||||
Saves a preset to either the global or project-specific TOML file.
|
||||
[C: tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_preset_manager.py:test_save_preset_project_no_root, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
|
||||
"""
|
||||
|
||||
@@ -30,6 +30,7 @@ def parse_ts(s: str) -> Optional[datetime.datetime]:
|
||||
|
||||
def entry_to_str(entry: dict[str, Any]) -> str:
|
||||
"""
|
||||
|
||||
Serialise a disc entry dict -> stored string.
|
||||
[C: tests/test_thinking_persistence.py:test_entry_to_str_with_thinking]
|
||||
"""
|
||||
@@ -50,6 +51,7 @@ def entry_to_str(entry: dict[str, Any]) -> str:
|
||||
|
||||
def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Parse a stored string back to a disc entry dict.
|
||||
[C: tests/test_thinking_persistence.py:test_str_to_entry_with_thinking]
|
||||
"""
|
||||
@@ -152,6 +154,7 @@ def default_project(name: str = "unnamed") -> dict[str, Any]:
|
||||
|
||||
def get_history_path(project_path: Union[str, Path]) -> Path:
|
||||
"""
|
||||
|
||||
Return the Path to the sibling history TOML file for a given project.
|
||||
[C: tests/test_history_management.py:test_save_separation]
|
||||
"""
|
||||
@@ -161,6 +164,7 @@ def get_history_path(project_path: Union[str, Path]) -> Path:
|
||||
def load_project(path: Union[str, Path]) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
|
||||
Load a project TOML file.
|
||||
Automatically migrates legacy 'discussion' keys to a sibling history file.
|
||||
[C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_migration_on_load, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip]
|
||||
@@ -185,6 +189,7 @@ def load_project(path: Union[str, Path]) -> dict[str, Any]:
|
||||
|
||||
def load_history(project_path: Union[str, Path]) -> dict[str, Any]:
|
||||
"""
|
||||
|
||||
Load the segregated discussion history from its dedicated TOML file.
|
||||
[C: tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments]
|
||||
"""
|
||||
@@ -196,6 +201,7 @@ def load_history(project_path: Union[str, Path]) -> dict[str, Any]:
|
||||
|
||||
def clean_nones(data: Any) -> Any:
|
||||
"""
|
||||
|
||||
Recursively remove None values from a dictionary/list.
|
||||
[C: tests/test_thinking_persistence.py:test_clean_nones_removes_thinking]
|
||||
"""
|
||||
@@ -208,6 +214,7 @@ def clean_nones(data: Any) -> Any:
|
||||
def save_project(proj: dict[str, Any], path: Union[str, Path], disc_data: Optional[dict[str, Any]] = None) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Save the project TOML.
|
||||
If 'discussion' is present in proj, it is moved to the sibling history file.
|
||||
[C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_save_separation, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip, tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments]
|
||||
@@ -270,6 +277,7 @@ def flat_config(proj: dict[str, Any], disc_name: Optional[str] = None, track_id:
|
||||
|
||||
def save_context_preset(project_dict: dict, preset_name: str, files: list[str], screenshots: list[str]) -> None:
|
||||
"""
|
||||
|
||||
Save a named context preset (files + screenshots) into the project dict.
|
||||
[C: tests/test_context_presets.py:test_save_context_preset]
|
||||
"""
|
||||
@@ -282,6 +290,7 @@ def save_context_preset(project_dict: dict, preset_name: str, files: list[str],
|
||||
|
||||
def load_context_preset(project_dict: dict, preset_name: str) -> dict:
|
||||
"""
|
||||
|
||||
Return the files and screenshots for a named preset.
|
||||
[C: tests/test_context_presets.py:test_load_context_preset, tests/test_context_presets.py:test_load_nonexistent_preset]
|
||||
"""
|
||||
@@ -291,6 +300,7 @@ def load_context_preset(project_dict: dict, preset_name: str) -> dict:
|
||||
|
||||
def delete_context_preset(project_dict: dict, preset_name: str) -> None:
|
||||
"""
|
||||
|
||||
Remove a named preset if it exists.
|
||||
[C: tests/test_context_presets.py:test_delete_context_preset, tests/test_context_presets.py:test_delete_nonexistent_preset_no_error]
|
||||
"""
|
||||
@@ -301,6 +311,7 @@ def delete_context_preset(project_dict: dict, preset_name: str) -> None:
|
||||
def save_track_state(track_id: str, state: 'TrackState', base_dir: Union[str, Path] = ".") -> None:
|
||||
"""
|
||||
|
||||
|
||||
Saves a TrackState object to conductor/tracks/<track_id>/state.toml.
|
||||
[C: tests/test_project_manager_tracks.py:test_get_all_tracks_with_state, tests/test_track_state_persistence.py:test_track_state_persistence]
|
||||
"""
|
||||
@@ -314,6 +325,7 @@ def save_track_state(track_id: str, state: 'TrackState', base_dir: Union[str, Pa
|
||||
def load_track_state(track_id: str, base_dir: Union[str, Path] = ".") -> Optional['TrackState']:
|
||||
"""
|
||||
|
||||
|
||||
Loads a TrackState object from conductor/tracks/<track_id>/state.toml.
|
||||
[C: tests/test_track_state_persistence.py:test_track_state_persistence]
|
||||
"""
|
||||
@@ -328,6 +340,7 @@ def load_track_state(track_id: str, base_dir: Union[str, Path] = ".") -> Optiona
|
||||
def load_track_history(track_id: str, base_dir: Union[str, Path] = ".") -> list[str]:
|
||||
"""
|
||||
|
||||
|
||||
Loads the discussion history for a specific track from its state.toml.
|
||||
Returns a list of entry strings formatted with @timestamp.
|
||||
"""
|
||||
@@ -346,6 +359,7 @@ def load_track_history(track_id: str, base_dir: Union[str, Path] = ".") -> list[
|
||||
def save_track_history(track_id: str, history: list[str], base_dir: Union[str, Path] = ".") -> None:
|
||||
"""
|
||||
|
||||
|
||||
Saves the discussion history for a specific track to its state.toml.
|
||||
'history' is expected to be a list of formatted strings.
|
||||
"""
|
||||
@@ -360,6 +374,7 @@ def save_track_history(track_id: str, history: list[str], base_dir: Union[str, P
|
||||
def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Scans the conductor/tracks/ directory and returns a list of dictionaries
|
||||
containing track metadata: 'id', 'title', 'status', 'complete', 'total',
|
||||
and 'progress' (0.0 to 1.0).
|
||||
@@ -428,6 +443,7 @@ def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
|
||||
def calculate_track_progress(tickets: list) -> dict:
|
||||
"""
|
||||
|
||||
|
||||
Calculates track progress based on ticket statuses.
|
||||
percentage (float), completed (int), total (int), in_progress (int), blocked (int), todo (int)
|
||||
[C: tests/test_progress_viz.py:test_calculate_track_progress_all_completed, tests/test_progress_viz.py:test_calculate_track_progress_all_todo, tests/test_progress_viz.py:test_calculate_track_progress_empty, tests/test_progress_viz.py:test_calculate_track_progress_mixed]
|
||||
@@ -463,6 +479,7 @@ def calculate_track_progress(tickets: list) -> dict:
|
||||
def branch_discussion(project_dict: dict, source_id: str, new_id: str, message_index: int) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Creates a new discussion in project_dict['discussion']['discussions'] by copying
|
||||
the history from source_id up to (and including) message_index, and sets active to new_id.
|
||||
[C: tests/test_discussion_takes.py:TestDiscussionTakes.test_branch_discussion_creates_new_take]
|
||||
@@ -483,6 +500,7 @@ def branch_discussion(project_dict: dict, source_id: str, new_id: str, message_i
|
||||
|
||||
def promote_take(project_dict: dict, take_id: str, new_id: str) -> None:
|
||||
"""
|
||||
|
||||
Renames a take_id to new_id in the discussions dict.
|
||||
[C: tests/test_discussion_takes.py:TestDiscussionTakes.test_promote_take_renames_discussion]
|
||||
"""
|
||||
|
||||
@@ -44,6 +44,7 @@ def _now_ts() -> str:
|
||||
def open_session(label: Optional[str] = None) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Called once at GUI startup. Creates the log directories if needed and
|
||||
opens the log files for this session within a sub-directory.
|
||||
[C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs, tests/test_session_logger_optimization.py:test_session_directory_and_subdirectories_creation, tests/test_session_logger_reset.py:test_reset_session, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry]
|
||||
@@ -89,6 +90,7 @@ def open_session(label: Optional[str] = None) -> None:
|
||||
|
||||
def close_session() -> None:
|
||||
"""
|
||||
|
||||
Flush and close all log files. Called on clean exit.
|
||||
[C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:e2e_setup, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:temp_session_setup, tests/test_session_logger_reset.py:temp_logs, tests/test_session_logging.py:temp_logs]
|
||||
"""
|
||||
@@ -136,6 +138,7 @@ def log_api_hook(method: str, path: str, payload: str) -> None:
|
||||
def log_comms(entry: dict[str, Any]) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Append one comms entry to the comms log file as a JSON-L line.
|
||||
Thread-safe (GIL + line-buffered file).
|
||||
[C: tests/test_logging_e2e.py:test_logging_e2e]
|
||||
@@ -150,6 +153,7 @@ def log_comms(entry: dict[str, Any]) -> None:
|
||||
def log_tool_call(script: str, result: str, script_path: Optional[str]) -> Optional[str]:
|
||||
"""
|
||||
|
||||
|
||||
Append a tool-call record to the toolcalls log and write the PS1 script to
|
||||
the session's scripts directory. Returns the path of the written script file.
|
||||
[C: tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts]
|
||||
@@ -194,6 +198,7 @@ def log_tool_call(script: str, result: str, script_path: Optional[str]) -> Optio
|
||||
def log_tool_output(content: str) -> Optional[str]:
|
||||
"""
|
||||
|
||||
|
||||
Save tool output content to a unique file in the session's outputs directory.
|
||||
Returns the path of the written file.
|
||||
[C: tests/test_session_logger_optimization.py:test_log_tool_output_returns_none_if_no_session, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs]
|
||||
|
||||
@@ -3,6 +3,7 @@ from imgui_bundle import imgui
|
||||
def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: imgui.ImVec2, color: imgui.ImVec4, shadow_size: float = 10.0, rounding: float = 0.0) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Simulates a soft shadow effect by drawing multiple concentric rounded rectangles
|
||||
with decreasing alpha values. This is a faux-shader effect using primitive batching.
|
||||
"""
|
||||
|
||||
@@ -54,6 +54,7 @@ def _build_subprocess_env() -> dict[str, str]:
|
||||
def run_powershell(script: str, base_dir: str, qa_callback: Optional[Callable[[str], str]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Run a PowerShell script with working directory set to base_dir.
|
||||
Returns a string combining stdout, stderr, and exit code.
|
||||
Environment is configured via mcp_env.toml (project root).
|
||||
|
||||
@@ -154,6 +154,7 @@ _SUMMARISERS: dict[str, Callable[[Path, str], str]] = {
|
||||
def summarise_file(path: Path, content: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Return a compact markdown summary string for a single file.
|
||||
`content` is the already-read file text (or an error string).
|
||||
[C: tests/test_subagent_summarization.py:test_summarise_file_integration]
|
||||
@@ -193,6 +194,7 @@ def summarise_file(path: Path, content: str) -> str:
|
||||
def summarise_items(file_items: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
||||
|
||||
Given a list of file_item dicts (as returned by aggregate.build_file_items),
|
||||
return a parallel list of dicts with an added `summary` key.
|
||||
"""
|
||||
@@ -212,6 +214,7 @@ def summarise_items(file_items: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
def build_summary_markdown(file_items: list[dict[str, Any]]) -> str:
|
||||
"""
|
||||
|
||||
|
||||
Build a compact markdown string of file summaries, suitable for the
|
||||
initial <context> block instead of full file contents.
|
||||
"""
|
||||
|
||||
@@ -5,6 +5,7 @@ from typing import Optional, Dict
|
||||
|
||||
def get_file_hash(content: str) -> str:
|
||||
"""
|
||||
|
||||
Returns SHA256 hash of the content.
|
||||
[C: tests/test_summary_cache.py:test_get_file_hash, tests/test_summary_cache.py:test_summary_cache]
|
||||
"""
|
||||
@@ -13,6 +14,7 @@ def get_file_hash(content: str) -> str:
|
||||
class SummaryCache:
|
||||
"""
|
||||
|
||||
|
||||
A hash-based cache for file summaries to avoid redundant processing.
|
||||
Invalidates when content hash changes.
|
||||
"""
|
||||
@@ -28,8 +30,9 @@ class SummaryCache:
|
||||
|
||||
def load(self) -> None:
|
||||
"""
|
||||
|
||||
Loads cache from disk.
|
||||
[C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry, tests/test_visual_sim_gui_ux.py:test_gui_track_creation]
|
||||
[C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry]
|
||||
"""
|
||||
if self.cache_file.exists():
|
||||
try:
|
||||
@@ -49,6 +52,7 @@ class SummaryCache:
|
||||
|
||||
def get_summary(self, file_path: str, content_hash: str) -> Optional[str]:
|
||||
"""
|
||||
|
||||
Returns cached summary if hash matches, otherwise None.
|
||||
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
|
||||
"""
|
||||
@@ -62,6 +66,7 @@ class SummaryCache:
|
||||
|
||||
def set_summary(self, file_path: str, content_hash: str, summary: str) -> None:
|
||||
"""
|
||||
|
||||
Stores summary in cache and saves to disk.
|
||||
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
|
||||
"""
|
||||
@@ -80,6 +85,7 @@ class SummaryCache:
|
||||
|
||||
def clear(self) -> None:
|
||||
"""
|
||||
|
||||
Clears the cache both in-memory and on disk.
|
||||
[C: tests/conftest.py:reset_ai_client]
|
||||
"""
|
||||
|
||||
@@ -23,6 +23,7 @@ from src.theme_nerv_fx import CRTFilter, AlertPulsing, StatusFlicker
|
||||
|
||||
def _c(r: int, g: int, b: int, a: int = 255) -> tuple[float, float, float, float]:
|
||||
"""
|
||||
|
||||
Convert 0-255 RGBA to 0.0-1.0 floats.
|
||||
[C: src/theme_nerv.py:module]
|
||||
"""
|
||||
@@ -283,7 +284,9 @@ def set_child_transparency(val: float) -> None:
|
||||
def apply(palette_name: str) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Apply a named palette by setting all ImGui style colors and applying global professional styling.
|
||||
[C: tests/test_theme.py:test_theme_apply_sets_rounding_and_padding]
|
||||
"""
|
||||
global _current_palette
|
||||
_current_palette = palette_name
|
||||
|
||||
@@ -63,6 +63,7 @@ NERV_PALETTE = {
|
||||
|
||||
def apply_nerv() -> None:
|
||||
"""
|
||||
|
||||
Apply NERV theme with hard edges and specific palette.
|
||||
[C: tests/test_theme_nerv.py:test_apply_nerv_sets_rounding_and_colors]
|
||||
"""
|
||||
|
||||
@@ -5,6 +5,7 @@ from src.models import ThinkingSegment
|
||||
def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
|
||||
"""
|
||||
|
||||
|
||||
Parses thinking segments from text and returns (segments, response_content).
|
||||
Support extraction of thinking traces from <thinking>...</thinking>, <thought>...</thought>,
|
||||
and blocks prefixed with Thinking:.
|
||||
|
||||
@@ -59,6 +59,7 @@ class ToolPresetManager:
|
||||
|
||||
def load_all(self) -> Dict[str, ToolPreset]:
|
||||
"""
|
||||
|
||||
Backward compatibility for load_all().
|
||||
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
|
||||
"""
|
||||
|
||||
@@ -26,6 +26,7 @@ class WorkspaceManager:
|
||||
|
||||
def load_all_profiles(self) -> Dict[str, WorkspaceProfile]:
|
||||
"""
|
||||
|
||||
Merges global and project profiles into a single dictionary.
|
||||
[C: tests/test_workspace_manager.py:test_delete_profile, tests/test_workspace_manager.py:test_load_all_profiles_merged, tests/test_workspace_manager.py:test_save_profile_global_and_project]
|
||||
"""
|
||||
|
||||
@@ -71,6 +71,7 @@ class VerificationLogger:
|
||||
def reset_paths() -> Generator[None, None, None]:
|
||||
"""
|
||||
|
||||
|
||||
Autouse fixture that resets the paths global state before each test.
|
||||
"""
|
||||
from src import paths
|
||||
@@ -82,6 +83,7 @@ def reset_paths() -> Generator[None, None, None]:
|
||||
def reset_ai_client() -> Generator[None, None, None]:
|
||||
"""
|
||||
|
||||
|
||||
Autouse fixture that resets the ai_client global state before each test.
|
||||
This is critical for preventing state pollution between tests.
|
||||
"""
|
||||
@@ -131,6 +133,7 @@ def kill_process_tree(pid: int | None) -> None:
|
||||
def mock_app() -> Generator[App, None, None]:
|
||||
"""
|
||||
|
||||
|
||||
Mock version of the App for simple unit tests that don't need a loop.
|
||||
"""
|
||||
with (
|
||||
@@ -163,6 +166,7 @@ def mock_app() -> Generator[App, None, None]:
|
||||
def app_instance() -> Generator[App, None, None]:
|
||||
"""
|
||||
|
||||
|
||||
Centralized App instance with all external side effects mocked.
|
||||
Matches the pattern used in test_token_viz.py and test_gui_phase4.py.
|
||||
[C: tests/test_gui2_events.py:test_app_subscribes_to_events]
|
||||
@@ -199,6 +203,7 @@ def app_instance() -> Generator[App, None, None]:
|
||||
def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
|
||||
"""
|
||||
|
||||
|
||||
Session-scoped fixture that starts sloppy.py with --enable-test-hooks.
|
||||
Includes high-signal environment telemetry and workspace isolation.
|
||||
"""
|
||||
|
||||
@@ -10,6 +10,7 @@ from src.api_hook_client import ApiHookClient
|
||||
|
||||
def wait_for_value(client, field, expected, timeout=5):
|
||||
"""
|
||||
|
||||
Polls the GUI state until a field matches the expected value.
|
||||
[C: tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
|
||||
@@ -3,6 +3,7 @@ from src import ai_client
|
||||
def test_list_models_gemini_cli() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that 'ai_client.list_models' correctly returns a list of models
|
||||
for the 'gemini_cli' provider.
|
||||
"""
|
||||
|
||||
@@ -37,6 +37,7 @@ def app_controller(tmp_session_dir):
|
||||
def test_on_comms_entry_tool_result_offloading(app_controller, tmp_session_dir):
|
||||
"""
|
||||
|
||||
|
||||
Test that _on_comms_entry offloads tool_result output to a separate file.
|
||||
"""
|
||||
output_content = "This is a large tool output that should be offloaded."
|
||||
@@ -83,6 +84,7 @@ def test_on_comms_entry_tool_result_offloading(app_controller, tmp_session_dir):
|
||||
def test_on_tool_log_offloading(app_controller, tmp_session_dir):
|
||||
"""
|
||||
|
||||
|
||||
Test that _on_tool_log calls session_logger.log_tool_call and log_tool_output.
|
||||
"""
|
||||
script = "Get-Process"
|
||||
|
||||
@@ -9,6 +9,7 @@ from src import mcp_client
|
||||
async def test_execute_tool_calls_concurrently_timing():
|
||||
"""
|
||||
|
||||
|
||||
Verifies that _execute_tool_calls_concurrently runs tools in parallel.
|
||||
Total time should be approx 0.5s for 3 tools each taking 0.5s.
|
||||
"""
|
||||
@@ -67,6 +68,7 @@ async def test_execute_tool_calls_concurrently_timing():
|
||||
async def test_execute_tool_calls_concurrently_exception_handling():
|
||||
"""
|
||||
|
||||
|
||||
Verifies that if one tool call fails, it doesn't crash the whole group if caught,
|
||||
but currently gather is used WITHOUT return_exceptions=True, so it should re-raise.
|
||||
"""
|
||||
|
||||
@@ -22,6 +22,7 @@ class TestCliToolBridgeMapping(unittest.TestCase):
|
||||
def test_mapping_from_api_format(self, mock_request: MagicMock, mock_stdout: MagicMock, mock_stdin: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that bridge correctly maps 'id', 'name', 'input' (Gemini API format)
|
||||
into tool_name and tool_input for the hook client.
|
||||
"""
|
||||
|
||||
@@ -7,6 +7,7 @@ import threading
|
||||
def test_conductor_abort_event_populated():
|
||||
"""
|
||||
|
||||
|
||||
Test that ConductorEngine populates _abort_events when spawning a worker.
|
||||
"""
|
||||
# 1. Mock WorkerPool.spawn to return a mock thread
|
||||
|
||||
@@ -4,6 +4,7 @@ from src.api_hook_client import ApiHookClient
|
||||
def simulate_conductor_phase_completion(client: ApiHookClient, track_id: str, phase_name: str) -> bool:
|
||||
"""
|
||||
|
||||
|
||||
Simulates the Conductor agent's logic for phase completion using ApiHookClient.
|
||||
"""
|
||||
try:
|
||||
@@ -24,6 +25,7 @@ def simulate_conductor_phase_completion(client: ApiHookClient, track_id: str, ph
|
||||
|
||||
def test_conductor_integrates_api_hook_client_for_verification(live_gui) -> None:
|
||||
"""
|
||||
|
||||
Verify that Conductor's simulated phase completion logic properly integrates
|
||||
with the ApiHookClient and the live Hook Server.
|
||||
"""
|
||||
|
||||
@@ -8,6 +8,7 @@ from src.models import Track
|
||||
def test_conductor_engine_initializes_empty_worker_and_abort_dicts() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that ConductorEngine correctly initializes _active_workers and _abort_events as empty dictionaries.
|
||||
"""
|
||||
# Mock the track object
|
||||
@@ -24,6 +25,7 @@ def test_conductor_engine_initializes_empty_worker_and_abort_dicts() -> None:
|
||||
def test_kill_worker_sets_abort_and_joins_thread() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test kill_worker: mock a running thread in _active_workers, call kill_worker,
|
||||
assert abort_event is set and thread is joined.
|
||||
"""
|
||||
|
||||
@@ -10,6 +10,7 @@ from src import ai_client
|
||||
def test_conductor_engine_initialization() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that ConductorEngine can be initialized with a Track.
|
||||
"""
|
||||
track = Track(id="test_track", description="Test Track")
|
||||
@@ -20,6 +21,7 @@ def test_conductor_engine_initialization() -> None:
|
||||
def test_conductor_engine_run_executes_tickets_in_order(monkeypatch: pytest.MonkeyPatch, vlogger) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run iterates through executable tickets and calls the worker lifecycle.
|
||||
"""
|
||||
ticket1 = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
|
||||
@@ -67,6 +69,7 @@ def test_conductor_engine_run_executes_tickets_in_order(monkeypatch: pytest.Monk
|
||||
def test_run_worker_lifecycle_calls_ai_client_send(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle triggers the AI client and updates ticket status on success.
|
||||
"""
|
||||
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
|
||||
@@ -88,6 +91,7 @@ def test_run_worker_lifecycle_calls_ai_client_send(monkeypatch: pytest.MonkeyPat
|
||||
def test_run_worker_lifecycle_context_injection(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle can take a context_files list and injects AST views into the prompt.
|
||||
"""
|
||||
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
|
||||
@@ -134,6 +138,7 @@ def test_run_worker_lifecycle_context_injection(monkeypatch: pytest.MonkeyPatch)
|
||||
def test_run_worker_lifecycle_handles_blocked_response(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle marks the ticket as blocked if the AI indicates it cannot proceed.
|
||||
"""
|
||||
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
|
||||
@@ -151,6 +156,7 @@ def test_run_worker_lifecycle_handles_blocked_response(monkeypatch: pytest.Monke
|
||||
def test_run_worker_lifecycle_step_mode_confirmation(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle passes confirm_execution to ai_client.send when step_mode is True.
|
||||
Verify that if confirm_execution is called (simulated by mocking ai_client.send to call its callback),
|
||||
the flow works as expected.
|
||||
@@ -188,6 +194,7 @@ def test_run_worker_lifecycle_step_mode_confirmation(monkeypatch: pytest.MonkeyP
|
||||
def test_run_worker_lifecycle_step_mode_rejection(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that if confirm_execution returns False, the logic (in ai_client, which we simulate here)
|
||||
would prevent execution. In run_worker_lifecycle, we just check if it's passed.
|
||||
"""
|
||||
@@ -213,6 +220,7 @@ def test_run_worker_lifecycle_step_mode_rejection(monkeypatch: pytest.MonkeyPatc
|
||||
def test_conductor_engine_dynamic_parsing_and_execution(monkeypatch: pytest.MonkeyPatch, vlogger) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that parse_json_tickets correctly populates the track and run executes them in dependency order.
|
||||
"""
|
||||
import json
|
||||
@@ -281,6 +289,7 @@ def test_conductor_engine_dynamic_parsing_and_execution(monkeypatch: pytest.Monk
|
||||
def test_run_worker_lifecycle_pushes_response_via_queue(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle pushes a 'response' event with the correct stream_id
|
||||
via _queue_put when event_queue is provided.
|
||||
"""
|
||||
@@ -307,6 +316,7 @@ def test_run_worker_lifecycle_pushes_response_via_queue(monkeypatch: pytest.Monk
|
||||
def test_run_worker_lifecycle_token_usage_from_comms_log(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle reads token usage from the comms log and
|
||||
updates engine.tier_usage['Tier 3'] with real input/output token counts.
|
||||
"""
|
||||
|
||||
@@ -10,6 +10,7 @@ from src.dag_engine import TrackDAG
|
||||
def test_get_ready_tasks_linear():
|
||||
"""
|
||||
|
||||
|
||||
Verifies ready tasks detection in a simple linear dependency chain.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
|
||||
@@ -22,6 +23,7 @@ def test_get_ready_tasks_linear():
|
||||
def test_get_ready_tasks_branching():
|
||||
"""
|
||||
|
||||
|
||||
Verifies ready tasks detection in a branching dependency graph where multiple tasks
|
||||
are unlocked simultaneously after a prerequisite is met.
|
||||
"""
|
||||
@@ -38,6 +40,7 @@ def test_get_ready_tasks_branching():
|
||||
def test_has_cycle_no_cycle():
|
||||
"""
|
||||
|
||||
|
||||
Validates that an acyclic graph is correctly identified as not having cycles.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
|
||||
@@ -48,6 +51,7 @@ def test_has_cycle_no_cycle():
|
||||
def test_has_cycle_direct_cycle():
|
||||
"""
|
||||
|
||||
|
||||
Validates that a direct cycle (A depends on B, B depends on A) is correctly detected.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"])
|
||||
@@ -58,6 +62,7 @@ def test_has_cycle_direct_cycle():
|
||||
def test_has_cycle_indirect_cycle():
|
||||
"""
|
||||
|
||||
|
||||
Validates that an indirect cycle (A->B->C->A) is correctly detected.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T3"])
|
||||
@@ -69,6 +74,7 @@ def test_has_cycle_indirect_cycle():
|
||||
def test_has_cycle_complex_no_cycle():
|
||||
"""
|
||||
|
||||
|
||||
Validates cycle detection in a complex graph that merges branches but remains acyclic.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
|
||||
@@ -81,6 +87,7 @@ def test_has_cycle_complex_no_cycle():
|
||||
def test_get_ready_tasks_multiple_deps():
|
||||
"""
|
||||
|
||||
|
||||
Validates that a task is not marked ready until ALL of its dependencies are completed.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="completed", assigned_to="worker1")
|
||||
@@ -95,6 +102,7 @@ def test_get_ready_tasks_multiple_deps():
|
||||
def test_topological_sort():
|
||||
"""
|
||||
|
||||
|
||||
Verifies that tasks are correctly ordered by dependencies regardless of input order.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
|
||||
@@ -107,6 +115,7 @@ def test_topological_sort():
|
||||
def test_topological_sort_cycle():
|
||||
"""
|
||||
|
||||
|
||||
Verifies that topological sorting safely aborts and raises ValueError when a cycle is present.
|
||||
"""
|
||||
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"])
|
||||
|
||||
@@ -13,6 +13,7 @@ from src import project_manager
|
||||
def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that the error message shown when credentials.toml is missing
|
||||
includes deepseek instructions.
|
||||
"""
|
||||
@@ -27,6 +28,7 @@ def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) ->
|
||||
def test_default_project_includes_reasoning_role() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that 'Reasoning' is included in the default discussion roles
|
||||
to support DeepSeek-R1 reasoning traces.
|
||||
"""
|
||||
@@ -37,6 +39,7 @@ def test_default_project_includes_reasoning_role() -> None:
|
||||
def test_gui_providers_list() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Check if 'deepseek' is in the GUI's provider list.
|
||||
"""
|
||||
from src.models import PROVIDERS
|
||||
@@ -45,6 +48,7 @@ def test_gui_providers_list() -> None:
|
||||
def test_deepseek_model_listing() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that list_models for deepseek returns expected models.
|
||||
"""
|
||||
models = ai_client.list_models("deepseek")
|
||||
@@ -54,6 +58,7 @@ def test_deepseek_model_listing() -> None:
|
||||
def test_gui_provider_list_via_hooks(live_gui: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify 'deepseek' is present in the GUI provider list using API hooks.
|
||||
"""
|
||||
from api_hook_client import ApiHookClient
|
||||
|
||||
@@ -5,6 +5,7 @@ from src import ai_client
|
||||
def test_deepseek_model_selection() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ai_client.set_provider('deepseek', 'deepseek-chat') correctly updates the internal state.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-chat")
|
||||
@@ -15,6 +16,7 @@ def test_deepseek_model_selection() -> None:
|
||||
def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ai_client.send() correctly calls the DeepSeek API and returns content.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-chat")
|
||||
@@ -34,6 +36,7 @@ def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
|
||||
def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that reasoning_content is captured and wrapped in <thinking> tags.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-reasoner")
|
||||
@@ -56,6 +59,7 @@ def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
|
||||
def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that DeepSeek provider correctly identifies and executes tool calls.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-chat")
|
||||
@@ -98,6 +102,7 @@ def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
|
||||
def test_deepseek_streaming(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that DeepSeek provider correctly aggregates streaming chunks.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-chat")
|
||||
@@ -121,6 +126,7 @@ def test_deepseek_streaming(mock_post: MagicMock) -> None:
|
||||
def test_deepseek_payload_verification(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the correct JSON payload (tools, history, params) is sent to DeepSeek.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-chat")
|
||||
@@ -149,6 +155,7 @@ def test_deepseek_payload_verification(mock_post: MagicMock) -> None:
|
||||
def test_deepseek_reasoner_payload_verification(mock_post: MagicMock) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that deepseek-reasoner payload excludes tools and temperature.
|
||||
"""
|
||||
ai_client.set_provider("deepseek", "deepseek-reasoner")
|
||||
|
||||
@@ -12,6 +12,7 @@ from src.ai_client import get_gemini_cache_stats, reset_session
|
||||
def test_get_gemini_cache_stats_with_mock_client() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that get_gemini_cache_stats correctly processes cache lists
|
||||
from a mocked client instance.
|
||||
"""
|
||||
|
||||
@@ -12,6 +12,7 @@ def app_instance(monkeypatch: pytest.MonkeyPatch) -> type[App]:
|
||||
def test_app_subscribes_to_events(app_instance: type[App]) -> None:
|
||||
"""
|
||||
|
||||
|
||||
This test checks that the App's __init__ method subscribes the necessary
|
||||
event handlers to the ai_client.events emitter.
|
||||
"""
|
||||
|
||||
@@ -3,6 +3,7 @@ from src.gui_2 import App
|
||||
def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the new consolidated Hub windows are defined in the App's show_windows.
|
||||
This ensures they will be available in the 'Windows' menu.
|
||||
"""
|
||||
@@ -20,6 +21,7 @@ def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None:
|
||||
def test_gui2_old_windows_removed_from_show_windows(app_instance: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the old fragmented windows are removed from show_windows.
|
||||
Note: Message, Response, and Tool Calls are kept as they are now optional standalone windows.
|
||||
"""
|
||||
|
||||
@@ -6,6 +6,7 @@ from src import ai_client
|
||||
def test_mcp_tool_call_is_dispatched(app_instance: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
This test verifies that when the AI returns a tool call for an MCP function,
|
||||
the ai_client correctly dispatches it to mcp_client.
|
||||
This will fail until mcp_client is properly integrated.
|
||||
|
||||
@@ -26,6 +26,7 @@ def cleanup_callback_file() -> None:
|
||||
def test_gui2_set_value_hook_works(live_gui: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Tests that the 'set_value' GUI hook is correctly implemented.
|
||||
"""
|
||||
client = ApiHookClient()
|
||||
@@ -42,6 +43,7 @@ def test_gui2_set_value_hook_works(live_gui: Any) -> None:
|
||||
def test_gui2_click_hook_works(live_gui: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Tests that the 'click' GUI hook for the 'Reset' button is implemented.
|
||||
"""
|
||||
client = ApiHookClient()
|
||||
@@ -60,6 +62,7 @@ def test_gui2_click_hook_works(live_gui: Any) -> None:
|
||||
def test_gui2_custom_callback_hook_works(live_gui: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Tests that the 'custom_callback' GUI hook is correctly implemented.
|
||||
"""
|
||||
client = ApiHookClient()
|
||||
|
||||
@@ -20,6 +20,7 @@ _shared_metrics = {}
|
||||
def test_performance_benchmarking(live_gui: tuple) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Collects performance metrics for the current GUI script over a 5-second window.
|
||||
Ensures the application does not lock up and can report its internal state.
|
||||
"""
|
||||
@@ -67,6 +68,7 @@ def test_performance_benchmarking(live_gui: tuple) -> None:
|
||||
def test_performance_baseline_check() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that we have successfully collected performance metrics for sloppy.py
|
||||
and that they meet the minimum 30 FPS baseline.
|
||||
"""
|
||||
|
||||
@@ -15,6 +15,7 @@ def test_diagnostics_panel_initialization(app_instance: Any) -> None:
|
||||
def test_diagnostics_history_updates(app_instance: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the internal performance history is updated correctly.
|
||||
This logic is inside the render loop in gui_2.py, but we can test
|
||||
the data structure and initialization.
|
||||
|
||||
@@ -11,6 +11,7 @@ from api_hook_client import ApiHookClient
|
||||
def test_idle_performance_requirements(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Requirement: GUI must maintain stable performance on idle.
|
||||
"""
|
||||
# Warmup to ensure GUI is ready
|
||||
|
||||
@@ -12,6 +12,7 @@ from src import paths
|
||||
def test_track_proposal_editing(app_instance):
|
||||
"""
|
||||
|
||||
|
||||
Verifies the structural integrity of track proposal items.
|
||||
Ensures that track proposals can be edited and removed from the active list.
|
||||
"""
|
||||
@@ -35,6 +36,7 @@ def test_track_proposal_editing(app_instance):
|
||||
def test_conductor_setup_scan(app_instance, tmp_path, monkeypatch):
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the conductor setup scan properly iterates through the conductor directory,
|
||||
counts files and lines, and identifies active tracks.
|
||||
"""
|
||||
@@ -63,6 +65,7 @@ def test_conductor_setup_scan(app_instance, tmp_path, monkeypatch):
|
||||
def test_create_track(app_instance, tmp_path):
|
||||
"""
|
||||
|
||||
|
||||
Verifies that _cb_create_track properly creates the track folder
|
||||
and populates the necessary boilerplate files (spec.md, plan.md, metadata.json).
|
||||
"""
|
||||
|
||||
@@ -3,6 +3,7 @@ import time
|
||||
def test_gui_startup_smoke(live_gui):
|
||||
"""
|
||||
|
||||
|
||||
Smoke test to ensure the GUI starts and remains running.
|
||||
"""
|
||||
proc, _ = live_gui
|
||||
|
||||
@@ -5,6 +5,7 @@ from src.api_hook_client import ApiHookClient
|
||||
def test_text_viewer_state_update(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that we can set text viewer state and it is reflected in GUI state.
|
||||
"""
|
||||
client = ApiHookClient()
|
||||
|
||||
@@ -17,6 +17,7 @@ from src.gui_2 import App
|
||||
def test_telemetry_data_updates_correctly(app_instance: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Tests that the _refresh_api_metrics method correctly updates
|
||||
the internal state for display by querying the ai_client.
|
||||
Verifies the boundary between GUI state and API state.
|
||||
@@ -43,6 +44,7 @@ def test_telemetry_data_updates_correctly(app_instance: Any) -> None:
|
||||
def test_performance_history_updates(app_instance: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify the data structure that feeds the sparkline.
|
||||
This ensures that the rolling buffer for performance telemetry maintains
|
||||
the correct size and default initialization to prevent GUI rendering crashes.
|
||||
@@ -54,6 +56,7 @@ def test_performance_history_updates(app_instance: Any) -> None:
|
||||
def test_gui_updates_on_event(app_instance: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that when an API event is received (e.g. from ai_client),
|
||||
the _on_api_event handler correctly updates internal metrics and
|
||||
queues the update to be processed by the GUI event loop.
|
||||
|
||||
@@ -6,6 +6,7 @@ from src.api_hook_client import ApiHookClient
|
||||
async def test_mma_track_lifecycle_simulation():
|
||||
"""
|
||||
|
||||
|
||||
This test simulates the sequence of API calls an external orchestrator
|
||||
would make to manage an MMA track lifecycle via the Hook API.
|
||||
It verifies that ApiHookClient correctly routes requests to the
|
||||
|
||||
@@ -10,6 +10,7 @@ from src import ai_client
|
||||
async def test_headless_verification_full_run(vlogger) -> None:
|
||||
"""
|
||||
|
||||
|
||||
1. Initialize a ConductorEngine with a Track containing multiple dependent Tickets.
|
||||
2. Simulate a full execution run using engine.run().
|
||||
3. Mock ai_client.send to simulate successful tool calls and final responses.
|
||||
@@ -49,6 +50,7 @@ async def test_headless_verification_full_run(vlogger) -> None:
|
||||
async def test_headless_verification_error_and_qa_interceptor(vlogger) -> None:
|
||||
"""
|
||||
|
||||
|
||||
5. Simulate a shell error and verify that the Tier 4 QA interceptor is triggered
|
||||
and its summary is injected into the worker's history for the next retry.
|
||||
"""
|
||||
|
||||
@@ -12,6 +12,7 @@ from src.gui_2 import App
|
||||
def test_new_hubs_defined_in_show_windows(mock_app: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the new consolidated Hub windows are defined in the App's show_windows.
|
||||
This ensures they will be available in the 'Windows' menu.
|
||||
"""
|
||||
@@ -27,6 +28,7 @@ def test_new_hubs_defined_in_show_windows(mock_app: App) -> None:
|
||||
def test_old_windows_removed_from_gui2(app_instance_simple: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the old fragmented windows are removed or renamed.
|
||||
"""
|
||||
old_tags = [
|
||||
@@ -54,6 +56,7 @@ def app_instance_simple() -> Any:
|
||||
def test_hub_windows_exist_in_gui2(app_instance_simple: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the new Hub windows are present in the show_windows dictionary.
|
||||
"""
|
||||
hubs = ["Project Settings", "AI Settings", "Discussion Hub", "Operations Hub"]
|
||||
@@ -63,6 +66,7 @@ def test_hub_windows_exist_in_gui2(app_instance_simple: Any) -> None:
|
||||
def test_indicators_logic_exists(app_instance_simple: Any) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the status indicators logic exists in the App.
|
||||
"""
|
||||
assert hasattr(app_instance_simple, 'ai_status')
|
||||
|
||||
@@ -14,6 +14,7 @@ from src.api_hook_client import ApiHookClient
|
||||
def test_user_request_integration_flow(mock_app: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that pushing a UserRequestEvent to the event_queue:
|
||||
1. Triggers ai_client.send
|
||||
2. Results in a 'response' event back to the queue
|
||||
@@ -76,6 +77,7 @@ def test_user_request_integration_flow(mock_app: App) -> None:
|
||||
def test_user_request_error_handling(mock_app: App) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that if ai_client.send raises an exception, the UI is updated with the error state.
|
||||
"""
|
||||
app = mock_app
|
||||
|
||||
@@ -16,6 +16,7 @@ from src.api_hook_client import ApiHookClient
|
||||
def wait_for_value(client, field, expected, timeout=10):
|
||||
"""
|
||||
|
||||
|
||||
Helper to poll the GUI state until a field matches the expected value.
|
||||
"""
|
||||
start = time.time()
|
||||
@@ -31,6 +32,7 @@ def wait_for_value(client, field, expected, timeout=10):
|
||||
def test_full_live_workflow(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Integration test that drives the GUI through a full workflow.
|
||||
ANTI-SIMPLIFICATION: Asserts exact AI behavior, thinking state tracking,
|
||||
and response logging in discussion history.
|
||||
|
||||
@@ -11,6 +11,7 @@ from src import api_hook_client
|
||||
|
||||
def _poll_mma_status(client, timeout, condition, label):
|
||||
"""
|
||||
|
||||
Poll get_mma_status() until condition(status) is True or timeout.
|
||||
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
|
||||
"""
|
||||
@@ -28,6 +29,7 @@ def _poll_mma_status(client, timeout, condition, label):
|
||||
def test_mma_concurrent_tracks_execution(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Stress test for concurrent MMA track execution.
|
||||
Verifies that starting multiple tracks simultaneously doesn't cause crashes
|
||||
and that workers from both tracks are processed.
|
||||
|
||||
@@ -25,6 +25,7 @@ def _poll_mma_workers(client: api_hook_client.ApiHookClient, timeout: int, condi
|
||||
def test_mma_concurrent_tracks_stress(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Stress test: Start two tracks concurrently and verify they both progress
|
||||
without crashing the GUI or losing state.
|
||||
"""
|
||||
|
||||
@@ -3,6 +3,7 @@ from src.models import Ticket, Track, WorkerContext
|
||||
def test_ticket_instantiation() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that a Ticket can be instantiated with its required fields:
|
||||
id, description, status, assigned_to.
|
||||
"""
|
||||
@@ -25,6 +26,7 @@ def test_ticket_instantiation() -> None:
|
||||
def test_ticket_with_dependencies() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that a Ticket can store dependencies.
|
||||
"""
|
||||
ticket = Ticket(
|
||||
@@ -39,6 +41,7 @@ def test_ticket_with_dependencies() -> None:
|
||||
def test_track_instantiation() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that a Track can be instantiated with its required fields:
|
||||
id, description, and a list of Tickets.
|
||||
"""
|
||||
@@ -61,6 +64,7 @@ def test_track_instantiation() -> None:
|
||||
def test_track_can_handle_empty_tickets() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that a Track can be instantiated with an empty list of tickets.
|
||||
"""
|
||||
track = Track(id="TRACK-2", description="Empty Track", tickets=[])
|
||||
@@ -69,6 +73,7 @@ def test_track_can_handle_empty_tickets() -> None:
|
||||
def test_worker_context_instantiation() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that a WorkerContext can be instantiated with ticket_id,
|
||||
model_name, and messages.
|
||||
"""
|
||||
@@ -90,6 +95,7 @@ def test_worker_context_instantiation() -> None:
|
||||
def test_ticket_mark_blocked() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ticket.mark_blocked(reason) sets the status to 'blocked'.
|
||||
Note: The reason field might need to be added to the Ticket class.
|
||||
"""
|
||||
@@ -100,6 +106,7 @@ def test_ticket_mark_blocked() -> None:
|
||||
def test_ticket_mark_complete() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ticket.mark_complete() sets the status to 'completed'.
|
||||
"""
|
||||
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="a")
|
||||
@@ -109,6 +116,7 @@ def test_ticket_mark_complete() -> None:
|
||||
def test_track_get_executable_tickets() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that track.get_executable_tickets() returns only 'todo' tickets
|
||||
whose dependencies are all 'completed'.
|
||||
"""
|
||||
@@ -134,6 +142,7 @@ def test_track_get_executable_tickets() -> None:
|
||||
def test_track_get_executable_tickets_complex() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies executable tickets with complex dependency chains.
|
||||
Chain: T1 (comp) -> T2 (todo) -> T3 (todo)
|
||||
T4 (comp) -> T3
|
||||
|
||||
@@ -24,6 +24,7 @@ def _poll_mma_status(client: api_hook_client.ApiHookClient, timeout: int, condit
|
||||
def test_mma_step_mode_approval_flow(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verify that we can manually approve a ticket in Step Mode and it proceeds.
|
||||
"""
|
||||
client = api_hook_client.ApiHookClient()
|
||||
|
||||
@@ -13,6 +13,7 @@ from src import api_hook_client
|
||||
def test_patch_modal_appears_on_trigger(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test that triggering a patch shows the modal in the GUI.
|
||||
Uses live_gui fixture to start the GUI with test hooks enabled.
|
||||
"""
|
||||
@@ -51,6 +52,7 @@ def test_patch_modal_appears_on_trigger(live_gui) -> None:
|
||||
def test_patch_apply_modal_workflow(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Test the full patch apply workflow: trigger -> apply -> verify modal closes.
|
||||
"""
|
||||
proc, _ = live_gui
|
||||
|
||||
@@ -25,6 +25,7 @@ def mock_project():
|
||||
def test_rag_integration(mock_project):
|
||||
"""
|
||||
|
||||
|
||||
Integration test verifying the flow from AppController through RAGEngine to ai_client.
|
||||
"""
|
||||
# 1. Initializes a mock project and AppController.
|
||||
|
||||
@@ -10,6 +10,7 @@ class TestRunWorkerLifecycleAbort(unittest.TestCase):
|
||||
def test_run_worker_lifecycle_returns_early_on_abort(self):
|
||||
"""
|
||||
|
||||
|
||||
Test that run_worker_lifecycle returns early and marks ticket as 'killed'
|
||||
if the abort event is set for the ticket.
|
||||
"""
|
||||
|
||||
@@ -13,6 +13,7 @@ from src.gui_2 import App
|
||||
def test_selectable_label_stability(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the application starts correctly with --enable-test-hooks
|
||||
and that the selectable label infrastructure is present and stable.
|
||||
"""
|
||||
|
||||
@@ -16,6 +16,7 @@ from simulation.sim_ai_settings import AISettingsSimulation
|
||||
def test_ai_settings_simulation_run() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that AISettingsSimulation correctly cycles through models
|
||||
to test the settings UI components.
|
||||
"""
|
||||
|
||||
@@ -16,6 +16,7 @@ from simulation.sim_base import BaseSimulation
|
||||
def test_base_simulation_init() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the BaseSimulation initializes the ApiHookClient correctly.
|
||||
"""
|
||||
with patch('simulation.sim_base.ApiHookClient') as mock_client_class:
|
||||
@@ -29,6 +30,7 @@ def test_base_simulation_init() -> None:
|
||||
def test_base_simulation_setup() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the setup routine correctly resets the GUI state
|
||||
and initializes a clean temporary project for simulation.
|
||||
"""
|
||||
|
||||
@@ -16,6 +16,7 @@ from simulation.sim_context import ContextSimulation
|
||||
def test_context_simulation_run() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that the ContextSimulation runs the correct sequence of user actions:
|
||||
discussion switching, context building (md_only), and history truncation.
|
||||
"""
|
||||
|
||||
@@ -16,6 +16,7 @@ from simulation.sim_execution import ExecutionSimulation
|
||||
def test_execution_simulation_run() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ExecutionSimulation handles script confirmation modals.
|
||||
Ensures that it waits for the modal and clicks the approve button.
|
||||
"""
|
||||
|
||||
@@ -16,6 +16,7 @@ from simulation.sim_tools import ToolsSimulation
|
||||
def test_tools_simulation_run() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that ToolsSimulation requests specific tool executions
|
||||
and verifies they appear in the resulting session history.
|
||||
"""
|
||||
|
||||
@@ -7,6 +7,7 @@ import os
|
||||
def test_system_prompt_sim(live_gui):
|
||||
"""
|
||||
|
||||
|
||||
Simulation test for system prompt settings.
|
||||
1. Wait for server.
|
||||
2. Verify initial state.
|
||||
|
||||
@@ -62,6 +62,7 @@ def test_run_powershell_optional_qa_callback() -> None:
|
||||
|
||||
def test_end_to_end_tier4_integration(vlogger) -> None:
|
||||
"""
|
||||
|
||||
1. Start a task that triggers a tool failure.
|
||||
2. Ensure Tier 4 QA analysis is run.
|
||||
3. Verify the analysis is merged into the next turn's prompt.
|
||||
|
||||
@@ -8,6 +8,7 @@ from src.project_manager import save_track_state, load_track_state
|
||||
def test_track_state_persistence(tmp_path) -> None:
|
||||
"""
|
||||
|
||||
|
||||
Tests saving and loading a TrackState object to/from a TOML file.
|
||||
1. Create a TrackState object with sample metadata, discussion, and tasks.
|
||||
2. Call save_track_state('test_track', state, base_dir).
|
||||
|
||||
@@ -4,6 +4,7 @@ from tree_sitter import Language, Parser
|
||||
def test_tree_sitter_python_setup() -> None:
|
||||
"""
|
||||
|
||||
|
||||
Verifies that tree-sitter and tree-sitter-python are correctly installed
|
||||
and can parse a simple Python function string.
|
||||
"""
|
||||
|
||||
@@ -56,6 +56,7 @@ def _poll(client: api_hook_client.ApiHookClient, timeout: int, condition, label:
|
||||
def test_mma_complete_lifecycle(live_gui) -> None:
|
||||
"""
|
||||
|
||||
|
||||
End-to-end MMA lifecycle using real Gemini API (gemini-2.5-flash-lite).
|
||||
Incorporates frame-sync sleeps and explicit state-transition waits per
|
||||
simulation_hardening_20260301 spec (Issues 2 & 3).
|
||||
|
||||
@@ -14,6 +14,7 @@ from src import api_hook_client
|
||||
def test_workspace_profiles_restoration(live_gui):
|
||||
"""
|
||||
|
||||
|
||||
Verifies that workspace profiles can save and restore UI state.
|
||||
1. Sets a field (ui_separate_tier1) to True.
|
||||
2. Saves a workspace profile.
|
||||
|
||||
Reference in New Issue
Block a user