Technical docs
Ally, the Built-In Platform Assistant
Public reference generated from tech docs/ally-ai.md.
What Ally is
* Ally is Alloy's built-in internal assistant. * The main user entry point is the sidebar `Chats` launcher and the global `Alt+C` shortcut. * In the current backend, Ally chat resolves to a per-user Ally AI teammate inside the current organization.
Frontend surface
* The sidebar `Chats` item is an action entry that opens internal chat directly instead of navigating to a dedicated `/ai` page. * `useOpenChat({ peer: 'ally' })` resolves to `openAlly()`. * Ally chat state is scoped per `user + organization`, then restored from persisted snapshots on load. * Current view modes: * docked panel * floating window * minimized stack * `toggleAlly()` closes Ally only for the current org scope; a minimized Ally session restores instead of closing.
REST and realtime surface
* Frontend conversation adapter base: * `/api/organizations/{organizationId}/ally` * Confirmed Ally REST actions: * `POST /ally/conversations/new` * `GET /ally/conversations` * `GET /ally/conversations/search` * `PATCH /ally/conversations/:conversation_id/title` * `DELETE /ally/conversations/:conversation_id` * `GET /ally/messages` * `POST /ally/messages` * `POST /ally/stop-generation` * Realtime voice session creation: * `POST /chat/realtime/ally/create-session/:organization_id`
Runtime context
* Ally uses the shared internal-chat pipeline, but the current backend resolves Ally through `Channel.EMPLOYEE_CHAT` rather than a separate Ally-only contact-channel type. * `allyStrategy` resolves the current user's Ally AI teammate with `AiEmployeeService.findUserAllyEmployee(organizationId, userId)`. * Runtime context for Ally runs currently includes: * `userId` * Current Ally contact-channel identity uses the same employee-chat external ID pattern as AI teammates: * `emp__{user.id}_{employeeId}` * Current conversation lookup is therefore scoped by: * user * organization * resolved Ally employee * New or restored user-organization memberships create/update that user's Ally AI teammate through `UserOrganizationService` and the Ally employee helpers. * When a per-user Ally is processed, its own model, voice settings, tools, and MCP toolsets are used first. If the canonical system Ally is configured, missing model or voice settings fall back to that system Ally, and tool lists/toolsets are unioned.
Organization action tool
* Ally can perform organization-scoped actions through the supported system action layer when running in an authorized system context.
Internal-chat behavior notes
* Ally shares the same internal-chat UX stack as AI teammates: * history * search * rename/delete * reply state * feedback * attachments * docked/floating/minimized modes * realtime voice * Model availability is exposed through: * `GET /api/init/internal-chat-capabilities` * If Ally is not configured for the current user/org resolution path, Ally route actions can return `Ally not found` or `Ally configuration incomplete`. * In storage sharing UX, Ally is treated as a system storage actor rather than a normal editable share target.
* Ally's system-only tool surface also includes documentation list/search/read tools through the shared system tool catalog.
Onboarding behavior
* New self-serve org bootstrap can seed an Ally welcome message. * The welcome message is written into the new user's personal Ally conversation by resolving that user's per-user Ally employee in the new org. * The current welcome begins with `Welcome — I’m Ally.`. * `?onboarding=true` still auto-opens Ally on first load after scoped chat state is restored. * Current onboarding redirect target is `/staff?onboarding=true`. * See `onboarding.md` for the full signup and invite flow.