-
Notifications
You must be signed in to change notification settings - Fork 138
Description
Description
When using @openrouter/ai-sdk-provider with multi-step tool calling (e.g., via Vercel AI SDK's streamText + stepCountIs), the streaming response appears buffered to the end user. Text deltas stream fine, but something in the tool-call streaming path causes a perceived delay before the tool executes and the next LLM step begins.
Switching to @ai-sdk/openai with baseURL: 'https://openrouter.ai/api/v1' (same API, different SDK client) resolves the issue — streaming becomes real-time token-by-token.
Bug Found: Missing tool-input-end in multi-chunk tool call path
In src/chat/index.ts, the single-chunk tool call path (lines ~905-949) correctly emits the full sequence:
tool-input-start→tool-input-delta→tool-input-end→tool-call
But the multi-chunk merge path (lines ~990-1013) skips tool-input-end:
tool-input-delta→tool-call(missingtool-input-endbeforetool-call)
// Multi-chunk path — emits tool-call but NO tool-input-end before it
if (isParsableJson(toolCall.function.arguments)) {
// ❌ Missing: controller.enqueue({ type: 'tool-input-end', id: toolCall.id });
controller.enqueue({
type: 'tool-call',
toolCallId: toolCall.id ?? generateId(),
toolName: toolCall.function.name,
input: toolCall.function.arguments,
...
});
toolCall.sent = true;
}This may cause downstream consumers (like the AI SDK's stream processor) to wait for the missing tool-input-end event, contributing to the perceived buffering.
Reproduction
- Use
@openrouter/ai-sdk-providerv2.x withaiSDK v6.x - Configure
streamText()with tools andstepCountIs(n)for multi-step - Send a message that triggers a tool call where arguments arrive across multiple chunks
- Observe that streaming feels delayed/buffered compared to
@ai-sdk/openai
Workaround
Use @ai-sdk/openai with OpenRouter's base URL instead:
import { createOpenAI } from '@ai-sdk/openai';
const openrouterProvider = createOpenAI({
apiKey: process.env.OPENROUTER_API_KEY,
baseURL: 'https://openrouter.ai/api/v1',
});
// Force chat completions API (not Responses API)
export const openrouter = (modelId: string) => openrouterProvider.chat(modelId);Environment
- `@openrouter/ai-sdk-provider`: 2.2.3
- `ai`: 6.0.81
- Node.js: 24
- Model tested: `openai/gpt-5.2`