Code mode
The escape hatch for whatever a site map can't say. A page that declares its own actions never fetches a map at all — code mode takes precedence, entirely, on that page.
Declare actions
<script>
window.GerryConfig = {
key: 'pk_…',
actions: {
filter_category: {
description: 'Narrows the list to one category.',
parameters: { category: { type: 'string', description: 'Category name' } },
required: ['category'],
handler: ({ category }) => { applyCategory(category); return `${count()} products left.`; },
},
},
context: () => `${count()} products are listed.`,
};
</script>
<script src="https://katman-widget.vercel.app/gerry.js" defer></script>
Load order doesn't matter: if GerryConfig exists before the widget script runs, it starts itself immediately. Otherwise, call Gerry.init({ … }) on the gerry:ready event — the demo page does it this way. The older Katman, KatmanConfig, katman:ready and katman.js names still work as aliases for all of this.
Options
actions | What the assistant may do. Names lowercase with underscores; descriptions one or two sentences; parameters string | number | boolean. Up to 24 actions, 8 parameters each, 600 characters of description — bounds the product enforces, not the voice provider's (see Security & privacy, rule 8). |
|---|---|
handler | Sync or async. Returns a string (spoken as-is), { summary, data } (summary is spoken, data goes to the model for follow-up questions), nothing at all ("Done."), or throws ("I couldn't do that"). Summary capped at 600 characters, data at 12 KB. |
context | What's on screen right now — called by the model's built-in page_context tool. Without it, the widget reads only the page's title, its path, and any element you marked with data-katman-context; nothing else, ever (SECURITY.md rule 5). |
onState | connecting | live | error | stopped, for your own UI to react to. |
position | bottom-right (default) or bottom-left. Superseded by appearance.position when both are given. |
name | The name shown on the control before a session opens (default "Gerry"); the tenant's assistant name replaces it once connected. Superseded by appearance.label. |
appearance | This page's own look, any subset of the tenant's appearance object (see What Gerry shows on the page) — wins over the tenant's, exactly as language does. |
language | The visitor's language (en | tr | de), explicit and winning over <html lang> and the browser's own language list. Sent with the session request. |
debug | Logs the call's life to the console. |
Headless: drawing your own UI
With ui: false there's no orb and no captions; the site draws its own and drives the call through the object Gerry.init returns. Audio still plays normally.
const gerry = Gerry.init({
key: 'pk_…',
ui: false,
onState: (state) => { /* connecting | live | error | stopped */ },
onCaption: (text, from) => { /* from: 'user' | 'assistant' */ },
onSpeaking: (source, level) => { /* source: 'user' | 'assistant', level 0..1 */ },
});
gerry.start(); // also stop(), toggle(), state, destroy()
Gerry.init always returns this same object, whether or not ui is on: start(), stop(), toggle(), the current state, and destroy(), which removes the badge entirely.
What the server does with a handler: nothing
The server never runs an action itself, in code mode or in map mode. A tool call becomes a command for the page that declared it, and that page's own code is what runs it — see Security & privacy, rule 1. An action name the page didn't declare gets "there is no such tool" back, every time.
No-code is still map mode
<script src="…/gerry.js" data-key="pk_…" defer> with no GerryConfig at all is map mode — the tenant's site map if it has one, page_context alone if it doesn't. Declaring actions is what opts a page out of the map fetch entirely; the two modes are never mixed on the same page.
Reloads
If a handler reloads the page, the conversation tries to continue on the new page with the same token; audio may need one more click on the control to resume. The reliable path stays an in-page handler that never navigates.
Questions: hello@heygerry.io. These pages describe what is built today; nothing here is a promise about what is not.