mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
refactor(history): project the /history wire shape server-side
Collapse the three hand-synced "raw storage -> render shape" projections into one server-side projection. The projection previously lived in a test-only `_build_history` (SSE-era reference impl), a client-side JS normaliser (`history_normalize.js`, the transitional bridge), and coord's inline `init()` handling -- drifting silently with no parity test. Add `project_history_messages` to `history_decoration.py` and run it as the final step of the `make_history_handler` pipeline (load_messages -> decorate -> extract_reasoning -> project), so `GET /history` emits the canonical render shape directly: flat tool_calls (with verdict / output_assessment), top-level source / reminders / attachments, collapsed multipart content, derived denied / is_error / pending, reasoning, and advisories. Interactive `replayHistory` now consumes the payload verbatim. Close two gaps the JS bridge deferred: - list-content <tool_output> advisory extraction (decorate handles only string content; the projection extracts list-carrier advisories, then joins remaining text parts to the string the renderers require); - orphan->pending marks ONLY the last orphan tool-call turn, so a mid-conversation cancelled tool still renders instead of vanishing. Delete `history_normalize.js` (+ its <script> tag and node test) and the test-only `_build_history` (+ orphaned imports); retarget its direct tests onto the projection helpers. Update the WorkstreamHistoryResponse description and the Web UI Resilience architecture note to the projected shape. Coord's `init()` still reads the raw side-channels; migrating it to the projected shape is the next commit, browser-verified separately. Refs #549.
This commit is contained in:
@@ -1058,11 +1058,12 @@ warns if the summary was truncated.
|
||||
unhandled promise rejections
|
||||
- **Pending approval across tab switches**: `WebUI._pending_approval` stores
|
||||
the `approve_request` event payload while the session is blocked waiting
|
||||
for user response. On SSE reconnect (e.g., switching back to the tab),
|
||||
the event is re-injected after history replay. `_build_history` marks the
|
||||
pending tool call as `"pending": true` so `replayHistory` skips the
|
||||
false `✓ approved` badge; the live approval UI is rendered by the
|
||||
re-injected event instead.
|
||||
for user response. On tab switch / reconnect the pane reloads history via
|
||||
REST `GET /history` and then reconnects SSE; the live approval event is
|
||||
re-injected. The server-side `project_history_messages` projection marks
|
||||
the trailing orphan tool-call turn `"pending": true` so `replayHistory`
|
||||
skips the false `✓ approved` badge; the live approval UI is rendered by
|
||||
the re-injected event instead.
|
||||
- **Browser history integration**: `history.pushState` is called in
|
||||
`switchTab()` with `{turnstone: 'workstream', wsId}`. The initial state is
|
||||
seeded with `history.replaceState({turnstone: 'dashboard'})` on load. The
|
||||
|
||||
Reference in New Issue
Block a user