# AI Agent

> How the bot's AI behaves on each of eighteen entry points — the module's one route, the inheritance model behind it, and where the API stops.

Page: https://sdk.chatfuel.com/docs/modules/ai-agent
Markdown: https://sdk.chatfuel.com/docs/modules/ai-agent.md

## What it is [#what-it-is]

Configuration here is per *source* — a channel plus an entry point, "Instagram post comments"
and not "Instagram" — and there are eighteen of them. Each source carries a **Default** set of
rules, and the sources that can be narrowed also carry **rules** of their own that inherit from
it. Turning the bot's AI off is not a bot-level switch anywhere in this API: it is disabling the
Default on the `All channels` source.

The module is one screen. The rail of eighteen sources sits on the left, the selected source's
page in the middle — its Default rules card and, where the source accepts them, the rules on it
— and a Test panel is always open beside them, pinned to whichever of the two you are reading.

## Installed as [#installed-as]

|             |                                              |
| ----------- | -------------------------------------------- |
| Wizard id   | `automations`                                |
| Install it  | `npx @chatfuel/wizard --modules automations` |
| Selected by | Default — `--yes` installs it                |
| Requires    | Nothing, beyond the implicit `core`          |
| Recommends  | `knowledge-base`, `livechat`, `bookings`     |

## Routes and views [#routes-and-views]

One path. The module declares no view segment at all: everything it can show is one source's
page, and which source that is lives in the query string.

| Path           | What it shows                                                                           |
| -------------- | --------------------------------------------------------------------------------------- |
| `/automations` | The source rail, the selected source's Default rules and its rules, and the Test panel. |

| Parameter    | What it does                                                                                                               |
| ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `scope`      | The selected source, one of the eighteen `FuelyAutomationScope` values. `All` is the default and is left out of the URL.   |
| `automation` | The rule card to expand and scroll to. The Test panel pins to it.                                                          |
| `setting`    | The section to expand on arrival — one of fifteen short keys such as `incomingMessages` or `switchToHuman`. Consumed once. |
| `new`        | Opens the New-rule dialog for that scope.                                                                                  |

An unknown value in any of them falls back to the default in silence, so a hand-edited or stale
link renders the `All channels` source rather than a white screen. The keys an earlier build
wrote — `view`, `test`, `mode`, `platform`, `q`, `filter`, `sort` — are still read past and
deleted on the first navigation.

## The model [#the-model]

Three layers, and only the middle one is yours to create.

There are eighteen **sources**: seventeen real entry points — five platforms crossed with the
entry points that exist for each of them, direct messages, post comments, ad comments, story
replies, `ig.me` and `m.me` links, click-from-ads, click-from-posts — plus `All channels` at the
root, which is not an entry point but the thing the other seventeen inherit from.

Every source is bootstrapped with exactly one **Default** automation. You cannot create one,
rename one or delete one; you edit it or you leave it.

A **rule** is a custom automation that narrows a source — "react only to these posts, only on
these keywords". Rules exist **only in sources that own at least one filter setting**
(`Keywords`, `ListOfPosts`, `ListOfStories`, `ListOfAds`, `RefLinks`); asking for one anywhere
else answers `FuelyAutomationScopeInvalid`. Thirty per source is the ceiling.

Every source carries the same eight settings — incoming messages, when the AI replies, message
delays, catalog images, booking rules, switch to human, follow-ups, collect contact info — and
comment and link sources carry extras on top. Fifteen setting types in all, and inheritance runs
two levels: any automation may follow the `All` base, and a rule may additionally follow its own
source's Default. Rules never inherit from each other. Read the allowed parents off the setting's
own `canInheritFrom` rather than deriving them.

<Callout type="warn">
  The live feed needs one to three seconds after you subscribe before it delivers anything, and
  events emitted in that window are lost — with no error and nothing on screen. Subscribe first,
  load the list second, and refetch on every reconnect. The module's store hook does exactly
  that; anything you build beside it has to as well.
</Callout>

This is **not** the flow builder. Flows are scripted canvas logic and live in their own module;
this is how the AI behaves when a message arrives.

## Configuration [#configuration]

| Variable                     | Notes                                           |
| ---------------------------- | ----------------------------------------------- |
| `CHATFUEL_TOKEN`             | Secret. Server-side only.                       |
| `VITE_CHATFUEL_WORKSPACE_ID` | The workspace you picked during the wizard run. |
| `CHATFUEL_API_BASE`          | Defaults to `https://panel.chatfuel.com`.       |

Every variable the app reads, and which side reads it, is on
[environment variables](/docs/deploy/environments).

## Permissions [#permissions]

| Object | Action | Required for                                                                           |
| ------ | ------ | -------------------------------------------------------------------------------------- |
| `Ai`   | `View` | Reading automations, channels, team, attributes and the knowledge-base facts.          |
| `Ai`   | `Edit` | Every write, the composites (duplicate, copy, every rule on or off) and the test chat. |

A manager has no `Ai: Edit`, which means a manager cannot run the Test panel either — testing
starts a real conversation, and starting one is a write.

## Limits [#limits]

**Rules only where a source can be narrowed.** Direct-message sources and `All channels` own no
filter setting, so they have a Default and nothing else. Thirty rules per source is the cap
(`FuelyAutomationScopeLimitReached`), and a filter a source does not own is refused even on a
rule (`FuelySettingNotAllowedInScope`).

**Every setting write replaces the whole value.** There is no add-one or delete-one mutation,
including for the list-valued settings — keywords, ad ids, post ids, follow-up rules. Read,
modify the array, send it back.

**Undo is a forward write.** Nothing on the server reverts. Undoing a setting change writes the
old value back; undoing a deleted rule re-creates it, which gives it a **new id** — the toast
says so, and any link you saved to the old one is dead.

**Writes are serialised by a per-bot lock.** A concurrent write answers
`FuelyAutomationBeingEdited`. It is retryable, and the module retries it with backoff, but two
tabs editing the same bot will feel it.

**A test is pinned, not routed.** The Test panel starts a real conversation on the production
pipeline, attached to one automation — so a disabled rule still answers, its filters are never
consulted, and the bot never gets to choose between rules. The `All channels` Default cannot be
tested at all (`PreviewResponsesFuelyAutomationScopeNotPreviewable`); open any other source and
its Default can be.

**One setting is read-only here.** `FuelySettingSendEventsToMeta` is ahead of production's
schema, so the module renders it as "Managed in the Chatfuel dashboard" rather than an editor
that would fail.

**The bundled schema cannot catch a malformed update.** `FuelySettingUpdateInput` is `@oneOf`
and the directive is stripped from the snapshot the operation validator reads, so a two-key
input passes the validator and is refused by the router. The module keeps one document per
setting and per direction so a document cannot carry two keys.

<Cards>
  <Card title="AI Agent" href="/modules/ai-agent" description="What this module does, from the product side: the eighteen sources, the rules, the test chat." />

  <Card title="Knowledge Base" href="/docs/modules/knowledge-base" description="What the AI knows about the business. The agent's own name, language and greeting are not there — they moved to this module." />

  <Card title="Inbox" href="/docs/modules/inbox" description="Where a switch-to-human rule sends the conversation." />

  <Card title="Your agent's notes" description="The wizard installs the module's skill as .claude/skills/chatfuel-automations/ for Claude Code, or .agents/skills/chatfuel-automations/ for Codex CLI. Its references/guide.md carries the scope model, the write path and the live-verified traps; references/test-panel.md carries the test chat." />
</Cards>
