docs(reports): add SSDL Discussion AI Turn Cycle report
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
# SSDL Report: Discussion AI Turn Cycle
|
||||
|
||||
**Track/Context:** Technical Architecture Reference
|
||||
**Date:** 2026-06-13
|
||||
**Status:** Completed
|
||||
**Subject:** Full SSDL trace of a discussion AI turn cycle from user prompt to AI response and handoff.
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
This report traces the execution flow and data lifecycle of a single **Discussion AI Turn Cycle** in the Manual Slop orchestrator. The cycle starts with a user-submitted prompt in the ImGui interface, flows through thread-offloaded controllers and event queues, enters the LLM provider context-enrichment and tool execution engine (HITL clutch), streams partial tokens back to the UI thread, and finally updates the persistent state, returning control to the user.
|
||||
|
||||
We model this end-to-end flow using the **Spec/Sketch Description Language (SSDL)** syntax.
|
||||
|
||||
---
|
||||
|
||||
## 2. End-to-End SSDL Topology Diagram
|
||||
|
||||
This diagram displays the flow across three distinct execution boundaries:
|
||||
1. **The UI Thread** (ImGui render loop ticking at 60 FPS)
|
||||
2. **Background IO/Worker Threads** (asynchronous worker pools)
|
||||
3. **Queue Processors** (mediating communication between threads)
|
||||
|
||||
```
|
||||
===================================================================================================
|
||||
DISCUSSION AI TURN CYCLE TOPOLOGY
|
||||
===================================================================================================
|
||||
|
||||
[UI Thread (60 FPS)] [Worker Thread (IO Pool)] [Worker Thread (AI / Tools)]
|
||||
-------------------- ------------------------- ----------------------------
|
||||
|
||||
[Q:ui_ai_input]
|
||||
│
|
||||
▼
|
||||
[I:render_message_panel]
|
||||
│
|
||||
[B:Gen+Send Clicked?] ─── yes ───► [I:_handle_generate_send]
|
||||
│
|
||||
(submit_io)
|
||||
│
|
||||
▼
|
||||
[I:_do_generate]
|
||||
(construct context)
|
||||
│
|
||||
▼
|
||||
[I:events.UserRequestEvent]
|
||||
│
|
||||
(put queue)
|
||||
│
|
||||
▼
|
||||
[S:event_queue (Q)]
|
||||
│
|
||||
(dequeue loop)
|
||||
│
|
||||
▼
|
||||
[_process_event_queue]
|
||||
│
|
||||
(submit_io)
|
||||
│
|
||||
▼
|
||||
[_handle_request_event]
|
||||
│
|
||||
[B:RAG Enabled?]
|
||||
╱ ╲
|
||||
yes no
|
||||
╱ ╲
|
||||
▼ ▼
|
||||
[I:rag_engine.search] [I:parse_symbols]
|
||||
│ │
|
||||
▼ ▼
|
||||
└──────► [M] ◄──────┘
|
||||
│
|
||||
▼
|
||||
[I:ai_client.send]
|
||||
│
|
||||
▼
|
||||
[I:run_with_tool_loop] ◄──────────────────────┐
|
||||
│ │ (next round)
|
||||
▼ │
|
||||
[B:Tool Calls Returned?] │
|
||||
╱ ╲ │
|
||||
yes no │
|
||||
╱ ╲ │
|
||||
▼ ▼ │
|
||||
[I:_confirm_and_run (HITL)] [I:Stream Callback] │
|
||||
[B:Clutch Approved?] │ │
|
||||
╱ ╲ ▼ │
|
||||
yes no [S:event_queue] │
|
||||
╱ ╲ │ │
|
||||
▼ ▼ │ (dequeue) │
|
||||
[I:_run_script] [I:abort] ▼ │
|
||||
[I:mcp_dispatch] │ [S:_pending_gui_tasks] │
|
||||
│ │ │ │
|
||||
▼ ▼ │ (UI Thread tick) │
|
||||
└───────► [M] ◄──────────┘ ▼ │
|
||||
│ [I:_handle_ai_response] │
|
||||
▼ │ │
|
||||
[I:Record Tool Result] ▼ │
|
||||
│ (append stream view) │
|
||||
▼ │ │
|
||||
[I:Trim Token History] └───────────────────┘
|
||||
│
|
||||
(loop ends)
|
||||
│
|
||||
▼
|
||||
[I:Final Result Wrapper]
|
||||
│
|
||||
▼
|
||||
[S:event_queue]
|
||||
│
|
||||
(dequeue)
|
||||
▼
|
||||
[S:_pending_gui_tasks]
|
||||
│
|
||||
(UI tick)
|
||||
▼
|
||||
[I:_handle_ai_response]
|
||||
│
|
||||
▼
|
||||
[I:render_response_panel]
|
||||
│
|
||||
▼
|
||||
[T:User]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Step-by-Step Execution Trace
|
||||
|
||||
### Phase 1: User Request Generation (UI Thread)
|
||||
1. **Query Input**: The ImGui render loop queries the text input buffer:
|
||||
`[Q:ui_ai_input] -> [I:render_message_panel]`
|
||||
2. **Branch Check**: The loop checks if the `Gen + Send` button is clicked and if the queue is idle:
|
||||
`[B:Gen+Send Clicked? (send_busy?)]`
|
||||
3. **Dispatch**: If clicked, the controller triggers `App._handle_generate_send()`, which delegates to the controller:
|
||||
`[I:_handle_generate_send]`
|
||||
|
||||
### Phase 2: Context Construction & Queue Placement (IO Thread)
|
||||
1. **Thread Offloading**: `AppController._handle_generate_send` submits a worker to the IO thread pool:
|
||||
`self.submit_io(worker)`
|
||||
2. **Curation Aggregation**: The background worker calls `_do_generate()` which flushes config, builds the active project configuration, and curates context files:
|
||||
`[I:_do_generate] ─── (queries context_files)`
|
||||
3. **Payload Wrapping**: Wraps the collected data into a `UserRequestEvent` struct.
|
||||
4. **Queue Placement**: Pushes the event to the thread-safe queue:
|
||||
`[S:event_queue] (user_request)`
|
||||
|
||||
### Phase 3: Background Event Processing & Enrichment (AI/Worker Thread)
|
||||
1. **Event Dequeue**: The event thread loop (`_process_event_queue()`) fetches the `"user_request"` event.
|
||||
2. **Thread Offloading**: It submits the request handler to execute asynchronously on the IO pool:
|
||||
`self.submit_io(self._handle_request_event, payload)`
|
||||
3. **RAG Retrieval**: The request thread queries ChromaDB using the user prompt and prepends chunks to the query:
|
||||
`[Q:rag_engine] -> [I:rag_engine.search] -> [S:user_msg]`
|
||||
4. **Symbol Resolution**: Parsed code symbols are looked up in active files and Python AST definitions are appended:
|
||||
`[I:parse_symbols] -> [I:get_symbol_definition] -> [S:user_msg]`
|
||||
5. **Comms Logging**: Pushes a comms logging request event onto the queue.
|
||||
6. **Client Setup**: Configures global variables, custom and base system prompts, and temperature boundaries on the `ai_client` instance.
|
||||
7. **Provider Invocation**: Dispatches the enriched request to the client endpoint:
|
||||
`[I:ai_client.send]`
|
||||
|
||||
### Phase 4: The Tool Loop & Human-In-The-Loop (HITL) Gate
|
||||
1. **Provider Resolution**: `ai_client` maps to the active vendor (e.g. Gemini, Grok, MiniMax).
|
||||
2. **Loop Iteration**: Runs `run_with_tool_loop(client, request, capabilities)`.
|
||||
3. **Tool Call Check**: If the provider returns tool requests:
|
||||
* **HITL Clutch Approval**: For each tool, the clutch mode is checked (ask vs auto). If ask, the loop raises `mma_spawn_approval` or `mma_step_approval` events.
|
||||
* **Execution Suspension**: The background worker thread blocks/waits for approval state.
|
||||
* **User Decision**: In the GUI thread, the user approves or rejects.
|
||||
* **Execution**: If approved, the tool runs (PowerShell via `_run_script` or MCP client API dispatch):
|
||||
`[I:_run_script] / [I:mcp_client.async_dispatch]`
|
||||
* **Result Record**: Appends the tool outputs to history and prunes history if token limit is exceeded.
|
||||
* **Loop Iteration**: Loops back to call the LLM again with results.
|
||||
4. **Streaming Callback**: For every text chunk received from the LLM, the `stream_callback` triggers:
|
||||
`[I:_on_ai_stream] -> [S:event_queue] (response)`
|
||||
|
||||
### Phase 5: Handoff Back to User (UI Thread)
|
||||
1. **Enqueue Stream**: The event loop `_process_event_queue` dequeues `"response"` events and pushes them to `self._pending_gui_tasks`.
|
||||
2. **UI Thread Dequeue**: The main ImGui render loop ticks (60 FPS) and calls `app._process_pending_gui_tasks()`.
|
||||
3. **Update UI State**: Runs `_handle_ai_response()`, which appends text to `self.ai_response` and sets `self._ai_status = "streaming..."` or `"done"`.
|
||||
4. **Blink Alert**: Triggers UI window blinking and focuses the Response panel:
|
||||
`[S:_trigger_blink]`
|
||||
5. **Final Render**: Renders final markdown output in `render_response_panel`. Keyboard focus returns to the input field, ready for the user's next request:
|
||||
`[T:User]`
|
||||
|
||||
---
|
||||
|
||||
## 4. Key Architectural Invariants
|
||||
|
||||
* **Thread-Safety**: All mutable updates to GUI-rendering variables (like `ai_response` and `ai_status`) occur strictly on the main thread via the `_pending_gui_tasks` synchronization list.
|
||||
* **Non-Blocking GUI**: The ImGui render loop never performs network I/O or file compilation directly. All RAG, parsing, model API connections, and tool executions run on the background IO pool.
|
||||
* **Data Integrity**: Enriched prompts are logged to history exactly as sent to the LLM (including RAG snippets and symbol definitions), maintaining auditability.
|
||||
Reference in New Issue
Block a user