Build your agent
AI employees and their tabs
An AI employee is the embeddable unit — persona, instructions,
knowledge, theme, rules — that runs on a customer's site. The app
calls it an AI employee (Dutch:
AI-medewerker); the API, the URLs (/app/agents)
and older pages of this documentation still say agent, and
both words mean the same thing. This page covers creating,
configuring, publishing, and rolling back AI employees.
Create an agent
From the customer app: /app/agents → New AI
employee. This creates one with your workspace's widget defaults
and opens the setup wizard for it, which asks for the website first (see
Quickstart). The plan's AI
employee limit is checked before anything is created. Name, language,
instructions, the confidence threshold, strict mode, the fallback message
and the booking link are all set afterwards on the AI employee's own
pages. The old create form is gone; its address
(/app/agents/create) opens the AI employees list.
When you enter your website at signup, the first AI employee is created for you, named after your domain. You can rename or delete it freely.
The eight tabs
Every page of an AI employee sits under its name, its checked status (see below), a Test it button that opens the real widget in the corner, and Publish while it is still a draft. Below that are eight tabs, always visible; on a phone they become one dropdown. Viewers see only Overview and Knowledge. With exactly one AI employee in the workspace, the menu item opens it directly instead of a list of one.
| Tab | What is on it |
|---|---|
| Overview | What needs attention, built like the list on Home but for this AI employee only and without the plan lines or a "not published" line; the setup checklist until it is complete; the main facts at a glance; Re-publish and Delete. |
| Knowledge | Sources (what could not be read comes first, with Try again), What it knows, Fixed answers, Unanswered questions and Visitor feedback. |
| Personality | Name and role, language, greeting and opening message, instructions, starter questions (with Suggest questions that fit the page) and waiting messages. The live preview is beside it. |
| Behaviour | How it answers, Asking questions first (Advisor Mode), Buttons in the chat (quick replies, Book a call and CTAs), When the chat opens by itself (auto-open, staged invitation and triggers), Handing over to a person, and Guided conversations (the workflows that run for it). |
| Lead capture | When it asks, the form, and who is told about a new lead. |
| Appearance | Colours, the chat button, position and layout, and the inline block's look, with the live preview beside it. |
| Website | All three install codes (script, Tag Manager, inline block), the websites where it may appear, and the pages where it appears. |
| Advanced | Segments, Type of website, Experiments, Nightly test questions, Tracking events and Earlier versions, each with a one-line description; the Playground only for platform staff. |
Each page saves only its own settings, so saving the colours never
touches the greeting. Conversations and leads of one AI employee are
the workspace lists filtered to it. The old addresses keep working:
/customize opens Appearance, /settings opens
Personality, and /conversations and /leads of
an AI employee open the filtered lists.
The Overview's setup checklist has three steps: Add your website (a source has been read), Try it yourself (a conversation with the live preview, which never counts as a visitor) and Put it on your website (ticked only once the chat has been seen on your website, not when the AI employee was published). It is the same checklist as on Home, and it disappears from both once complete.
Online, Ready, Blocked, Draft
Every AI employee shows one of four states, checked against what visitors experienced rather than a setting:
| State | Meaning | What to do |
|---|---|---|
| Online | Seen on an allowed website in the last 30 days, with the host and the time of the last visit. | Nothing. |
| Ready | Published and allowed, but not seen on your website yet (or not in the last 30 days). | Paste the install code into your website, or check that it is still there. |
| Blocked | Published, but no website is on its allowed list, so the widget refuses every site. | Add your website under Website › Websites where it may appear. |
| Draft | Not published. | Publish it (it also publishes itself when its first page has been read). |
"Seen" means a visitor session started by the widget on a page of a
website that is allowed now, matched the way the widget matches
(www. and the bare domain are the same website, other
subdomains are not). Chats in the dashboard preview never count. The
state is read from existing data, cached for a minute, and replaces the
old Live label, which only meant "published".
The agent record
Every agent has these editable fields:
| Field | What it does |
|---|---|
name | Display name in the dashboard. Not shown to visitors. |
price_display | Where prices may appear (cards #508, #512), stored in vertical_overrides. The four modes are the cells of a two-by-two — price in the reply text, price on the product card. See Price display for the full behavior and how to make the restricted modes airtight. |
language_default | The default language (Personality › Language). One of en, nl, es, fr, de, pt, ja, ar or zh; nothing else is accepted. The reply language comes from the visitor's browser (Accept-Language), with this as the fallback when that gives no match, and the AI is told to reply in the language the visitor writes in. The widget's own texts follow the page's language first, then this setting, then the browser. How much of the interface is translated differs per language. On Dutch agents the stream also normalizes the small-model habit of opening a reply with an English discourse marker: a leading No,/Yes, is rewritten to Nee,/Ja, before the first token reaches the visitor (real Dutch openings like "Nog" or "Nou" are never touched). |
persona | JSON: { name, tone }. Tone goes into the system prompt verbatim. |
theme | Widget colors, radius, position, launcher label. |
system_prompt | Optional override. Appended to the built-in prompt — doesn't replace the safety / RAG instructions. |
guardrails | JSON: { avoid: [topics], max_chars }. |
starter_prompts | Up to 6 chips shown above the input on first open. 80 chars each. |
confidence_threshold | 0–1. Below this score (after rerank) the agent says "I don't know" instead of guessing. |
allowed_origins | Strict list of scheme://host origins where the widget may load. |
restricted_paths | The path pattern list (globs, * wildcard) that path_mode reads. See Allowed origins. |
path_mode | Where the agent appears within an allowed origin (card #613): all (every page), except (every page but the listed patterns) or only (the listed patterns and nowhere else). Lets two specialised agents share one domain. |
auto_index_visited_pages | If on, pages visitors land on get queued for crawl + index. |
lead_prompt_strategy | When the chat offers the lead form (Lead capture tab). One of engagement (default: on an intent keyword such as pricing or demo, or once the visitor has sent 3 messages), first_turn (on the visitor's first message), keyword_only (only on an intent keyword) or never. |
wp_integration (JSON, encrypted) | WordPress / WooCommerce companion-plugin context. Stores the shopper-signing secret and any per-store config the LLM tools (e.g. lookup_order) need. Populated automatically when the WordPress plugin connects via API token; not edited by hand. |
Confidence threshold
The retriever scores every chunk against the visitor's question. Anything
below confidence_threshold is dropped. If fewer than two
chunks survive, the answer is flagged low_confidence and the
agent answers honestly that it doesn't know — and the system queues a
"knowledge gap" entry you can review.
Defaults are tuned per provider:
- Cloudflare bge-base-en-v1.5 embeddings — default
0.5. Cosine scores run lower than OpenAI's, so the bar is lower. - OpenAI text-embedding-3-small — default
0.78. Set this on signup if you switch providers.
Draft → Published
A draft AI employee does not start on any website. Publishing lets the widget start (it also happens by itself when the first source has been read). After that, every save is live for visitors straight away: the widget reads the AI employee's current settings.
Each publish, and each Re-publish on the Overview, also keeps a copy of the name, language, persona, look, allowed websites, instructions, answer limits and how sure it must be. Under Advanced › Earlier versions you can restore one of those copies; it overwrites those settings with the earlier values. Knowledge, conversations and leads are never touched, and the copies themselves are kept.
Embed the agent
The Website tab shows a one-line install snippet with your
data-agent-id baked in. The widget URL includes a
cache-busting hash that mutates whenever the bundle is rebuilt, so
customers don't get stuck on stale versions. See
Install snippet for details.
Delete an agent
Two ways to remove an agent:
- From the AI employees list (
/app/agents): click the trash icon next to the gear in the Settings column of its row. Confirm in the prompt and the agent is gone. - From the AI employee's Overview (
/app/agents/{id}): click Delete at the foot of the page, then Delete again in the warning that appears.
Deletion is a hard delete. Buyer report 2026-05-19:
soft-delete left phantom playground conversations + child DB rows
visible after the customer "deleted" their agent, so the destroy
path now calls forceDelete(). Every child row cascades
via FK at the database layer: conversations,
messages, leads, sources,
documents, chunks, experiments,
visitor_page_views, etc. The widget embed snippet for
the agent stops resolving immediately.
The vector store (Cloudflare Vectorize / Qdrant) is not on the same
DB connection, so DB cascade can't reach it. Destroy queues
PurgeAgentVectorsJob just before
forceDelete(): the job calls
QdrantClient::deleteByFilter with
['agent_id' => $id] against the
services.vector_collection index. It's idempotent and
swallows transport errors so a temporary Vectorize outage doesn't
block the user-facing delete. php artisan pitchbar:audit-vectors
compares the chunks of every agent that still exists with the vector
index and reports missing and orphan vectors. It only checks agents
that still exist, so it does not find the vectors of a deleted agent
whose purge failed.
Because the delete is permanent, there's no
withTrashed() restore path. The platform-admin
destroy at /admin/agents/{id} uses the same semantics
(audit 2026-05-30) — it previously left soft-deleted rows that the
customer couldn't see, defeating the orphan-cleanup intent the
super_admin action was added for.
Authorization: requires owner, admin, or editor role on the workspace. Viewers and members of other workspaces hit a 403.
Bulk delete agents
Select multiple rows on the Agents index page (/app/agents)
via the checkbox column. The header checkbox toggles all rows on
the current page; shift-click a row checkbox to range-select between
the last clicked row and the current one. Selection persists across
pages until you click Clear.
A sticky bar at the bottom of the page surfaces the count and a
Delete action. Confirm in the prompt — every
selected agent is hard-deleted (same semantics as single-agent
destroy: DB cascade reaches child rows;
PurgeAgentVectorsJob queued per agent to clean
Vectorize). Cross-workspace ids are silently dropped from the
result (the per-row policy gate rejects them without leaking
existence).
The same useBulkSelection hook + BulkActionsBar
component now power bulk delete on every index page across the app:
/app/agents— bulk delete agents (this page)./app/workflows— bulk delete workflows./app/conversations— bulk delete conversations./app/leads— bulk delete captured leads./admin/agents— super_admin bulk delete agents across workspaces./admin/leads— super_admin bulk delete leads./admin/conversations— super_admin bulk delete conversations./admin/workspaces— super_admin bulk soft-delete workspaces (cannot delete the workspace you're currently signed into)./admin/users— super_admin bulk soft-delete users (skips self, last super_admin, and workspace owners).
Selection model is identical on every page: header tri-state checkbox,
shift-click range select on row checkboxes, persistent selection across
pagination, sticky bar with count + Delete + Clear. Each bulk endpoint
accepts { ids: string[] } (max 100 per request) and runs
every id through its resource's policy gate.
Multiple agents per workspace
You can run as many agents as your plan allows — one for marketing, one for the help center, one for the in-app upsell flow, etc. New AI employee checks the plan's limit first and refuses with a message when it is reached. Each has its own knowledge base, persona, and embed snippet. Conversations and leads stay scoped to the agent that handled them.