Complete "Persisting widget state" pattern documentation
Replaces the TODO stub with complete server-side and client-side examples based on the `pdf-server` implementation pattern: - Server: shows returning `widgetUUID` via `CallToolResult._meta` - Client: shows receiving UUID via `ontoolresult`, using it as localStorage key with generic `saveState<T>()` / `loadState<T>()` helpers Also clarifies the distinction between widget state persistence (UI state surviving page reloads) and `updateModelContext()` (model-visible state). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a0265f92d2
commit
05e07a76e7
1 changed files with 78 additions and 12 deletions
|
|
@ -54,13 +54,20 @@ Listen for display mode changes via {@link app!App.onhostcontextchanged onhostco
|
|||
|
||||
{@includeCode ../src/app.examples.ts#App_onhostcontextchanged_respondToDisplayMode}
|
||||
|
||||
## [TODO] Persist data (incl. widget state)
|
||||
## Persisting widget state
|
||||
|
||||
- Note: OAI's `window.openai.setWidgetState({modelContent, privateContent, imageIds})` has only a partial equivalent in the MCP Apps spec (for now!): `App.updateModelContext({content, structuredContent})`
|
||||
- For data persistence / to reload when conversation is reloaded, you must use localStorage / IndexedDb with `hostInfo.toolInfo.id` as key returned `CallToolResult._meta.widgetUUID = randomUUID()`
|
||||
To persist widget state across conversation reloads (e.g., current page in a PDF viewer, camera position in a map), use [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) with a stable identifier provided by the server.
|
||||
|
||||
**Server-side**: Tool handler generates a unique `widgetUUID` and returns it in `CallToolResult._meta.widgetUUID`:
|
||||
|
||||
{@includeCode ./patterns.tsx#persistDataServer}
|
||||
|
||||
**Client-side**: Receive the UUID in {@link app!App.ontoolresult ontoolresult} and use it as the storage key:
|
||||
|
||||
{@includeCode ./patterns.tsx#persistData}
|
||||
|
||||
> **Note:** For model-visible state (informing the LLM about what the user is viewing), use {@link app!App.updateModelContext updateModelContext} instead. Widget state persistence is for UI state that should survive page reloads but doesn't need to be seen by the model.
|
||||
|
||||
## Lowering perceived latency
|
||||
|
||||
Use {@link app!App.ontoolinputpartial ontoolinputpartial} to receive streaming tool arguments as they arrive, allowing you to show a loading preview before the complete input is available.
|
||||
|
|
|
|||
Loading…
Reference in a new issue