TabulariaDocs

DocumentationIntegrations

AI in Tabularia

Tabularia can use a language model in five places: a chat that answers questions on the datasources, an assistant that builds flows in the editor, one that writes Python and R scripts, the naming of conversations, and the descriptions and SQL translations of the dbt export. All of it is optional, off until an administrator adds a model provider, and limited to the models the administrator enables. This page says, for each use, what goes to the model and what does not, and how to configure, cap and audit it.

At a glance

Providersany number: Anthropic, through its own SDK, and any endpoint that speaks the OpenAI chat-completions protocol, with tool calls, and lists its models at GET /models
Who talks to themthe gateway only; the engine and the workers never call a provider
Onwhen a provider is added in Administration → AI models, or AI__BASE_URL and AI__SECRET_KEY are set, and at least one model is enabled
Modelschosen by the administrator from each provider's catalog; none enabled by default
Instructionssix system prompts, editable in Administration → AI models → Agent instructions
Costsestimated per answer; caps per answer, per person per day, per installation per day
Auditevery query on data, every provider changed, every model enabled or disabled, every instruction changed
Sending no datametadata-only mode: two switches, one for these uses and one for MCP

Where the AI is used

UseWhereSends to the modelNever sends
Data assistantAssistant page (Ask your data)the question and the conversation; names, folders, row counts and descriptions of the datasources the person can read; columns, types and field descriptions; 5 sample rows of each datasource it describes; the rows its queries return, up to AI__MAX_RESULT_ROWS (200), text cut at 300 characters; when it builds, what the flow assistant gets (the first rows of every step) and the names, types and folders of the connections the person may usedatasources the person cannot read; storage paths and credentials; a connection's address, user or secret
Flow assistantflow editor, right panel, Assistant tabthe request; the flow on the canvas (its nodes and their settings) and the selected node; the same catalogue tools as the data assistant (sample rows included); the first 5 rows of every step it adds or changes, and up to 30 rows when it previews a nodedata the person cannot read; the flow's saved versions
Script assistantScript node and saved script editor, Assistant (Kubernetes only)the request; the code; the environment's language, version and packages; the names of the variables the script finds; names and types of its inputs' columns; after a failed run, only the error of its log (the Python traceback, the R error)any row of data; the values of variables; what the script printed
Conversation titlesdata assistantthe first question of a conversation (up to 1,000 characters), onceanything else
dbt descriptionsthe dbt export dialog, when ticked (dbt export)each flow's structure (sources, steps with their settings cut at 300 characters, outputs); the columns without a description, with their type and up to 3 sample values of up to 40 characters eachfull rows; columns that already have a description
dbt SQL translationsthe dbt export, when a query does not translate to the target dialectthe query (up to 20,000 characters), the two dialects and the output columns; on a second attempt, why the engine rejected the firstdata
AI commentsa dashboard or a report, on an AI comment elementthe instruction of whoever built it; the title and the numbers of the KPIs, charts and tables it reads, as the screen writes them, with a table's groups and totals and a matrix's page. Never a row: a table's detail rows and a scatter that is not aggregated stay outanything else: it has no tool to query with

The SQL script editor has no assistant.

The script assistant sees no data. Its tools cannot read a datasource. When it fixes a failed run, Tabularia extracts from the log only what the interpreter writes for an error (the frames and the exception line of the last Python traceback; the last R Error… line, rlang's ! lines, Calls: and Execution halted) and drops everything the script printed, even lines shaped like errors. The error message itself may quote a value, as errors do («could not convert 'abc'»). Without such an error, the model is told the exit code only. The editor says so under the input: «The model gets the code, the names and types of the columns and the error of a failed run: never a row of data.»

The data and flow assistants do send rows. As many as a query or a preview returns, within the caps above, to the provider of the model the person chose. Pick the providers accordingly, and keep personal data out of the datasources whose readers use the assistant, or turn on metadata-only mode.

What the assistants can change. The assistant of the Assistant page changes nothing by itself: what it builds — flows, their runs and schedules, and the other objects its tools offer — becomes a plan that the person reads in a card under the answer and applies with its «Confirm» button (or on the plan's page); the assistant has no way to confirm it, and the person's permissions are checked again when it is applied. The flow assistant changes only the canvas in the browser: what it built comes back as one Undo step, and it never saves, runs or schedules the flow. The script assistant proposes whole files that the person applies or discards; it never saves or runs the script.

A plan card on the Assistant page: create a flow with its steps and first rows, then schedule it, with Confirm, Change and Cancel

A plan waiting for Confirm on the Assistant page: nothing has changed yet (the example).

Metadata-only mode

With this mode on, no value of a row of data goes to a model. There are two switches, both off by default and both changed live in Administration → Settings, with a line in the audit log; every gateway replica applies a change within 10 seconds:

VariableCoversWhose model
AI__METADATA_ONLYthe chat, the flow assistant, the script assistant, the dbt export, the AI commentsthose configured in Tabularia, whichever the provider
MCP__METADATA_ONLYthe MCP serverthe client's, outside the administrator's control

Administration → AI models shows the state of both.

Goes to the modelDoes not
names of datasources, folders, columns, flows, connections, tables and filessample rows, query results, previews
types, row counts, the descriptions people wroteaggregates and charts: a total is a value of the data
the structure of flows, flow groups, SQL scripts and notebooks, with their schedulesthe text of errors of the engine, of runs and of connections: could not convert 'abc' quotes one
the SQL saved in a script or a datasourcea refresh's notes (the values it did not find; their count goes)
for the script assistant, the code and the exit code of a failed runfor the script assistant, the error of a failed run

The barrier is in the tools, not in a prompt, so no agent's instructions can open it. Each tool declares whether it returns values of the data: those that do are not offered, and calling one over MCP anyway is refused; those that hold both, such as describe_datasource, leave the data out. Here is what changes for each use:

  • Chat: the dialog at the start says the mode is on, and asks to be read again when an administrator changes the mode. The model is told it cannot read data, so it says so instead of inventing figures. It can still explain what a datasource holds from its descriptions, write SQL for the person to run, and build. There are no result tables under its answers. A plan's card still shows the person the first rows: they never go to the model, nor does whether the query of a planned SQL script fails.
  • Flow assistant: it adds and changes steps without any preview, neither rows nor columns nor the preview's error come back (the columns of a pivot are values, and whether a step fails can be made to depend on one). The person checks the result on the canvas.
  • Script assistant: it loses the help on a failed run: the editor says so, and the person describes the problem in their own words.
  • dbt export: columns are described from their name and type. Descriptions already written from sample values before the mode came on stay in the project: they are not sent again.
  • AI comments: a total is a value, so nothing is sent and no number is read for one: the element says it is off, in a PDF, an image or an email too, which go out all the same, and what was written before the mode came on is not shown.
  • Conversations: the turns of a conversation made outside the mode stop going to the model, whole (a tool's result, the SQL the model wrote after reading it, what it answered, the choices of a card), so the model does not remember them, and says so. The person still reads them on the page and can still download a past result. Turns made in the mode go back as usual. Turning the mode off sends everything back again.
  • A turn in progress when the mode comes on stops before its next request to the model, with a message saying so. One begun in the mode stays in it to its end.

What stays visible

The mode keeps the values of your rows from the model. It cannot keep from it what people wrote into the structure, which is what the model needs in order to work on it:

  • constants in the settings of a flow: country = 'IT' in a filter, a value in a fill_null, the literals of a computed column;
  • constants in SQL: a saved script, the query of a datasource, a post-SQL;
  • the text of descriptions, of a note on the canvas, of a Pushmail or an email Output (subject, body, recipients), the parameters saved with a report in a flow group, the names of the variables of a script;
  • whatever the person types in the conversation;
  • names that are values: the column a pivot made out of a value and published in a datasource, a file called after a customer, a table named after a client.

If those hold something confidential, the mode does not protect it.

It does not close every side door either, and these are decisions, not oversights:

  • Row counts and the state of a run go, on purpose. A flow that filters on a guessed value, or fails only when a value is there, and is run after the person confirms its plan, will show how many rows it wrote and whether it failed.
  • MCP__METADATA_ONLY covers /mcp. An API token also works on the rest of Tabularia's API, where it reads what its owner may read. A client that hands its model a generic HTTP tool and the token is outside this barrier: give MCP clients a token only through their MCP configuration, and a service account with only the folders it needs.
  • A page opened before an administrator changes the mode keeps showing the old state until it is reloaded. The gateway applies the mode in force, whatever the page says.

Permissions of each use

UseWho
Data assistantanyone signed in; it reads what the person can read (VIEW) and builds only where they may (EDIT, RUN, CONNECT), checked at every call and again when a plan is applied. Observers can ask, reading only, but their conversations are not saved
Flow assistantEDIT on the flow's folder (any signed-in person on a flow not saved yet); not observers
Script assistantthe use of the script's environment; not observers
dbt export with AIwhoever may export the flow (dbt export)
Add and change providers, enable models, change the instructionsadministrators; observers read them, without the providers' addresses or keys

Telling people it is an AI

The three assistants open with the same dialog, «You are writing to an automated assistant», and stay locked until «I understand». It names the providers of the models on offer, by the name the administrator gave them, and asks again when that list changes. Every answer is labelled «AI assistant» with its model and its provider; under the input, the provider of the model chosen («Your messages, and what the assistant reads for them, go to …») and «This is an AI: it can make mistakes. Always check the results.» A downloaded conversation opens with the same notice. The acceptance lives in the browser, so every new browser, or a shared account on another machine, asks again. Details: Ask your data.

The dialog You are writing to an automated assistant, with its four points and the button I understand

The notice every assistant opens with, until «I understand».

Configuration

The providers

Administration → AI models → AI providers lists them. An administrator adds one with a name, a type, an address and an API key, tests it, turns it off or removes it. The name is what people read as who gets their data. The key is encrypted with SECURITY__FERNET_KEY and never comes back, not in the page, the log, the audit or an error: an empty field keeps it. A new address needs the key typed again, so a saved key cannot be sent elsewhere. Every change goes to the audit log, without the key.

TypeAddressModels come from
Anthropicempty, for https://api.anthropic.comthe Models API, through Anthropic's SDK
OpenAI-compatiblethe endpoint, ending in /v1, hosted or inside your networkGET {address}/models

Data leaves your network only if the address is outside it. An OpenAI-compatible endpoint must also answer chat completions with tool calls, which is how the assistants use their tools.

Administration, AI providers: a provider from the environment, read-only, and Anthropic, with its buttons to test, change, turn off and remove

Administration → AI models: the providers. Only the environment's cannot be changed here.

A provider from the environment stays what it always was, and appears in the list as «from the environment», named after its host; it is changed where it is set:

VariableHelm value
AI__BASE_URLai.baseUrlan OpenAI-compatible endpoint, ending in /v1
AI__SECRET_KEYsecrets.aiSecretKeyits API key
AI__ACCESS_KEYai.accessKeythe key's identifier, informational only
AI__DEFAULT_MODELai.defaultModeloffered first in the pickers, and used by the dbt export, when enabled

On Kubernetes, ai.enabled: true renders these variables; the chart refuses to render without ai.baseUrl and the secret. The full list, with the caps below, is in Configuration.

Turning a provider off, or removing it. Its models can no longer be chosen, and a request for one is refused with the reason. Its conversations stay readable, and go on with another model: the page says the next message goes to the model selected. Turned on again, its models are back as they were. Removed, its key and its enabled models are gone; the panel says first how many conversations and models depend on it.

Anthropic. Tabularia sends no sampling settings and no thinking, and never forces a tool call: today's models refuse them. Effort is set to medium on the models that take it (low for the titles), max_tokens to 32,000, and prompt caching is on for the assistants' turns. Thinking blocks go back untouched. When the conversation before them has changed (the date, the plans, the datasources in focus are in the system prompt) the API refuses them, and Tabularia repeats the request asking it to drop them: the person sees nothing, and the refused request costs nothing. A history cut by AI__MAX_HISTORY_MESSAGES is cut between turns, and goes without thinking blocks. A conversation can change model, and provider, at any question: the new one gets the earlier messages, not the other model's reasoning. When a model declines to answer, the person is told, and what it had written is discarded. Server-side fallbacks to another model are not on.

The models

Administration → AI models lists each provider's catalog; one that does not answer says so without hiding the others. Nothing is enabled by default: every message is billed by the provider, so an administrator enables each model people may choose. Embedding, audio and reranker models are listed but cannot be enabled. A model the provider stops offering stays in the list, marked «no longer offered», so it can be disabled. The same name on two providers is two models, and the pickers show each model with its provider. The dbt export uses AI__DEFAULT_MODEL when it is enabled, otherwise the first enabled model. That setting holds a model's name, for instance claude-opus-5-5: with the same name on two providers, the environment's wins, then the provider added first.

Administration, AI models: the catalog of each provider, some models enabled, an embedding model marked not a chat model, one marked price unknown

Administration → AI models: the catalog of each provider; only the enabled models can be picked.

Costs and caps

Under each answer the page shows the tokens and an estimated cost, computed from the model's public list price as published with the AI library: an estimate, not your provider's invoice, with cached input at its own rates. A dash means the model could not be priced, which is not zero.

VariableDefaultCaps
AI__MAX_REQUESTS12model round-trips per question of the data assistant
AI__MAX_FLOW_REQUESTS30the same for the assistants that build: the flow assistant, and the Assistant page for whoever may make changes
AI__MAX_COST_PER_TURN_USD0.5dollars per question
AI__MAX_INPUT_TOKENS_PER_TURN400000input tokens per question
AI__MAX_COST_PER_DAY_USD0 (none)dollars per person per day
AI__MAX_COST_PER_DAY_TOTAL_USD0 (none)dollars for the whole installation per day
AI__MAX_RESULT_ROWS200rows of a data assistant query, to the model and to the chat
AI__MAX_HISTORY_MESSAGES60past messages replayed to the model at each question (metadata-only mode: only those of turns made in it)
AI__DBT_EXPORT_TIMEOUT_SECONDS180seconds for all the AI calls of one dbt export

The daily caps are checked before a question is sent; once reached, the person (or everyone, for the installation's cap) is told to try again the next day. The dbt export's calls count in the same ledger and stop at the same caps. A model with no known price, marked «price unknown» in the panel, is not free for the caps: they count it at $4 in and $20 out per million tokens, whatever it really costs. Set both daily caps wherever people you do not know can sign in. All of these can also be changed in Administration → Settings, without a restart.

The agents' instructions

Administration → AI models → Agent instructions shows the system prompt of each of the seven agents:

AgentPurpose
Data assistantthe chat on the Assistant page
Flow assistantbuilds and changes steps in the flow editor
Script assistantwrites and fixes Python or R in the script editor
Conversation titlesnames every new conversation
dbt export descriptionswrites the descriptions of flows and columns in the dbt project
dbt export SQL translationstranslates the queries the engine does not convert
AI commentswrites the comment on the numbers of a dashboard or a report

An administrator can rewrite a text (up to 20,000 characters) or restore the default. A change applies from the next request, on every gateway replica, and goes to the audit log. Texts the AI already wrote for a version of a flow in a dbt export stay: the new text applies to later versions.

What the administrator writes is only the agent's text. At every request Tabularia adds a context that cannot be edited, shown in the panel with example values: today's date, the engine's SQL dialect and the row cap, the flow or the script being edited, the dialects of a translation, and last, the language: the answer is written in the language of the person's interface (English, Italian, French, German or Spanish), whatever the language of the question, the data or the instructions. The dbt descriptions get no context and are written in English, as the rest of the dbt project, unless the instructions say otherwise.

Conversations

The conversations of the three assistants are saved in Tabularia's database, private to their author, and hold what was sent and returned, rows included. One untouched for ORCHESTRATOR__AI_CHAT_RETENTION_DAYS (90 by default) is deleted; all of a person's go with their account. Observers' conversations are never saved. The flow assistant's conversation reopens with its flow.

Turning it off

  • Entirely: leave AI__BASE_URL or AI__SECRET_KEY empty (on Helm, ai.enabled: false), and add no provider. The Assistant page says «Assistant not configured», the editors show no Assistant tab, and the dbt export offers no AI (it can still reuse the texts kept for a flow version).
  • For now: disable every model in Administration → AI models. The Assistant page says «No model enabled»; nothing is sent.
  • One use: there is no switch per use or per group. Restricting what the data assistant can read is done with folder permissions, as for everything else.
  • Only the data: metadata-only mode keeps the assistants on, with no value of a row going to the model.

Audit

EventWhen
ai.queryevery query of the data assistant and every preview of the flow assistant, with the SQL, the model and its provider, the engine and the rows returned
export.downloada full result downloaded from a conversation, with the SQL
ai.provider_create, ai.provider_update, ai.provider_deletea provider added, changed (which fields, whether the key changed; never the key) or removed
ai.model_enable, ai.model_disablea model enabled or disabled, with its provider
ai.prompt_update, ai.prompt_resetan agent's instructions changed or restored

The dbt export's own audit entry names the AI models that wrote its texts (dbt export).

Example: turning it on

From the panel: Administration → AI models → Add a provider: a name, the type, the API key, Test, Save. Enable a model in the list below it (claude-opus-5-5, for instance).

Docker Compose, in infrastructure/.env:

AI__BASE_URL=https://api.scaleway.ai/v1
AI__SECRET_KEY=<your API key>
AI__DEFAULT_MODEL=gpt-oss-120b
AI__MAX_COST_PER_DAY_USD=2
AI__MAX_COST_PER_DAY_TOTAL_USD=50

Then docker compose up -d again, from infrastructure/: the gateway restarts with the new settings.

Helm, in your values:

ai:
  enabled: true
  baseUrl: https://api.scaleway.ai/v1
  defaultModel: gpt-oss-120b
  maxCostPerDayUsd: 2
  maxCostPerDayTotalUsd: 50
secrets:
  aiSecretKey: ""   # or AI__SECRET_KEY in the Secret named by existingSecret

Then, as an administrator:

  1. Administration → AI models: enable gpt-oss-120b (and any other model people may pick).
  2. Optionally, Agent instructions → Data assistant: add a line such as «Amounts are in euros, net of VAT. The fiscal year starts on 1 April.» and Save.
  3. Open Assistant, accept the notice and ask «Which datasources can I use and what do they contain?».
  4. On the external ClickHouse, give the assistant its own read-only account: the AI user.

Edit this page on GitHub