second attempt in call graph track

This commit is contained in:
2026-05-07 22:32:09 -04:00
parent 12439ac639
commit 2d48c07760
@@ -1,62 +1,86 @@
# AI Interaction Loop: Sequence Diagram # AI Interaction Pipeline: Intensive Technical Trace
This diagram traces the flow of a user message from the GUI thread to the background AI worker thread, including the multi-turn tool-calling loop and final response hand-off. This document provides a low-level technical trace of the AI interaction loop, following a pipeline-oriented architectural model. It identifies thread context switches, data transformation overhead, and synchronization bottlenecks.
## 1. Sequence Diagram: Asynchronous Interaction Pipeline
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant UI as gui_2.py (Main Thread) autonumber
participant AC as app_controller.py (Event Thread) participant UI as gui_2.py (Main/Render Thread)
participant AW as app_controller.py (AI Worker Thread) participant EV as app_controller.py (Event Dispatcher)
participant AI as ai_client.py (Unified SDK) participant WK as ai_client.py (Worker Thread Pool)
participant MCP as mcp_client.py (Read-Only Tools) participant AI as ai_client.py (Provider Pipeline)
participant SR as shell_runner.py (PowerShell) participant MCP as mcp_client.py (FileSystem Pipeline)
participant SR as shell_runner.py (Subprocess Pipeline)
Note over UI, SR: 1. Initiation Note over UI, WK: [Phase A: Request Initiation]
UI->>AC: event_queue.put("user_request", payload) UI->>EV: SyncEventQueue.put("user_request", dict)
AC->>AW: threading.Thread(target=_handle_request_event).start() Note right of UI: Data: Raw Prompt + Context Pointers
EV->>EV: polling loop (event_queue.get())
Note over UI, SR: 2. Request Processing EV->>WK: threading.Thread(target=_handle_request_event).start()
AW->>AI: send(md_context, prompt, history, ...) Note right of EV: Context Switch: Event Thread -> AI Worker Thread
AI->>AI: Prompt Assembly (Context + History + SysPrompt)
Note over WK, AI: [Phase B: Context Synthesis & Generation]
loop Tool-Call Loop (r_idx <= MAX_TOOL_ROUNDS) WK->>AI: ai_client.send(md_content, history)
AI->>Vendor: Provider SDK Request AI->>AI: _build_chunked_context_blocks()
Vendor-->>AI: Tool Call(s) OR Text Note right of AI: Perf: O(N) string concatenation + regex scans
AI->>Vendor: Provider API Request (HTTPS/JSON)
alt Tool Call(s) Detected Note right of AI: Bottleneck: Network Latency (1-30s)
AI->>AW: _execute_tool_calls_concurrently() Vendor-->>AI: ToolCall(s) or StopReason
Note over AI, SR: [Phase C: Multi-Turn Tool Execution Loop]
loop MAX_TOOL_ROUNDS (r_idx <= 10)
alt Tool Use Detected
AI->>WK: _execute_tool_calls_concurrently()
alt Read-Only Tool alt Read-Only (MCP)
AW->>MCP: call_tool(args) WK->>MCP: read_file / list_dir / search
MCP-->>AW: output MCP-->>WK: stdout_string
else Mutating / PS Tool else Mutating (Shell)
AW->>UI: _confirm_and_run(script) [MODAL] WK->>EV: _pending_gui_tasks.append(approval_modal)
Note over UI: User Approval Required Note over UI: UI Polling Detects Task
UI-->>AW: Approved UI->>UI: Render ImGui Popup (Wait for HITL)
AW->>SR: run_powershell(script) Note over UI: User Approval Interaction
SR-->>AW: stdout/stderr UI-->>WK: threading.Condition.notify()
Note right of WK: Resume AI Worker Thread
WK->>SR: run_powershell(script)
SR->>OS: Subprocess Spawn (powershell.exe)
OS-->>SR: stdout/stderr (JSON-L Stream)
SR-->>WK: COMBINED_OUTPUT_STRING
end end
AW-->>AI: Tool Result(s) WK-->>AI: Aggregate Tool Results
AI->>AI: Append Result to History AI->>AI: _reread_file_items() (Context Refresh)
else Final Text Returned Note right of AI: Perf: IO Bound (File MTime Scans)
AI-->>AW: Final Response Text AI->>Vendor: Follow-up Prompt (with Tool Result)
else Terminal Text
AI-->>WK: Final AI Response Text
end end
end end
Note over UI, SR: 3. Completion Note over WK, UI: [Phase D: Result Synchronization]
AW->>AC: event_queue.put("response", {"text": resp, "status": "done"}) WK->>EV: SyncEventQueue.put("response", result)
AC->>AC: _pending_gui_tasks.append(response_task) EV->>EV: _pending_gui_tasks.append(response_obj)
loop Every Frame (~16.6ms)
loop Every Frame UI->>EV: _process_pending_gui_tasks()
UI->>AC: _process_pending_gui_tasks() Note right of UI: Data Copy: Controller State -> UI History Buffer
AC-->>UI: response_task UI->>UI: Update Rendering State (Markdown/Syntax Highlight)
UI->>UI: Update AI History & Reset Status
end end
``` ```
### Key Technical Details ## 2. Technical Performance Audit
- **Thread Separation:** The UI remains responsive by delegating the blocking `ai_client.send()` call to a daemon thread.
- **Human-in-the-Loop:** `_confirm_and_run` uses a `threading.Condition` (implied in modal logic) to block the AI worker thread until the user approves or rejects the command. ### 2.1 Threading & Synchronization
- **Stall Detection:** (Managed by Simulation Puppeteer, see preservation doc). - **Context Switches:** The pipeline traverses four distinct execution contexts: Main Thread -> Event Thread -> Daemon Worker -> Subprocess.
- **Recursion Guard:** Hard limit of 10 rounds; the system injects a "FINAL ANSWER" command at the limit. - **Lock Contention:** `_pending_gui_tasks_lock` is acquired twice per AI response turn (once by background thread to append, once by UI thread to process).
- **Blocking Sites:** `ai_client.send` blocks the dedicated `WK` thread. `_confirm_and_run` blocks the `WK` thread using a `Condition` variable waiting on UI input.
### 2.2 Data Transformation Costs
- **Context Bloat:** `md_content` is a monolithic string. During synthesis, this string is often copied or chunked (`_chunk_text`), increasing memory pressure on the Python heap.
- **Serialization Overhead:** Every tool call involves: Python dict -> JSON String -> Subprocess Stdin -> (Tools) -> Subprocess Stdout -> JSON String -> Python dict.
### 2.3 Curation Targets (Intensive)
1. **Reduce Memory Copies:** The monolithic Markdown context should be handled as a stream or a shared buffer to avoid redundant copies between `aggregate` and `ai_client`.
2. **Deterministic Status Polling:** Replace string-based status polling (`ai_status`) with an enum-based state machine to reduce regex comparisons in the simulator and UI.
3. **Subprocess Pooling:** `shell_runner` spawns a new process for every script. For high-frequency tool use, a persistent PowerShell session could reduce overhead.