- 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.