Build your agent
Site types & vertical presets
Pitchbar agents adapt to the kind of site they live on. When you set up an agent, the system can auto-detect whether you're running an e-commerce store, a documentation site, a SaaS product, a help center, a marketing site, or an internal knowledge base — and load a vertical preset tuned for that context.
What a preset changes
Each preset bundles four kinds of defaults:
- System prompt fragment — appended to the LLM system prompt at every turn. Sits after retrieval data and before any custom system prompt you write, so your custom instructions always win.
- Starter prompts — the chips visitors see on first open. Filled in for new agents; left alone if you've already curated your own list.
- Launcher label — the call-to-action on the widget's closed orb (e.g. "Browse our shop", "Search docs").
-
Capabilities — a list of rich-UI affordances
the widget reads on init. Phase 3 renderers ship today for
product cards, pricing cards, case-study cards, and the
escalation button (see
resources/widget/src/ui/blocks.tsx); more renderers (code blocks, FAQ accordions, etc.) follow as the capability list grows. Product cards can carry a review score (a★ 4.6 (123)line) when the crawled page declares a Schema.orgaggregateRating— the crawler records it as aRating:fact and the assistant copies it onto the card, never inventing one. On e-commerce agents, "what's the difference between X and Y" questions are answered with a compact comparison table, rendered as a real scrollable table in the widget.
The seven verticals
| Slug | For sites that… | Capabilities (locked in this version) |
|---|---|---|
ecommerce |
Sell products. Pricing, stock, returns, shipping. | product_card, price_inline, shipping_estimate, cart_handoff, order_status, ticket_escalation |
documentation |
Publish technical docs, API references, SDK guides. | code_block, api_reference_card, version_picker, troubleshoot_steps, ticket_escalation |
saas |
Sell software with pricing, features, and signup. | pricing_card, signup_handoff, feature_compare, account_status, ticket_escalation |
help_center |
Run a public support / FAQ surface with article and ticket flows. | ticket_escalation, kb_article_card, sentiment_routing, ticketing |
marketing |
Capture leads, run case studies, do top-of-funnel content. | lead_capture_inline, demo_booking, case_study_card, ticket_escalation |
internal_kb |
Serve an employee wiki, runbooks, or compliance docs. | policy_lookup, team_handoff, auth_aware, ticket_escalation |
generic |
None of the above, or you'll configure everything yourself. | ticket_escalation only — every vertical exposes this so the LLM can always hand off to a human. |
Auto-detection
During onboarding (after you paste your website URL) Pitchbar fetches the homepage, scores a handful of structured signals, and picks the highest-scoring vertical. The signals it weighs:
-
og:typemeta tag (e.g.product,website,article) -
JSON-LD
@typevalues (Schema.org entities likeProduct,SoftwareApplication,FAQPage,TechArticle) -
generatormeta (Shopify, WooCommerce, Docusaurus, Mintlify, Zendesk, WordPress…) -
URL path patterns (
/products,/docs,/help,/api) -
Hostname signals (
app./dashboard.subdomains for SaaS;.local/.internalfor KB) -
Presence of
<article>tags and<pre><code>blocks
Each signal carries a weight; the highest-summing vertical wins. If
no vertical clears a confidence floor of 0.25, the
detector falls back to generic and asks you to pick
manually.
Auto-detection is best-effort. JS-heavy SPAs that ship empty SSR
HTML, or auth-walled hosts, fall back to generic —
you can always pick a vertical manually from the radio cards.
Changing a vertical later
Open /app/agents/{id}/vertical from the agent's nav
tiles. You can:
- Re-detect if your site has changed (e.g. you added a Shopify storefront to a previously content-only site).
- Pick a different vertical via the radio grid. If your customisations would be overwritten, a confirmation dialog explains exactly what gets replaced.
The system prompt fragment is runtime-applied — it isn't
baked into the agent record, so changing the vertical instantly
changes the prompt with no stale text. Capabilities are runtime too:
the widget receives the live list on every /init call.
Starter prompts and launcher label are merged into the agent record
on apply, so you can edit them in Customize without losing your work
next time you re-apply the same vertical.
Overriding capabilities
Each agent has an optional vertical_overrides JSON
column. Set vertical_overrides.capabilities = [...] to
replace the preset's capability list with your own. The widget reads
the override; the LLM still sees the preset's system fragment so
your overrides don't accidentally weaken the prompt contract.
Multi-tenancy & security
Both endpoints (POST /app/agents/{agent}/vertical/detect
and POST /app/agents/{agent}/vertical/apply) are gated
by AgentPolicy::update — only members of the agent's
workspace can call them. Cross-workspace access returns 403.
vertical_signals caches the most recent detection on
the agent row so the admin UI can show "auto-detected on …"
without re-fetching.
What's next
Phase 1 ships the data model, detection, presets, admin UX, and
exposes capabilities to the widget. Phase 2 (tool /
function calling) is partially shipped — the ToolRegistry
in app/Services/Tools/ToolRegistry.php is wired, and
the first tool (EscalateToHumanTool) ships gated to
the ticket_escalation capability. Vertical-specific
tools (product_lookup for e-commerce, etc.) follow as
integrations land. Phase 3 (rich-message renderers in the widget)
is partially shipped — resources/widget/src/ui/blocks.tsx
renders product, pricing, case-study, and escalation blocks the
LLM emits via inline-XML markers; additional renderers follow as
we extend the capability list.
Card link guard
The model fills each card's url attribute from retrieved
context, and when the real page URL wasn't retrieved, small models
fall back to the site's bare homepage — so the card's "View" link
would land visitors on the homepage instead of the product page.
ProductCardUrlResolver
(app/Services/Widget/ProductCardUrlResolver.php) guards
every product, pricing, and case-study card post-stream: a URL that
matches an indexed page is swapped for the stored canonical URL
(normalising www/apex and trailing-slash drift), a bare
homepage or unknown URL is re-resolved by matching the card title
against indexed page titles and URL slugs, and when nothing matches
the link is dropped — the widget then renders the card without a
"View" button rather than linking somewhere wrong. Runs in both the
visitor stream and the Playground, reads only the agent's own
documents, and never runs before the first streamed token.