Skip to content

fix(webui): persist chat history and WebUI transcripts across deploys#9

Merged
Ho1yShif merged 2 commits into
mainfrom
fix/webui-history-persistence
Jul 10, 2026
Merged

fix(webui): persist chat history and WebUI transcripts across deploys#9
Ho1yShif merged 2 commits into
mainfrom
fix/webui-history-persistence

Conversation

@Ho1yShif

Copy link
Copy Markdown
Collaborator

Problem

After a redeploy, the WebUI sidebar listed past conversations, but opening one showed an empty thread ("What should we work on?") instead of the previous messages. The conversation content was never lost — it lives in the persisted session files — but the WebUI display transcript was gone.

Root cause: nanobot has two storage roots. workspace (session files, sidebar index) is on the mounted disk and survives. But data_dir resolved to /app — the committed config baked into the image — which is ephemeral and rebuilt every deploy. The WebUI display transcripts live under data_dir/webui, so they were wiped on each deploy → the thread endpoint 404'd → empty thread.

Changes

  • entrypoint.sh — copy the selected config template (render-config.json, or render-demo-config.json when DEMO) onto the mounted disk and run with --config pointing there, so data_dir (= config_path.parent) resolves under the mount. webui/, cron, media, and logs now persist alongside session files. Copied as root before the setpriv drop, then covered by the existing chown. Overwrite on every boot; secrets stay as ${VAR} placeholders resolved in memory, so nothing secret is written to disk.
  • nanobot/webui/transcript.pybuild_webui_thread_response now reconstructs the thread from the durable session file when the display transcript is missing, instead of returning None (→ 404). Recovers already-orphaned chats and self-heals any future transcript loss.
  • render.yaml — correct the misleading disk comment. Stays Starter / 1 GB (the lean default; history persistence needs the disk, not a bigger plan).
  • README.md — HeyGen offload recipe for the hyperframes CLI App (set HEYGEN_API_KEY in the dashboard rather than the interactive hyperframes auth login), plus a note that history persistence needs the disk, not a plan upgrade.

Testing

  • New unit tests in tests/utils/test_webui_transcript.py: reconstruction from session messages (plain + paginated, matching the live limit=160&direction=latest call) and a guard that both-empty still returns None.
  • pytest tests/cli_apps/ tests/webui/ tests/utils/test_webui_transcript.py green; ruff check nanobot/ clean; shellcheck entrypoint.sh clean.
  • Not yet run: the post-deploy Playwright end-to-end check against a live instance.

🤖 Generated with Claude Code

Ho1yShif and others added 2 commits July 10, 2026 00:17
Chat history did not fully survive redeploys: the sidebar listed past
conversations but opening one showed an empty thread. Root cause was
nanobot's data_dir resolving to /app (baked into the image, wiped every
deploy), so the WebUI display transcripts under data_dir/webui were lost
while session files on the persistent disk survived.

- entrypoint.sh: copy the selected config template onto the mounted disk
  and run with --config on the disk, so data_dir resolves under the mount
  (webui/, cron, media, logs now persist). Overwrite on every boot; secrets
  stay as ${VAR} placeholders resolved in memory.
- transcript.py: build_webui_thread_response reconstructs the thread from
  the durable session file when the display transcript is missing, instead
  of 404ing. Recovers orphaned chats and self-heals future transcript loss.
- render.yaml: correct the misleading disk comment; stays Starter / 1 GB.
- README: HeyGen offload recipe for the hyperframes CLI App, and a note
  that history persistence needs the disk, not a bigger plan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eep them

mistune's HTMLRenderer treats any non-http(s) scheme as harmful and rewrites
it to "#harmful-link" before the nh3 cleaner runs. That stripped mxc:// image
sources and matrix: links even though MATRIX_HTML_CLEANER is explicitly built
to preserve them (via _filter_matrix_html_attribute and MATRIX_ALLOWED_URL_SCHEMES),
breaking test_send_keeps_only_mxc_image_sources.

Pass an HTMLRenderer with allow_harmful_protocols=("mxc:", "matrix:") so mistune
emits the URLs unchanged and nh3 remains the single security gate. Non-mxc image
srcs, javascript:, and data: URLs are still stripped by nh3 as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ho1yShif Ho1yShif merged commit fce747a into main Jul 10, 2026
5 checks passed
@Ho1yShif Ho1yShif deleted the fix/webui-history-persistence branch July 10, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant