Extracts incomplete message state from the last historical assistant message, enabling the realtime chunk processor to resume building messages across reconnected sessions. ## Key Components ### `extractIncompleteMessageState(lastMessage)` Inspects a `ProcessedMessage` and returns resumable state if any in-progress segments are found. **Parameters:** - `lastMessage` — A `ProcessedMessage` or `undefined` **Returns:** An object with optional `existingSegments`, `pendingApprovals`, `executingTools`, and `agentBusy`, or `undefined` if the message is complete or ineligible. **Incomplete state detection by segment type:** | Segment Type | Condition Flagged Incomplete | |---|---| | `tool_execution` | Status is `EXECUTING_TOOL` | | `approval_request` | Status is `pending` with a `requestId`, **or** `approved` as the trailing segment | | `approval_batch` | Not `rejected` and not all tool calls have `done` executions | | `context_compaction` | Status is `started` | ### `agentBusy` — incomplete ≠ working Unfinished says nothing about WHO the turn is waiting on, and only the activity indicator's answer to that is user-visible. `agentBusy` is the second, narrower question, derived here so every host answers it the same way (the reducer raises `idle → thinking` off it on `initializeWithState`; callback-contract hosts fire `onAgentBusy`). Nothing on the wire restores this after a reload: a run's EXECUTING chunk is long past and its EXECUTED one may be minutes away. | Tail state | Busy | Why | |---|---|---| | `EXECUTING_TOOL` with no result | ✅ | The tool is running now | | `approval_batch` `approved`, calls outstanding | ✅ | Runs are recorded inside the batch, so `executingTools` is empty — gating on that map missed the whole approval path | | `approval_request` `approved`, trailing | ✅ | A single request carries no execution record; work that followed it is the only "it came back" signal | | `context_compaction` `started` | ✅ | Compaction is the agent's own work | | Any approval still `pending` | ❌ | Blocked on the USER — spinning claims work that is not happening | | `rejected` / `cancelled`, or all calls `done` | ❌ | Nothing outstanding | ## Usage Example ```typescript import { extractIncompleteMessageState } from './extract-incomplete-message-state' const lastMessage = conversationHistory.at(-1) const incompleteState = extractIncompleteMessageState(lastMessage) if (incompleteState) { initializeRealtimeChunkProcessor({ existingSegments: incompleteState.existingSegments, pendingApprovals: incompleteState.pendingApprovals, executingTools: incompleteState.executingTools, }) } ``` **Source:** [`extract-incomplete-message-state.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/extract-incomplete-message-state.ts)