Cookbook
Agents & skills · for AI agents

Configure a page playbook (page-aware chat opener)

Give the agent a per-page briefing — background, an opening line and suggested questions — chosen automatically from the visitor's URL, over MCP.

MCP tools:list_page_contextsupsert_page_contextresolve_page_contextpage_context_stats

Principle — the opener is the only sentence guaranteed to be read. A generic "How can I help?" converts a page visit into nothing. A playbook lets the same agent open differently on each page, already knowing where the visitor is. More in Page playbooks.

A page playbook is a small briefing attached to a URL pattern. It has three parts:

  • context — private background for the agent, not shown to the visitor (who lands on this page, what they're deciding, what they usually worry about). Write background, not facts: prices, quotas and policy belong in a knowledge base, which outranks it.
  • greeting — the opening line the visitor actually sees.
  • questions — up to four suggested questions, so a visitor who hasn't formed one can just pick.

The right playbook is chosen from the URL: resolution order is explicit key → url_pattern → default. A single default catches every unmatched page, so nothing ever falls back to a blank box.

1. See what's already there

list_page_contexts()   # existing playbooks: match rules, greeting mode, position, which is default

2. Create or replace one

upsert_page_context(
  key="pricing",
  label="Pricing page",
  url_pattern="*/pricing",           # glob, path-only; ignores query string and trailing slash
  context="Visitors here are comparing plans and worrying about overage. "
          "They are usually the person who will sign off on the cost. "
          "Do not quote custom pricing in chat.",
  greeting="You're looking at our plans — want me to work out where overage would start for your volume?",
  questions=["What's included in the free plan?", "How is overage billed?", "Can I change plans later?"],
  greeting_mode="generated",         # generate opener + questions in the visitor's language (recommended)
  is_default=False,
)

greeting_mode="generated" writes the opener and questions per visitor language on the fly — so a Spanish visitor gets a Spanish greeting without you authoring five versions. Use "static" only when you want your exact greeting/questions verbatim.

3. Verify the match — always

resolve_page_context(url="https://acme.com/pricing?ref=x")   # → which playbook this URL hits, and how

Globs are easy to get subtly wrong (a missing *, one path level too many). A mismatch has no error message — the visitor just silently gets the default playbook. So after writing any url_pattern, resolve a real URL and confirm matched_by is url_pattern, not default.

4. Set a catch-all default

upsert_page_context(
  key="default",
  label="Everywhere else",
  context="General visitor to the site; intent unknown. Ask what brought them in before assuming.",
  greeting_mode="generated",
  is_default=True,                    # at most one default per tenant; setting this unsets any other
)

upsert_page_context is a full replace, not a patch: fields you omit fall back to defaults rather than keeping their old value. To change one field, list_page_contexts() first, merge, then upsert.

Once playbooks have been live for a while, page_context_stats() shows which ones get opened and which suggested questions get clicked — so you tune copy from data, not guesses.

Report back. Give the user the console link to review and edit these — https://console.agent4.io/#/page-contexts — and confirm each url_pattern resolves the way they expect (step 3). The chat widget needs no code change for a static site; single-page apps that have no distinct URL per view can name a playbook by its key instead.