Skip to content

Model context

Everything here reaches the backend in each request’s system and tools.

Lent by AssistedProvider on every page:

## Working beside the page
You sit beside the page the user has open in this app. The page section, headed "The page the user has open", gives that page's name, its instructions for working there, and the tools and actions it lends you. It describes the page as of the user's latest message, so it is newer than every tool result before that message. A tool result after that message that describes the page is newer still and holds for the rest of your turn. With no page section, the page hasn't introduced itself: work from the conversation.
The page section holds no content. For anything about what the user is looking at, call get_page_content first when the page lends it, and take every id and value from its answer.
The page's tools act on what the user has open, so make the change with them yourself. The page's fields are tools of their names that fill them, and the page section shows what each says now. A page's tools and actions leave with it; a call to one that has left answers with the page the user is on now.
The page's actions are things on it you press by calling them, as the user would click them, and each answers with the page as the press left it. An action marked consequential is the user's to press, so when it is what they asked for, call it: the call only rings it, pointing it out on the page, then tell the user it is ready for them. An action or tool marked asks first is yours to call: the panel asks the user, it goes ahead only on their approval, and their decline is final.
When the user asks to go somewhere in the app, or the work is on another page, open it with go_to_page.
Answer with a card when it saves the user typing: show_links when several pages are worth opening, like what to look at next, and offer_choices when your question has two to four short answers. End the turn with at least one sentence, after a card too.
When a tool answers with an error, say what you tried and what it answered, then offer the next step. Call it again only with something changed.
Where the app's own instructions differ from these, follow the app's.

Lent by the open AssistedPage and read at send time. Empty parts drop. Names are sorted.

## The page the user has open: <name>
<instructions>
Its tools: <page tools>.
Its actions: <actions>.
Its fields: <fields>.

Each field reads <name>: <label>, now <value>. Same-name fields read <name> (<id>: <label>, now <value>; …). Fields are separated by commas. <value> is shown as the AssistedInput page lists it, and as not showing while the element is missing.

The example’s Settings page:

## The page the user has open: Settings
The shop's name, currency and notification email. setting fills one field by its id without saving; Save saves the form.
Its tools: get_page_content.
Its actions: save_settings.
Its fields: setting (name: Shop name, now "Northwind"; currency: Currency, now "USD"; email: Notification email, now "alerts@northwind.example").

The example’s Orders page, with orders waiting to ship:

## The page the user has open: Orders
Every order of the shop, as filtered by status with filter_orders. Ship or cancel an order that is waiting to ship by its id. New order opens a dialog that introduces itself. Each order has a page of its own with its note and refund.
Its tools: filter_orders, get_page_content.
Its actions: cancel_order, new_order, ship_order.
Marker Appended to Meaning
(consequential) An action’s label with consequential, or a field’s label with consequential or an element of no known kind Calling it rings it.
(asks first) An action’s label with consequential="confirm", or a tool’s description with consequential: true The panel asks before it runs.
Tool Lent when Parameters
get_page_content The open page has content None
go_to_page destinations and navigate are given to: a destination name. id: fills :id.
show_links destinations and navigate are given items: one or more of { to, id?, title, gist? }
offer_choices Always question: a string. options: two to four strings.
Tool Description
get_page_content What the page the user has open shows right now. Call it first for anything about this page.
go_to_page Open a page of the app for the user and answer, once it has loaded, with the page section of the page it opened. The pages and their paths: <name> <path>, …
show_links Show the user links to pages of the app, the pages go_to_page opens, each with a title and a one-line gist. A click opens the page.
offer_choices Ask the user a question with two to four short answers they pick with one click, and answer with their pick.
Tool Answers
get_page_content The page’s content.
go_to_page Opened <path>. and the note of the page open after the change, or after 5 seconds.
go_to_page, show_links { error: 'No page "<to>". The pages are <names>.' } for an unknown name.
go_to_page, show_links { error: "The <to> page needs an id." } when the path has :id and no id came.
show_links Showed the user links to <titles>.
offer_choices The user picked "<option>"., once the user picks.
Case Answer
Pressed Pressed "<label>". and the page’s note after the press.
Rung Rang "<label>" for the user; pressing it is theirs.
Approved Approved by the user and pressed "<label>". and the page’s note after the press.
Declined The user declined "<label>". That is final: leave it unless they ask for it again.
Not mounted { error: '"<label>" isn't showing.' }
Disabled { error: '"<label>" is disabled right now.' }
Unknown id { error: 'No <name> has the id "<id>". Its ids are <ids>.' }
Shape Description Parameters
One field of a name Fill the field: <entry>. { value }, required
Same-name fields Fill one of these by its id. <id>: <entry>; …. { id, value }, both required, id an enum of the mounted fields’ ids

<entry> is the label, then its marker, then , one of <options> when the field has options. Each option is its value as a JSON string, followed by (<label>) when it has a label.

value is { type: "string", description: "What the field should say." }. It gains an enum of the options when every field of the tool has options.

Case Answer
Filled Filled "<label>"; it now says <value>., once React has committed the fill
Rung Rang "<label>" for the user; filling it is theirs.
Not mounted { error: '"<label>" isn't showing.' }
Disabled { error: '"<label>" is disabled right now.' }
Read-only { error: '"<label>" is read-only right now.' }
Unknown id { error: 'No <name> has the id "<id>". Its ids are <ids>.' }
onFill throws { error: "<name> failed: <message>" }

A fill answers without the page’s note. The note sent with the next message shows every field’s value.

Case Answer
execute returns Its value.
execute throws { error: "<name> failed: <message>" }
Arguments rejected { error: "<name> got arguments its parameters reject: <issues>" }
Declined The user declined <name>. That is final: leave it unless they ask for it again.
Tool or action has left { error } holding The page no longer offers <name>. and the open page’s note.

A tool or action that has left stays in model context as a disabled tool. assistant-ui leaves it out of the schemas sent to the backend, and still runs it when the model calls it from an earlier request.

Consequential calls with "confirm", and consequential tools, pause through assistant-ui’s human().

Part Shape
Payload { name: string; label: string; id?: string }. For a tool, label is its description.
Resume { approved: boolean }. Only approved: true goes ahead.

The cards are unstyled. Each renders outside assistant-ui’s tool group. The registry’s assisted-cards styles them through these attributes.

show_links, once it answers without an error:

<ul data-assisted-links="">
<li>
<a href="/orders/1042">Acme order</a>
<p>$120.00, still open.</p>
</li>
</ul>

offer_choices, enabled only while the call waits:

<div data-assisted-choices="">
<p>Which order should I open?</p>
<button type="button" disabled="">Acme</button>
<button type="button" disabled="" data-picked="">Globex</button>
</div>

The confirm card, shown only while the call waits:

<div data-assisted-confirm="">
<p>Cancel Globex's order #1043</p>
<button type="button" data-answer="approve">Approve</button>
<button type="button" data-answer="deny">Deny</button>
</div>