Configuration & providers
The Assistant is configured entirely through the root Assistant configuration section
(bound to AssistantOptions) plus two host calls on the backend and one module flag on the
frontend. This page covers the providers, the wiring, and the runtime behaviour you can tune.
For what the feature does, see the AI Assistant overview. For DB-enforced tenant isolation, see Tenant isolation & SQL hardening.
Providers
Section titled “Providers”Four providers ship, selected by Assistant:Provider (case-insensitive). The right endpoint and
model go with each:
| Provider | Endpoint |
Example Model |
API key |
|---|---|---|---|
| OpenAI | https://api.openai.com/v1 |
gpt-4o-mini, gpt-4 |
required |
| Gemini | https://generativelanguage.googleapis.com/v1beta |
gemini-pro |
required |
| DeepSeek | https://api.deepseek.com/v1 |
deepseek-chat |
required |
| Ollama | http://localhost:11434 |
codellama:7b, llama3:8b |
not required (local) |
Provider selection happens at DI time (RegisterAssistantProvider): the configured name maps to
OpenAiProvider / GeminiProvider / DeepSeekProvider / OllamaProvider, each implementing
IAssistantProvider. An unknown name throws at startup with the supported list.
Backend wiring
Section titled “Backend wiring”The umbrella AddGenieApp already registers the Assistant module and maps the hub. A host that
composes the engine directly adds two calls:
services.AddGenieAssistant(builder.Configuration); // provider + MCP tools + services// …app.MapAssistantHubs(); // the /hubs/assistant-chat SignalR hubAddGenieAssistant (ServiceCollectionExtensions) binds AssistantOptions, registers the HTTP
clients, the core services (SchemaContextBuilder, NaturalLanguageQueryService,
ConversationService, ChatHistoryService, AppDocsService, AssistantQueryExecutor, …), the
four MCP tools, the McpOrchestratorService, the selected provider, and the AssistantChat
authorization policy that gates the hub.
Configuration reference
Section titled “Configuration reference”Configuration lives in the root Assistant section (not under Genie):
"Assistant": { "Provider": "OpenAI", // OpenAI | Gemini | DeepSeek | Ollama "Endpoint": "https://api.openai.com/v1", "Model": "gpt-4o-mini", "ConversationMode": true, // keep chat context across turns "AutoGenerateTitle": true, // AI-summarise the first message into a chat title "DocsPath": "AssistantDocs", // optional: a dir of *.md help docs (merged over baseline) "ChatWidgetEnabled": true, // gates the AssistantChat auth policy / hub "ChatWidgetEnabledForRoles": "*", // "*" or a list/CSV of role names, e.g. ["Admin","Analyst"] "ConnectionString": "" // optional read-only DB login for generated SQL (see hardening)}Other notable AssistantOptions knobs (all optional, sensible defaults):
MaxTokens(10000),Temperature(0.1),TopP(0.9),TimeoutSeconds(60) — generation parameters.ConversationHistoryLimit(3) — how many recent Q&A pairs (beyond the system prompt) are sent each turn, to control token usage.SchemaTableLimit(15) — how many tables are described inline in the system prompt; the rest remain reachable viaget_table_schema.ToolResultMaxChars(8000) — cap on a single tool result before truncation.WelcomeMessage/WelcomeChips— the greeting and quick-action chips shown on an empty chat.
The API key — keep it out of source
Section titled “The API key — keep it out of source”ASP.NET Core layers the environment-variable provider after the JSON files, and nested keys map
via the __ separator. So set the key as an OS variable rather than committing it:
# Windows — the double underscore maps to Assistant:ApiKeysetx Assistant__ApiKey "sk-…"# then restart the shell/IDE so the process inherits itThe same applies to the hardening connection string (Assistant__ConnectionString). Ollama is
local and needs no key.
Frontend createGenieApp module
Section titled “Frontend createGenieApp module”Mount the assistant by enabling the module. It renders app-wide over every route — an AI icon in the header (left of the notification bell) opening a themed bottom-right panel:
createGenieApp({ apiBase: "/api/v1", modules: { assistant: true },});The panel is multi-conversation: a conversations list (open / rename / delete / new, plus
multi-select bulk delete) and the conversation view — user/assistant bubbles as sanitised Markdown
(GFM tables, lists, code) via marked + DOMPurify, a live Thinking disclosure, a collapsible
SQL block and result-table preview for data answers, suggestion chips, a Shift+Enter
composer, and a stop control while a reply is in flight. It is accent-/theme-aware.
The UI talks to the backend over AssistantChatHub when connected and falls back to REST
(api/assistant: POST /query, thread CRUD GET/POST /chats, GET/PATCH/DELETE /chats/{id},
POST /chats/delete for bulk delete) otherwise. GenieAssistant and GenieAssistantButton are
also exported for hosts that want to place or configure them manually (custom title, subtitle,
suggestions, welcome). See Frontend configuration.
Persistence, titles and error masking
Section titled “Persistence, titles and error masking”- Persistence. Conversations live in the database (schema
Genie, tablesAssistantChat+AssistantChatMessage), owned per user (UserId+CompanyId). Non-admins only see their own threads. A thread is saved only once its first reply succeeds; a failed first turn is rolled back. Host apps must add the migration for the two tables (dotnet ef migrations add AddAssistantChat -c YourContext). - Titles. New threads show a truncated placeholder immediately. With
AutoGenerateTitleon (default) the provider summarises the first message into a concise title after the first reply, pushed live to the list (ConversationRenamed); on failure the placeholder is kept silently. A manual rename (PATCH /chats/{id}) always overrides a generated title. - Error masking. Internal error detail (a missing/invalid key, a raw provider failure) is
surfaced only to users holding the
Systemrole (AssistantErrors.ForUser). Everyone else sees a generic “The assistant is temporarily unavailable…” message. Generated SQL is likewise returned to admins only.
Where to go next
Section titled “Where to go next”- Tenant isolation & SQL hardening — the read-only login + RLS setup that makes tenant scope DB-enforced.
- AI Assistant overview — the tool-orchestration model and prompt context.