Technical docs

Internal Chat

Overview

Support reference for the current internal chat UI.

Current chat modes

  • The current frontend chat peer modes are:
  • `aiTeammate`
  • `ally`
  • Sidebar `Chats` opens the shared chat surface. It is an action item, not navigation to a dedicated `/ai` page.
  • `Alt+C` toggles `Chats`.
  • Internal chat uses one shared session model for panel, floating, and minimized views.

What users can do

  • Start a new conversation, open history, rename a conversation, or delete it.
  • In the shared `Chats` surface, users first see a history screen across active AI teammates, then open a teammate conversation or start a fresh teammate chat from a target chip.
  • Shared `Chats` history uses the same teammate-only filtering as Cowork. It does not mix in Ally conversations.
  • Send text, reply to a message, stop generation, and send attachments.
  • Use `Enter` to send from the current internal-chat composer.
  • Use `Shift+Enter` or `Alt+Enter` to insert a newline without sending.
  • Use `@` teammate mentions and `#` shared-file mentions when mention sources are available.
  • `@` mentions resolve from the teammate catalog for the current org. In AI-teammate chat, that list can also include Ally; the currently open teammate is excluded from the mention list.
  • `#` file mentions are scoped to the current AI teammate's readable shared folders, not the org's entire Storage tree.
  • Recall previously sent user messages with `ArrowUp` / `ArrowDown` when the composer is otherwise idle.
  • Leave feedback on assistant replies:
  • `Like`
  • `Dislike`
  • `Feedback` comment editor
  • Failed system-error assistant messages support comment-only feedback.
  • Use voice mode for Ally and AI teammate chat when that chat has realtime voice enabled.

Reasoning and display behavior

  • The composer shows a `Reasoning` control only when the resolved model supports reasoning.
  • User-facing reasoning selections are:
  • `Off`
  • `Low`
  • `Medium`
  • `High`
  • Reasoning preference is persisted in local storage and scoped by user, org, peer, entity, and conversation. A draft selection can carry forward into the first persisted conversation.
  • The reasoning selector is hidden while voice mode is active.
  • Assistant messages can persist a preface with reasoning, tool calls, and source cards, so those details survive reloads.
  • Chats that are already at the bottom stay pinned during streaming, thinking updates, and panel/viewport resize. If the user scrolls away, expanding a reasoning/tool section does not force them back to the bottom.

Mobile and onboarding behavior

  • On mobile, the internal-chat panel renders full width above the shared bottom nav instead of as a desktop-sized floating panel.
  • Tapping outside the mobile panel overlay closes it.
  • The onboarding URL flag `?onboarding=true` auto-opens Ally once the scoped chat state has restored.
  • Onboarding Ally bootstrap prefers the latest server conversation once per user/org scope, so users land in the current onboarding thread instead of a blank draft.
  • The onboarding floater is positioned bottom-right on desktop when the saved chat mode restores as a floating session.

REST endpoints the current UI uses

  • AI teammate chat:
  • `GET /api/organizations/{orgId}/employees/{employee_id}/messages`
  • `POST /api/organizations/{orgId}/employees/{employee_id}/messages`
  • `POST /api/organizations/{orgId}/employees/{employee_id}/conversations/new`
  • `POST /api/organizations/{orgId}/employees/{employee_id}/stop-generation`
  • `GET /api/organizations/{orgId}/employees/{employee_id}/conversations`
  • `GET /api/organizations/{orgId}/employees/{employee_id}/conversations/search`
  • `PATCH /api/organizations/{orgId}/employees/{employee_id}/conversations/{conversation_id}/title`
  • `DELETE /api/organizations/{orgId}/employees/{employee_id}/conversations/{conversation_id}`
  • Ally chat:
  • `GET /api/organizations/{orgId}/ally/messages`
  • `POST /api/organizations/{orgId}/ally/messages`
  • `POST /api/organizations/{orgId}/ally/conversations/new`
  • `POST /api/organizations/{orgId}/ally/stop-generation`
  • `GET /api/organizations/{orgId}/ally/conversations`
  • `GET /api/organizations/{orgId}/ally/conversations/search`
  • `PATCH /api/organizations/{orgId}/ally/conversations/{conversation_id}/title`
  • `DELETE /api/organizations/{orgId}/ally/conversations/{conversation_id}`
  • Capability bootstrap used by the current frontend:
  • `GET /api/init/internal-chat-capabilities`
  • Current response only exposes Ally model availability.

Feedback and realtime

  • Canonical internal-chat feedback endpoint:
  • `PUT /api/organizations/{orgId}/conversations/{conversation_id}/messages/{message_id}/feedback`
  • Feedback comments are capped at `500` characters.
  • Only the conversation owner can update feedback.
  • `429` feedback responses are surfaced as rate-limit failures, and `409` is used for messages that do not accept feedback.
  • Internal chat subscribes to:
  • `internal.message`
  • `internal.message_updated`
  • `voice_thinking_started`
  • `voice_thinking_ended`
  • `internal.message_updated` is the channel used to sync feedback edits and other message updates into the transcript.
  • Messages with status `in_progress` are not rendered in the transcript or conversation previews.

Attachments and voice

  • Shared chat input currently enforces:
  • max `5` attachments per message
  • `Too many attachments` toast when exceeded
  • drag/drop overlay text `Drop files here`, or `Attachment limit reached` when the cap is already hit
  • Clipboard-pasted generic image names are rewritten to `screenshot-...`.
  • Realtime voice session creation currently uses:
  • `POST /chat/realtime/employee/create-session/{organization_id}/{employee_id}`
  • `POST /chat/realtime/ally/create-session/{organization_id}`
  • Voice session creation returns a `conversation_id` so the chat UI can bind the realtime session to the correct conversation.
  • Employee and Ally voice session creation require exactly one of:
  • `conversation_id`
  • `create_new_conversation`

Start building your AI team