--- title: "The AI Assistant" description: "The panel inside the editor builds, saves and runs the open workflow by calling the editor's tools — reads run at once, changes wait for a click." source: https://flowdrop.io/docs/editor/ai-assistant site: FlowDrop documentation --- # The AI Assistant The **AI Assistant** is the chat panel in the editor's bottom bar, next to the command console. Since `@flowdrop/flowdrop` 2.8.0 it is a tool-calling agent: you describe what you want, the model on the server calls the editor's tools, the editor runs them in your browser, and the loop continues until the assistant answers in text. It is the same tool set a [browser agent](/editor/browser-agents) gets through WebMCP — the two share one execution path — with one difference: it works for every user of the editor, in every browser, with no flag and no MCP client. ## What a turn looks like One message is one *turn*. A typical build request runs like this: 1. **Reads first.** `search_types` finds candidate node types; `describe_type` answers a type's ports, config keys, allowed values and confirmation policy before it is used. Reads run at once and show up as `Read: describe_type http_request` lines in the transcript. 2. **One `batch` per change.** Adds, connects and `set_config`s travel together. The editor opens its approval dialog — "The assistant wants to change *Newsletter* — 4 changes: adds 2 nodes, connects 1 edge, sets 1 config key" — and nothing touches the workflow until you click **Apply**. One batch is one undo step. The transcript keeps the dialog's summary as `Applied: 4 changes — …`. 3. **`save`, then `run`.** Both ask, every time; neither is covered by "don't ask again". `run_status` polls the run and is a read. The dialog is the editor's one approval gate, shared with [browser agents](/editor/browser-agents) when WebMCP is on: ticking "don't ask again for edits" covers both, and two dialogs never stack. Only the title says who is asking. 4. **The assistant answers in text** — what it changed, how data flows, what is left. Rejecting the dialog is not an error. `REJECTED` goes back to the model as the tool's result, and the assistant explains what it proposed and asks what you would prefer, without retrying. A run that pauses for a person (a node whose confirmation policy is `ask`) is reported as `PENDING` with the node it waits on; you approve it in the editor and tell the assistant to check again. No tool answers an interrupt. The transcript is the memory: the server keeps the user turns, the assistant turns with their tool calls, and the tool results, so the next message continues the conversation and a round that was cut off (a closed tab mid-dialog) is healed rather than replayed. ## Rounds and bounds A *round* is one reasoning step: the model asks for tool calls, the editor runs them, the results go back. The server bounds rounds per message (**8** by default in the FlowDrop Drupal module, `max_tool_rounds`); on the bound the model gets no tools and must answer in text, saying how to continue. The panel keeps a backstop of its own. ## Settings In the editor's **Settings → Behavior**: | Setting | Default | What it does | |---|---|---| | **AI Assistant Mode** (`chatMode`) | `tools` | `tools` is the loop described here. `dsl` is the legacy text mode: one reply holding a command block you apply by hand. Deprecated; removed one minor after tools mode ships in the Drupal module. | | **AI Assistant Layout Changes** (`chatAllowLayoutChanges`) | on | Off, `auto_layout` and `beautify_layout` are skipped (not failed) in both modes. | | **AI Assistant Auto-retry** (`chatAutoRetry`) | on | Text mode only. In tools mode the tool result itself tells the model what went wrong, in the same turn. | The panel enters tools mode only when the backend declares the tool-results endpoint (`endpoints.chat.toolResults`). Against an older backend the first reply arrives without a turn id; the panel says so once and stays in the text mode for the session. ## What the host provides The panel needs three things from the host, all of which the Drupal module supplies: - **The endpoints.** `chat.sendMessage` takes the message together with the tool catalogue (`tools: [{name, description, input_schema, readOnly}]`) and answers either `{turnId, toolCalls, done: false}` or `{turnId, content, done: true}`; `chat.toolResults` (`POST /workflows/{id}/chat/turns/{turnId}/tool-results`, body `{results: [{toolCallId, content, isError?}]}`) continues a turn. The library owns the catalogue — the server holds no copy of the tool schemas. - **The host hooks.** `save`, `run` and `run_status` exist when the mount has `onSave`, `onRun` and `onRunStatus`. `mountFlowDropApp` takes them as the `host` option and publishes them on `instance.host`; `onSave` defaults to the mount's own Save. Hooks passed inside the `webmcp` option are picked up too, so a host that already wires browser agents need not repeat them. See [Host hooks and the result envelope](/editor/browser-agents#host-hooks-and-the-result-envelope). - **A reasoner.** The server side calls a tool-capable model; in the Drupal module this is the same `flowdrop.chat_reasoner` service the Reason node uses, backed by `drupal/ai` function calling. ```ts const app = await mountFlowDropApp(el, { endpointConfig, host: { onRun: (inputs) => launcher.run(workflowId, inputs), onRunStatus: (runId) => launcher.status(runId) } }); ``` ## The Drupal module *Configuration → FlowDrop → Chat Settings* (`/admin/flowdrop/config/chat`): | Setting | Default | | |---|---|---| | **Chat mode** | Tools | Tools, or Text (legacy). In text mode the endpoint answers without a turn id and the panel follows. | | **Max tool rounds** | 8 | Reasoning rounds per user message. | | **Agent prompt template** | built-in | The system prompt of a tools-mode turn; `{{WORKFLOW_SUMMARY}}` is replaced by a compact description of the open workflow. The built-in prompt teaches the call order and the rules the tool schemas cannot carry — it carries no node-type catalogue, `describe_type` does that on demand. | | **LLM Provider** | system default | The model the reasoner uses, `provider:model`. | | **Node type index threshold** | 30 | Text mode only: above this many types the DSL prompt lists a compact index instead of every schema. | The processing-mode group (built-in pipeline or a FlowDrop workflow) applies to the text mode only. Access is the editor's: both doors require `use flowdrop_chat` and `update` access on the workflow, and continuations are flood-counted on their own bucket so a long build does not eat into the message limit. Tools are dispatched by origin: the catalogue the model sees is the union of the panel's tools and any *server tools* the site registers (services tagged `flowdrop_chat.server_tool`, exposed under `site_…`), which run on the server inside a round without a trip to the browser. None ship yet; the seam is for site-side reads such as a workflow's recent runs. ## Legacy text mode Before 2.8.0 the assistant was a single-shot text generator: the whole node-type catalogue in every prompt, one reply with a ```` ```flowdrop ```` block, a preview and an **Apply** click. It is still available as `chatMode: 'dsl'` (and *Chat mode → Text* in Drupal) for one minor release. What it lacked is what the loop adds: the model can look before it acts, ask in the middle, save, run and watch, and it pays for a type's schema only when it uses it.