Skip to main content

AI Assistant

Open Saasframe ships with AI-powered assistants you open directly from the admin pages you already use. Each assistant is scoped to one domain (customers, catalog) and knows only what its agent contract allows it to know. Every change the assistant proposes requires an explicit Confirm before it touches your data.

When to use each assistant
  • Account Assistant — open on a person, company, or deal page when you need to explore the record and its linked history in plain English.
  • Merchandising Assistant — open on the products list when you want to draft descriptions, extract attributes, or stage bulk price and title updates.

Opening the AI sheet

There are two ways to open an assistant.

From any page — the global launcher (Cmd/Ctrl+L)

Every backoffice page shows an AI pill in the topbar (next to global search). Click it — or press Cmd/Ctrl+L from anywhere in the admin — to open a search dialog listing every assistant you have access to. Type to filter by name, description, or module; arrow keys navigate; Enter launches; Escape closes.

AI assistants picker with three registered agents and Can write badges

The launcher self-hides when no AI provider is configured or when your account has access to no assistants. If you don't see the button, ask your administrator to grant ai_assistant.view to your role and confirm at least one of ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_GENERATIVE_AI_API_KEY is set.

Each row shows the assistant name, what it does, and a Can write badge if the assistant is allowed to propose changes (always behind an approval card).

From the page you're on — the per-page trigger

On any supported page (person, company, deal, products list, …) you'll see an Ask AI button in the page header or toolbar. Click it to slide the AI sheet in from the right. The sheet carries the current page context automatically — there's no need to paste record ids.

The Customers AI assistant, opened from the people list, can search across people, companies, deals, and activities and stream rich record cards back into the chat:

Customers AI assistant searching for "Norton" and rendering people record cards in the chat

The merchandising demo (D18)

The Merchandising Assistant lives on the products list at /backend/catalog/catalog/products. Pick any set of rows with the row-checkbox column, click Ask AI, and the sheet opens primed with four canned prompts:

  1. Draft descriptions — generate customer-facing descriptions for every selected product.
  2. Extract attributes — scan the product title, description, and media to propose structured attribute values.
  3. Title variants — generate a handful of alternative titles for A/B testing or channel-specific wording.
  4. Price adjustment suggestion — compute a justified price delta per product based on the current price, cost, and category peers.

The assistant streams quick stats like product, active, category, and tag counts as a compact overview card so you can size up the selection at a glance:

Catalog Merchandising Assistant rendering a quick catalog overview stats card with Products, Active, Categories, and Tags counts

Drilling into the same chat, asking for a sample of records returns rich product cards with status badges, SKU, description, and a deep link back to the record:

Catalog Merchandising Assistant streaming three product record cards with status badges and SKUs

Every chat thread is preserved per assistant. Open the history menu in the sheet header to jump back into a prior session — the canned prompt picker stays accessible while you flip between threads:

Catalog Merchandising Assistant Recent Sessions dropdown listing previous chat threads with timestamps

The approval flow

Any time the assistant wants to write something, it does not write directly. Instead it renders a proposal card with:

  • The tool it wants to run (for example, catalog.update_product).
  • A field-by-field diff of the current value vs the proposed value, per product.
  • A [Confirm All] button for the whole batch and an optional per-row reject toggle.

Nothing is persisted until you press Confirm.

The proposal card below was raised by the Customers Account Assistant when the operator asked it to log a planned call as a new activity. Notice the Action applied banner from the previous turn (a comment that was already approved earlier in the session) and the new Review proposed changes card with a per-field before/after table — every value the assistant wants to write is shown alongside the Cancel and Confirm buttons:

Mutation approval card showing customers.manage_record_activity proposal with field-by-field diff and Cancel/Confirm controls

After you press Confirm:

  1. The system re-reads each target row to make sure no one else edited it in the meantime.
  2. Rows that changed under you are skipped and surfaced as "stale — please retry" in the result card.
  3. The remaining rows are updated inside a single database transaction.
  4. The products list refreshes in place — no page reload needed.

Read-only vs confirm-required

Not every assistant can write. An assistant's operating envelope is printed in the sheet header:

  • Read-only (the shipped default for the Catalog Assistant) — the assistant can explore and answer questions, but it will never propose a write. Questions that would require a write ("update this deal to stage X") are politely refused.
  • Confirm required (the shipped default for the Customers Account Assistant and the Catalog Merchandising Assistant) — every write is staged as a proposal card with diff + Confirm.
  • Destructive confirm required — the same flow, scoped to destructive actions (deletes, bulk cascades). The card explicitly labels the destructive scope.

Your administrator can tighten an assistant from confirm-required down to read-only at any time (see AI Agents settings). They cannot loosen it beyond what the shipped agent declares.

Local LLMs with LM Studio or Llama

Open Saasframe can use local OpenAI-compatible servers for typed AI agents. This is useful for development, demos, offline work, or testing open-weight Llama models before choosing a hosted provider.

LM Studio

  1. Install LM Studio and download a chat/instruct model, such as a Llama instruct model.
  2. Start LM Studio's local server and keep it listening on http://localhost:1234/v1.
  3. Add these values to your app .env:
SF_AI_PROVIDER=lm-studio
LM_STUDIO_API_KEY=lm-studio
LM_STUDIO_BASE_URL=http://localhost:1234/v1
SF_AI_MODEL=<the model id shown by LM Studio>

LM Studio accepts OpenAI-compatible requests on the local server. The API key is only a placeholder for local development; use the exact model id reported by LM Studio's server or model list.

Ollama / local Llama

If you run Llama through Ollama's OpenAI-compatible endpoint, use the built-in ollama provider:

SF_AI_PROVIDER=ollama
OLLAMA_API_KEY=ollama
OLLAMA_BASE_URL=http://localhost:11434/v1
SF_AI_MODEL=llama3.3

For hosted Llama models, use one of the OpenAI-compatible providers in the settings page, such as OpenRouter, Groq, Together, Fireworks, or DeepInfra. After changing env values, restart the app and open Settings → AI Allowlist and Settings → AI Agents to confirm the provider and model are available for the tenant and agent.

Tips

  • The assistant only sees records your user account can already see. It inherits your roles and permissions.
  • Proposals expire after 15 minutes of inactivity by default. If a proposal expires before you confirm, just ask again — the context is preserved in the chat.
  • Attachments (product images, PDFs) are supported on agents that declare the right media types — drop them into the chat input to include them. The Send button stays disabled while attachments are uploading; the composer hint switches to "Uploading attachments…" until every chip is ready. Each file has a 60-second upload timeout — failed uploads surface as a red chip you can remove and retry.
  • The sheet shows Thinking… while the assistant runs; reasoning streams into a collapsible panel; you can cancel with Escape at any time.
  • Open multiple sessions with the same assistant — each tab has its own thread. Sessions persist across page reloads (history is kept locally).

Keyboard shortcuts

ComboAction
Cmd/Ctrl+LOpen the global AI assistant launcher
Cmd/Ctrl+KOpen the global search dialog
Cmd/Ctrl+JOpen the legacy command palette (OpenCode chat)
Cmd/Ctrl+EnterSend the current message in the chat
EscCancel the streaming response or close the dialog