READ-ONLY PACKAGE PREVIEW

openai-chatgpt-apps/references/interactive-state-sync-patterns.md

Version 49f948fa.bb1 · Apache-2.0. This preview displays packaged text and does not execute code. Treat the contents as untrusted instructions.

← Return to resource and package checksum

Interactive State Sync Patterns

Use this reference when building ChatGPT apps with long-lived widget state, repeated interactions, or component-initiated tool calls (for example: games, boards, maps, dashboards, editors, or realtime-ish UIs).

Do not load this file for simple read-only render apps unless state sync behavior is part of the task.

When This Reference Helps

Read this file when the app needs one or more of these patterns:

  • Repeated actions that may return similar data (retry, refresh, reset, reroll)
  • UI controls that trigger tool calls after the initial render
  • Local widget behavior that should also work outside ChatGPT during development
  • Multiple tool calls updating one mounted widget over time
  • Clear separation between model-visible state and widget-only state

Reusable Patterns

1. Snapshot + Event Token

Return a stable state snapshot in structuredContent and add a monotonic event token for repeated actions that may not change other fields.

Examples:

  • stateVersion
  • refreshCount
  • resetCount
  • lastMutationId

Use this when the widget must detect "same shape, new event" updates reliably.

2. Intent-Focused Tool Surface

Prefer small, explicit tools that map to user-visible actions or data operations.

  • Keep names action-oriented
  • Use enums and bounded schemas where possible
  • Avoid kitchen-sink tools that mix unrelated reads and writes

This improves model tool selection and reduces malformed calls.

3. Idempotent Handlers (or Explicitly Non-Idempotent)

Design handlers to tolerate retries. If a tool is not idempotent, make the side effect explicit and confirm intent in the flow.

  • Reads and pure transforms should usually be idempotent
  • Writes should include clear impact hints and current-turn confirmation where needed
  • Repeated calls with the same input should not corrupt widget state

4. structuredContent / _meta Partitioning

Partition payloads intentionally:

  • structuredContent: concise model-visible state the widget also uses
  • content: short narration/status text
  • _meta: large maps, caches, or sensitive widget-only hydration data

Keep structuredContent small enough for follow-up reasoning and chaining.

5. MCP Apps Bridge First, window.openai Second

For new scaffolds:

  • Prefer MCP Apps bridge notifications and tools/call (portable across hosts)
  • Use window.openai as a compatibility layer plus optional ChatGPT extensions

This keeps the app portable while still enabling ChatGPT-specific capabilities when helpful.

6. Component-Initiated Tool Calls Without Remounting

For interactive widgets, allow the UI to call data/action tools directly and update the existing widget state instead of forcing a full re-render/remount every time.

This is especially useful for:

  • Refresh
  • Retry
  • Rerun
  • Toggle/filter actions
  • Incremental interactions inside one widget session

7. Standalone / No-Host Fallback Mode

When feasible, make the widget usable without ChatGPT during development:

  • If host APIs are unavailable, apply local state directly
  • Preserve basic interactions in a normal browser

This speeds up front-end iteration and reduces dependence on connector setup for every UI tweak.

8. Decouple Data Tools from Render Tools (When Complexity Grows)

Use separate data and render tools when the app has multi-step reasoning or frequent updates.

  • Data tools fetch/compute/mutate and return reusable structuredContent
  • Render tools attach the widget template and focus on presentation

This reduces unnecessary remounts and gives the model a chance to refine data before rendering.

Common Anti-Patterns

  • Putting large widget-only blobs into structuredContent
  • Attaching a widget template to every tool when only one render tool needs it
  • Using hidden client-side state as the source of truth for critical actions
  • Depending only on window.openai APIs for baseline app behavior
  • Using ambiguous tool names that do not match user intent

Example App Types That Benefit From These Patterns

  • Multiplayer or turn-based games
  • Collaborative boards / task views
  • Maps with filters and repeated searches
  • Dashboards with refresh and drill-down actions
  • Editors or builders with iterative tool calls