The Items Paradigm
callModel is built on OpenRouter’s Responses API which uses an items-based
model rather than the messages-based model used by OpenAI Chat or Vercel AI
SDK.
The key insight: items are emitted multiple times with the same ID but
progressively updated content. You replace the entire item by ID rather than
accumulating stream chunks.
Messages vs Items
| Traditional (OpenAI Chat, Vercel AI) | callModel (Items-native) |
|---|---|
| Stream chunks, accumulate text | Stream items, replace by ID |
| Single message type | Multiple item types |
| Reconstruct content at end | Each emission is complete |
| Manual state management | Natural React state updates |
Item Types
getItemsStream() yields these item types:
| Type | Description |
|---|---|
message | Assistant text responses |
function_call | Tool invocations with arguments |
reasoning | Model thinking (extended thinking) |
web_search_call | Web search operations |
file_search_call | File search operations |
image_generation_call | Image generation operations |
function_call_output | Results from executed tools |
How Streaming Works
Each iteration yields a complete item with the same ID but updated content:React Integration
The items paradigm eliminates manual chunk accumulation. Use a Map keyed by item ID and let React’s reconciliation handle updates:Benefits
- No chunk accumulation - Each item emission is complete
- Natural React updates - Setting state triggers re-render automatically
- Concurrent item handling - Function calls and messages stream in parallel
- Works with React 18+ - Compatible with concurrent features and Suspense
- Type-safe - Full TypeScript inference for all item types
Comparison with Chunk Accumulation
Traditional streaming requires manual accumulation:Migrating from getNewMessagesStream()
getNewMessagesStream() is deprecated in favor of getItemsStream(). The
migration is straightforward:
getItemsStream() includes all item types (reasoning,
function calls, etc.), not just messages.