Agent & portals
agent:
name: Teranga # optional: Convoy never invents a name
persona: "a warm host who helps put the meal together"
tone: friendly # friendly | professional | playful
rules:
- "Never invent a dish: only what the menu returns."
emoji: false
model: gemini-2.5-flash # the agent's model
portals:
web: # the tenant's site, a portal of the agent
widget:
origins: [https://teranga.example.sn] # the only sites where the widget shows
theme: {primary: "#C8412B", secondary: "#F6EFE4", font: manrope}
brand_label: Teranga # and the labels, the avatar, the suggested prompts
site: {...} # the demo site's copy
pitch: {...} # the presentation page
mcp: {...} # the MCP server's name and instructions
| key | effect |
|---|---|
agent.persona, tone, emoji | how the agent introduces itself, on every door. persona and tone are required |
agent.name | the agent's name, if the tenant gives it one; no surface shows it today |
agent.model | the model the agent runs on; gemini-2.5-flash by default |
agent.rules | instructions copied as they are, on every door: the widget as well as Claude or ChatGPT. Write them in the station's language, and name the station's skills, not a tool it does not expose. |
agent.portals.web.widget.origins | the only sites where the widget can show, as origins (https://host[:port]). A value that is not an origin (a bare host, a path, *) is refused at load time. Without it, the widget shows on any site |
agent.portals.web.widget.theme | the colours (primary, secondary, accent_gradient) and the typeface (font: inter, jakarta, manrope, geist, dmsans; manrope by default). The colours go to the widget, the PWA and the MCP frames; the typeface to the widget only (the frames keep the host's). A colour that is not #rgb or #rrggbb, a typeface outside the list: refused at load |
agent.portals.web.widget (the rest) | the widget's words: brand_label, avatar_initial, avatar_url, fallback_title, empty_state_text, suggested_prompts; labels replaces Convoy texts |
agent.portals.web.site, pitch | the copy of the demo site; pitch has only meeting_url (read by the MCP frames) and headline, headline_accent (the site's title when site gives none) |
mcp | the MCP server's name; collection_name_override chooses the catalogue collection |
An item's link to its page on the tenant's site is not a key of the portal: it is the role: link
field of the skill that presents the item (Skills).
Today, the agent has three portals: the widget on the tenant's site, the PWA, and the Chrome extension. The others (Teams, Slack, WhatsApp) and proof of who is speaking come with the target (Agent & portals).
Instructions are not guards
A rule in agent.rules guides the agent; it does not prevent anything. Everything that must
be guaranteed — a required address, a confirmation before ordering — is written in a select
guard or in the submit guard, which Core applies whatever the model says.