Complete "Lowering perceived latency" pattern documentation
- Expand `App_ontoolinputpartial_progressiveRendering` example in `app.examples.ts` to show full state management pattern with `toolInputs` and `toolInputsPartial` variables - Add healed JSON caveat to `ontoolinputpartial` JSDoc in `app.ts` - Update `patterns.md` to reference the expanded example and document the streaming preview pattern - Remove empty `lowerPerceivedLatency` placeholder from `patterns.tsx` Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
dce143e92e
commit
a1ae100ef0
4 changed files with 33 additions and 18 deletions
|
|
@ -60,13 +60,14 @@ Listen for display mode changes via {@link app!App.onhostcontextchanged onhostco
|
||||||
|
|
||||||
{@includeCode ./patterns.tsx#persistData}
|
{@includeCode ./patterns.tsx#persistData}
|
||||||
|
|
||||||
## [TODO] Lower perceived latency / manage loading time
|
## Lowering perceived latency
|
||||||
|
|
||||||
Leverage partial inputs to show widgets as possible.
|
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.
|
||||||
|
|
||||||
Beware of partial JSON being partial (but healed), so some of your objects may not be complete (e.g. in a list you may need to skip the last item if your code validates input schemas strictly).
|
{@includeCode ../src/app.examples.ts#App_ontoolinputpartial_progressiveRendering}
|
||||||
|
|
||||||
{@includeCode ./patterns.tsx#lowerPerceivedLatency}
|
> [!IMPORTANT]
|
||||||
|
> Partial arguments are "healed" JSON — the host closes unclosed brackets/braces to produce valid JSON. This means objects may be incomplete (e.g., the last item in an array may be truncated). Don't rely on partial data for critical operations; use it only for preview UI.
|
||||||
|
|
||||||
## [TODO] Supporting both iframe & MCP Apps in same binary
|
## [TODO] Supporting both iframe & MCP Apps in same binary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,17 +111,6 @@ function persistData(app: App) {
|
||||||
//#endregion persistData
|
//#endregion persistData
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Example: Lower perceived latency / manage loading time
|
|
||||||
*/
|
|
||||||
function lowerPerceivedLatency(app: App) {
|
|
||||||
//#region lowerPerceivedLatency
|
|
||||||
// TODO: Leverage partial inputs to show widgets as possible.
|
|
||||||
// Beware of partial JSON being partial (but healed),
|
|
||||||
// so some objects may not be complete.
|
|
||||||
//#endregion lowerPerceivedLatency
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example: Supporting both iframe & MCP Apps in same binary
|
* Example: Supporting both iframe & MCP Apps in same binary
|
||||||
*/
|
*/
|
||||||
|
|
@ -147,6 +136,5 @@ void errorsToModel;
|
||||||
void hostStylingVanillaJs;
|
void hostStylingVanillaJs;
|
||||||
void hostStylingReact;
|
void hostStylingReact;
|
||||||
void persistData;
|
void persistData;
|
||||||
void lowerPerceivedLatency;
|
|
||||||
void iframeAndMcpApps;
|
void iframeAndMcpApps;
|
||||||
void migrateFromOpenai;
|
void migrateFromOpenai;
|
||||||
|
|
|
||||||
|
|
@ -157,13 +157,34 @@ async function App_ontoolinput_setter(app: App) {
|
||||||
*/
|
*/
|
||||||
function App_ontoolinputpartial_progressiveRendering(app: App) {
|
function App_ontoolinputpartial_progressiveRendering(app: App) {
|
||||||
//#region App_ontoolinputpartial_progressiveRendering
|
//#region App_ontoolinputpartial_progressiveRendering
|
||||||
|
let toolInputs: Record<string, unknown> | null = null;
|
||||||
|
let toolInputsPartial: Record<string, unknown> | null = null;
|
||||||
|
|
||||||
app.ontoolinputpartial = (params) => {
|
app.ontoolinputpartial = (params) => {
|
||||||
console.log("Partial args:", params.arguments);
|
toolInputsPartial = params.arguments as Record<string, unknown>;
|
||||||
// Update your UI progressively as arguments stream in
|
render();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
app.ontoolinput = (params) => {
|
||||||
|
toolInputs = params.arguments as Record<string, unknown>;
|
||||||
|
toolInputsPartial = null;
|
||||||
|
render();
|
||||||
|
};
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
if (toolInputs) {
|
||||||
|
renderFinalUI(toolInputs);
|
||||||
|
} else {
|
||||||
|
renderLoadingUI(toolInputsPartial); // e.g., shimmer with partial preview
|
||||||
|
}
|
||||||
|
}
|
||||||
//#endregion App_ontoolinputpartial_progressiveRendering
|
//#endregion App_ontoolinputpartial_progressiveRendering
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stubs for App_ontoolinputpartial_progressiveRendering example
|
||||||
|
declare function renderLoadingUI(data: Record<string, unknown> | null): void;
|
||||||
|
declare function renderFinalUI(data: Record<string, unknown>): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example: Display tool execution results using ontoolresult.
|
* Example: Display tool execution results using ontoolresult.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,11 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
||||||
* streams partial tool arguments during tool call initialization. This enables
|
* streams partial tool arguments during tool call initialization. This enables
|
||||||
* progressive rendering of tool arguments before they're complete.
|
* progressive rendering of tool arguments before they're complete.
|
||||||
*
|
*
|
||||||
|
* **Important:** Partial arguments are "healed" JSON — the host closes unclosed
|
||||||
|
* brackets/braces to produce valid JSON. This means objects may be incomplete
|
||||||
|
* (e.g., the last item in an array may be truncated). Use partial data only
|
||||||
|
* for preview UI, not for critical operations.
|
||||||
|
*
|
||||||
* This setter is a convenience wrapper around `setNotificationHandler()` that
|
* This setter is a convenience wrapper around `setNotificationHandler()` that
|
||||||
* automatically handles the notification schema and extracts the params for you.
|
* automatically handles the notification schema and extracts the params for you.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue