Deliver attached images, and stop two compose windows sharing a toolbar

Fixkamo-internal
Shipped
August 4, 2026 at 3:40 PM UTC
Author
kamo
Commit
17cd281

AI chat attachments were never reaching the AI. AiChatInput sent the storage paths as `imageUrls`, but the REST body in AiChatWebSocketContext reads `imageObjectPaths`, so the server received undefined. The image still appeared in the member's own transcript — it is echoed optimistically from the same message — so the failure was invisible: the member sees the picture they attached and the assistant answers as if there were none. `AiWsMessage` has an `[key: string]: any` index signature, which is why a misspelled field typechecked. Both names are now declared explicitly. The echo was broken too, in the opposite direction: it renders its values straight into <img src>, but was handed minio object paths rather than the browser-loadable blob: URL. The two consumers now get the value each one actually needs. The blob URLs are no longer revoked on send either — MESSAGE_COMPLETE only appends the assistant reply and never replaces the echoed user message, so that message keeps referencing them for the life of the window. TemplateInlineEditor bound Quill's toolbar with a module-level constant DOM id. The message tool is maxInstances: Infinity, so with two compose windows open both editors resolved `#tpl-editor-toolbar` to whichever toolbar came first in the DOM — clicking Bold in one window formatted the other window's text. The binding id is now per-instance via useId (colons stripped, since they are not selector-safe). Styling moves to a shared class so the global style block stays identical across instances and can still be deduped.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing