Appearance
Function: chat()
ts
function chat(ctx: Context, options?: ChatOptions): RenderSession;Defined in: packages/sdk/src/renderer/templates/chat.ts:196
Interactive chat template — a full, block-only conversational surface.
One long-lived render: a Chat block renders the transcript, a PromptInput + Suggestion chips (bound to the same messagesKey via pushTo) seed user turns, and replies stream in. By default the reply comes from Chrome's on-device Gemini Nano (model: chromeAI()); pass model: aiSdk({...}) to stream from a cloud model in the skill's Node context. Per-turn rich blocks come from model-chosen tools or the deterministic augment callback. Voice, attachments, per-message actions, and in-chat confirmations are built in — none resolve the render; only Dismiss does.
Fire-and-forget: returns a RenderSession the caller can await (resolves when Dismiss is pressed).
Parameters
| Parameter | Type | Description |
|---|---|---|
ctx | Context | Render context. |
options | ChatOptions | Chat configuration. |
Returns
Example
ts
import {chat, nano, tool, reply, data} from '@matterway/sdk/UI';
import {z} from 'zod';
// On-device (default — `model: nano()`):
await chat(ctx, {title: 'Assistant', suggestions: ['Summarize this']});
// With tools. The return type names who writes the reply:
// reply(...) → skill-authored, verbatim; data(...) → AI phrases it.
await chat(ctx, {
model: nano(),
tools: {
weather: tool({
description: 'Current weather for a city',
input: z.object({city: z.string()}),
run: async ({city}) => data(await getWeather(city)), // AI phrases it
}),
// A tool that ALWAYS asks first — `confirm` hard-gates `run`:
deleteFile: tool({
description: 'Delete the file',
input: z.object({path: z.string()}),
confirm: ({path}) => `Delete ${path}?`, // present ⇒ gate
run: async ({path}) => reply(`Deleted ${path}.`), // only after approval
}),
},
});