← Back to Virtual Office

Shared Multi-Chat Window Architecture

This locks down how the existing chat window grows into one shared system that supports the main window plus 3 additional slide-out windows without forking the UI into four separate implementations.

1. Window model

primaryMain chat window. Always exists. Keeps the current anchor/toggle behavior.
secondary-1First optional slide-out instance. Controlled by button 1.
secondary-2Second optional slide-out instance. Controlled by button 2.
secondary-3Third optional slide-out instance. Controlled by button 3.

2. Per-window state

Every chat slot owns its own target/session state. That means selected agent, session key, draft text, attachments, unread count, and streaming metadata all live per window instead of in page-global singletons.

const chatWindows = {
  primary: {
    slotId: 'primary',
    selectedAgentKey: 'main',
    sessionKey: 'agent:main:main',
    draft: '',
    attachments: [],
    pendingRunId: null,
    unread: 0,
    layoutMode: 'docked-right'
  },
  'secondary-1': null,
  'secondary-2': null,
  'secondary-3': null
};

3. One shared chat UI system

All windows must come from one reusable chat component/template. The current single-instance code needs to be migrated so each window renders from the same logic with a slot-scoped state object.

createChatWindow(slotId, containerEl)
renderChatWindow(slotState)
bindChatWindowEvents(slotState, elements)
loadChatHistory(slotState)
connectChatStream(slotState)
sendChatMessage(slotState)
resetChatSession(slotState)
destroyChatWindow(slotId)

4. Shared transport, isolated windows

Do not create four separate websocket stacks. Use one shared gateway connection and route events to the correct window by slotId and sessionKey.

5. Buttons 1, 2, and 3

Buttons map to fixed secondary slots and act as toggles.

1 → secondary-1 2 → secondary-2 3 → secondary-3

6. Layout behavior

7. Acceptance checklist