Files
hermes-agent/apps
sal 0b87e89d40 fix(desktop): assistant rows whose text persisted to sidecars no longer vanish on rehydrate (#68321)
Field-level reproduction (2026-09-02, v0.21.0, in the issue thread): an
assistant row with content length 0 whose user-visible response exists
only in reasoning / reasoning_content / codex_message_items renders
live, then disappears from the transcript after a session/profile
switch-back. DB intact - the row is still there on every re-read; only
the rehydrated render loses it. Six independent confirmations across
macOS and Windows since 2026-07-22; all prior fixes (#68329 envelope
normalization, closed implemented_on_main; #77644 mid-turn reconcile;
#101470 compaction-display projections) addressed adjacent producers,
not this one.

Two producers in toChatMessages hydration, both pinned by the new
chat-messages.reasoning-survival.test.ts (fails 9/9 on current main):

1. codex_message_items never read. Responses-API turns can persist with
   `content` empty while the reply the user saw lives only in the
   message-items sidecar ({type:'message', role:'assistant', phase,
   content:[{type:'output_text', text}]}). The live stream painted that
   text; hydration ignored the sidecar, so the rehydrated bubble came
   back blank - and the blank chatMessageText at the same role-ordinal
   then made reconcileResumeMessages drop the cached row's parts
   (sameText/extension/isLiveTailRow all fail), erasing the reply on
   every switch-back. Fix: codexMessageItemText() extracts
   non-commentary assistant output_text as the bubble's text when
   content and reasoning produced no parts. Persisted content still
   wins when present; commentary narration is never promoted.

2. the zero-parts drop. An assistant row hydrating to no parts at all
   returned early and vanished from the transcript entirely - the
   "all assistant messages gone; user messages remain" shape. Fix: a
   wholly empty assistant row (display_kind != 'hidden') paints a
   _(assistant response not persisted)_ placeholder instead of
   disappearing. Hidden scaffolding rows keep dropping as designed
   (pinned by a test).

Also adds codex_message_items to the SessionMessage type (the gateway
has shipped it since the branch-copy lane; the type never declared it).

Verification (native Windows, node 24.17):
- new file: 9 passed (fails 9/9 without the hydration changes)
- src/lib full dir: 1243 passed
- reconcile suites (utils + resume-structural-parts): 115 passed
- streaming/timeline reasoning-part suites: 25 passed
- tsc --build tsconfig.json: clean

Fixes #68321
2026-09-07 00:45:11 +05:30
..