Private
Public Access
0
0

docs(reports): add SSDL Discussion AI Turn Cycle report

This commit is contained in:
2026-06-13 18:44:57 -04:00
parent cc8771b99b
commit bcd7ee14cb
@@ -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.