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.
- 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.

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:

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:
- Draft descriptions — generate customer-facing descriptions for every selected product.
- Extract attributes — scan the product title, description, and media to propose structured attribute values.
- Title variants — generate a handful of alternative titles for A/B testing or channel-specific wording.
- 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:

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:

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:

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:

After you press Confirm:
- The system re-reads each target row to make sure no one else edited it in the meantime.
- Rows that changed under you are skipped and surfaced as "stale — please retry" in the result card.
- The remaining rows are updated inside a single database transaction.
- 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
- Install LM Studio and download a chat/instruct model, such as a Llama instruct model.
- Start LM Studio's local server and keep it listening on
http://localhost:1234/v1. - 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
| Combo | Action |
|---|---|
Cmd/Ctrl+L | Open the global AI assistant launcher |
Cmd/Ctrl+K | Open the global search dialog |
Cmd/Ctrl+J | Open the legacy command palette (OpenCode chat) |
Cmd/Ctrl+Enter | Send the current message in the chat |
Esc | Cancel the streaming response or close the dialog |
Related
- Admin setup: AI Agents settings
- Architecture: AI Framework Overview
- Developers — add a new agent: Developer Guide