Spacerr
  • Features
  • Pricing
  • FAQ
  • Docs
Get Access
Spacerr
  • Introduction
  • Features
  • Tech Stack
  • Setup
  • Configuration
  • Agents
  • Database
  • Jobs
  • Admin
  • Settings
  • Billing
    • AI Workspace
    • Projects
    • Library
    • Context
    • Models and tools
    • Streams and realtime
  • Storage
  • Email
  • Support
  • Localization
  • SEO
  • Analytics
  • UI And Navigation
  • Deploying To Production
  • Testing And QA
  • Troubleshooting

Search documentation

Search documentation pages.

Documentation/AI Workspace

AI Workspace

Spacerr includes a complete AI workspace, not a small demo chat. It has persistent conversations, projects, files, model selection, streaming controls, realtime sidebar updates, tool rendering, citations, generated images, and a global AI widget.

What It Looks Like

The AI product surface is split into a few user facing areas:

  • Dashboard chat at src/features/ai/chat/components/dashboard-chat.tsx.
  • Chat session UI under src/features/ai/chat/components/chat-session.
  • Chat sidebar under src/features/ai/chat/components/chat-dashboard-sidebar.
  • Project workspace under src/features/ai/chat/components/project-workspace.
  • Global AI widget under src/features/ai/widget.
  • Global realtime bridge at src/features/ai/chat/components/chat-realtime-events-bridge.tsx.

The main chat route renders the dashboard shell, sidebar, active chat session, and project workspace surfaces. The user can create chats, move chats into projects, upload files, search history, choose a model, stop streams, retry messages, and regenerate assistant responses.

AI Widget

The app also includes a global AI widget for pages that exist outside the dashboard. Many real SaaS products have important public and account surfaces such as the landing page, pricing page, checkout flow, blog, contact page, and legal pages. A widget gives users a way to ask questions and get help from those surfaces without first navigating into the dashboard workspace.

The widget is intentionally extensible. You can keep it as a lightweight assistant entry point, connect it to support workflows, pass page context into prompts, limit where it appears, or reshape it for your own product experience. The route visibility logic lives in src/features/ai/widget/utils/ai-widget-route-visibility.utils.ts, and the UI lives under src/features/ai/widget/components.

Core Features

The workspace includes:

  • Persistent chat history with saved messages and older message pagination.
  • Auto generated and editable chat titles.
  • Chat search across saved conversations.
  • Draft persistence per chat, including unsent text and attachments.
  • Pending prompt persistence for users who start typing before signing in.
  • File upload, drag and drop, paste support, attachment previews, and attachment removal.
  • Project workspaces with project chats, project source files, and project aware context.
  • Multi model selection through the model picker, with the selected model saved locally.
  • Streaming responses with stop, retry, regenerate, retry from a specific assistant message, and resume support.
  • Markdown, code blocks, math, Mermaid diagrams, citations, generated image results, timestamps, and model metadata.
  • Assistant message actions for copy, like, unlike, removing reactions, and optional unlike feedback.
  • User message copy actions.
  • Tool status labels that show human readable progress for web search, image generation, and support tools.
  • Realtime sidebar state, active stream indicators, unseen indicators, and multi tab updates.

Feature Layout

Most AI code lives under src/features/ai/chat.

txt
src/features/ai/chat
  api
  components
  constants
  hooks
  providers
  repositories
  schemas
  store
  tools
  types
  utils

Use components for UI, hooks for client behavior, repositories for data access, schemas for request validation, tools for AI tool calls, store for client runtime state, and utils for stream, context, message, and project helpers.

Request Flow

The chat request is validated by src/features/ai/chat/schemas/chat-request.schema.ts.

typescript
export const chatRequestSchema = z.object({
  chatId: z.string().min(1),
  trigger: z.enum(["submit-message", "regenerate-message"]).default("submit-message"),
  projectId: z.string().min(1).nullable().optional(),
  modelId: z.enum(CHAT_MODEL_IDS).default(DEFAULT_CHAT_MODEL_ID),
  message: z.unknown().optional(),
  pageUrl: z.url().optional(),
  sourceClientId: z.string().min(1).optional(),
})

The important fields are:

  • chatId identifies the conversation.
  • trigger decides whether the user submitted a new message or regenerated an assistant response.
  • projectId connects the request to a project workspace.
  • modelId chooses the active model.
  • message carries the incoming user message.
  • pageUrl gives the assistant current page context.
  • sourceClientId helps realtime updates ignore events from the same browser client.

Where To Customize

Use these files first:

  • src/features/ai/chat/constants/chat-model.constants.ts for model options, context budget, and project source limits.
  • src/features/ai/chat/constants/ai-shared-context.constants.ts for product context and available pages.
  • src/features/ai/chat/utils/chat-system-prompt.server.ts for system prompt assembly.
  • src/features/ai/chat/tools/chat-tools.server.ts for available tool calls.
  • src/features/ai/chat/components/chat-session for the chat UI.
  • src/features/ai/chat/components/chat-dashboard-sidebar for sidebar behavior.
  • src/features/ai/chat/components/project-workspace for project files and project chats.
  • src/features/ai/widget for the global AI widget.

Keep AI product behavior inside the feature owned AI folders. Shared route strings still belong in ApiRoutes and WebRoutes.

Billing

Learn how Stripe checkout, price IDs, webhooks, access state, and pricing customization work.

AI Projects

Learn how project workspaces, project chats, and project source files support AI context.

On this page
What It Looks LikeAI WidgetCore FeaturesFeature LayoutRequest FlowWhere To Customize