Technical docs

Internal Chat

Public reference generated from tech docs/internal-chat.md.

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