Vercel AI SDK
Run any Vercel AI SDK language model (OpenAI, Google, Anthropic, Ollama, the AI Gateway, ...) as the pipeline's LLM with AISDKLLMService.
Overview
AISDKLLMService runs a Vercel AI SDK language model as the pipeline's LLM
service. The AI SDK gives one interface to many providers, so one service covers all of them:
@ai-sdk/openai, @ai-sdk/google, @ai-sdk/anthropic, @ai-sdk/mistral, @ai-sdk/amazon-bedrock,
Ollama and the other community providers, and model ID strings routed through the AI Gateway.
AISDKLLMService: anLLMServicethat streams the model's reply with the AI SDK'sstreamText(). It behaves like pipedog's native LLM services: it consumesLLMContextFrames, pushesLLMFullResponseStartFrame,LLMTextFrames andLLMFullResponseEndFrame, runs function calls through pipedog's function calling, and reports TTFB, processing time and token usage.
This is a pipedog addition: Pipecat (Python) has no AI SDK service.
Source
packages/ai-sdk/src/llm.ts and the message adapter, ai_sdk_adapter.ts.
AI SDK providers
The official and community providers, and their model IDs and options.
Installation
ai (version 7) is a peer dependency, so you pick its version. Add the provider package you use,
and zod, which ai requires.
bun add @pipedog/ai-sdk ai zod @ai-sdk/googleimport { AISDKLLMService } from "@pipedog/ai-sdk";Prerequisites
- Whatever the provider needs.
@ai-sdk/googlereadsGOOGLE_GENERATIVE_AI_API_KEY, or takescreateGoogleGenerativeAI({ apiKey }). A model ID string uses the AI Gateway, which readsAI_GATEWAY_API_KEY.
AISDKLLMService
Configuration
Prop
Type
Settings
AISDKLLMService.Settings (AISDKLLMSettings) holds the runtime-updatable settings. The common
fields map to the AI SDK's call settings: temperature, maxTokens (maxOutputTokens), topP,
topK, frequencyPenalty, presencePenalty and seed. null, the default, leaves a field to the
provider.
Prop
Type
systemInstruction is sent as the AI SDK's instructions. extra is merged into the
streamText() call as is.
Usage
import { google } from "@ai-sdk/google";
import { AISDKLLMService } from "@pipedog/ai-sdk";
const llm = new AISDKLLMService({
model: google("gemini-3.5-flash-lite"),
settings: new AISDKLLMService.Settings({
systemInstruction: "You are a helpful voice assistant. Keep answers short.",
temperature: 0.7,
maxTokens: 1024,
}),
});
Function calling
Tools come from the context's ToolsSchema, as with every LLM service. Each FunctionSchema
becomes an AI SDK tool with a JSON schema and no execute, so the AI SDK hands the model's calls
back to pipedog, which runs the registered handler (or the schema's own handler, or a direct
function), adds the result to the context and asks the model again.
import { FunctionSchema } from "@pipedog/core/adapters/llm/schemas/function_schema";
import { ToolsSchema } from "@pipedog/core/adapters/llm/schemas/tools_schema";
import { LLMContext } from "@pipedog/core/processors/aggregators/llm_context";
import type { FunctionCallParams } from "@pipedog/core/services/llm_service";
const weather = new FunctionSchema({
name: "get_weather",
description: "Get the current weather for a city",
properties: { city: { type: "string" } },
required: ["city"],
});
// pipedog runs the handler and sends the result back to the model.
llm.registerFunction("get_weather", async (params: FunctionCallParams) => {
await params.resultCallback({ conditions: "sunny", celsius: 21 });
});
const context = new LLMContext({ tools: new ToolsSchema({ standardTools: [weather] }) });
Provider-defined tools, such as Google Search grounding or OpenAI web search, go in the tools
option. They are sent on every request and run on the provider's side.
Switching models
import { LLMUpdateSettingsFrame } from "@pipedog/core/frames/frames";
// With `provider`, a model ID in a settings update switches the model.
const switchable = new AISDKLLMService({
model: google("gemini-3.5-flash-lite"),
provider: google,
});
const update = new LLMUpdateSettingsFrame({
delta: new AISDKLLMService.Settings({ model: "gemini-3.5-flash" }),
});
// Or switch to a model from any provider directly.
switchable.setLanguageModel(google("gemini-3.5-flash"));Without provider, a model ID in a settings update can't be turned into a model, so it is ignored
with a warning (unless the model was given as an ID string in the first place).
Provider options
Provider-specific options go in providerOptions, keyed by provider, as in the AI SDK:
const thinkingOff = new AISDKLLMService({
model: google("gemini-3.5-flash-lite"),
settings: new AISDKLLMService.Settings({
providerOptions: { google: { thinkingConfig: { thinkingBudget: 0 } } },
}),
});Notes
- Consumes
LLMContextFrame. For each response it pushesLLMFullResponseStartFrame, oneLLMTextFrameper streamed text delta andLLMFullResponseEndFrame, even when the request fails. - Reasoning is pushed as
LLMThoughtStartFrame/LLMThoughtTextFrame/LLMThoughtEndFrameand kept in the context, so providers that need it back (Anthropic thinking blocks) get it. - Provider metadata that comes with a tool call or the reply text, such as Gemini's thought signatures, is kept in the context and sent back with that output on later turns.
- An initial
"system"context message becomes the instructions when the service has nosystemInstruction. Later"system"and"developer"messages are sent as user messages. - Images (
image_url), files (file_url,file_base64) and audio (input_audio) in user messages become AI SDK image and file parts. File URLs are fetched by pipedog's file resolver and sent inline. - A failed request is pushed upstream as an
ErrorFrame(Error during completion: ...). The AI SDK retries failed requests itself (maxRetries, 2 by default). runInference()runs a one-shotgenerateText(). AresponseSchemais passed asOutput.object(), so the provider enforces it where it can.
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/ai-sdk/package.json: ✅ means the compat smoke test passes on that runtime.
- An interruption cancels the response: the request's
abortSignalis aborted and each stream part is a cancellation point. - The service uses no runtime-specific APIs. Whether a provider package runs on a given runtime is
up to that package; the official ones use
fetch.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).