Skip to content

Vercel AI SDK ​

The ai package with an OpenAI-shaped provider. For the Anthropic and Google providers, see Vercel AI SDK (Anthropic) and Vercel AI SDK (Google).

Connect ​

Use createOpenAICompatible with supportsStructuredOutputs: true:

ts
const baseURL = process.env.PLUGBOARD_BASE_URL! // ends in /v1
const apiKey = process.env.PLUGBOARD_KEY!

// 1. createOpenAICompatible: Chat Completions. supportsStructuredOutputs sends json_schema for Output.object (structured.ts).
export const compat = createOpenAICompatible({ name: "plugboard", baseURL, apiKey, includeUsage: true, supportsStructuredOutputs: true })

// 2. openai.chat(id): Chat Completions through @ai-sdk/openai.
// 3. openai(id): the default. In @ai-sdk/openai v4 it is the Responses API (POST /v1/responses).
export const openai = createOpenAI({ baseURL, apiKey })

The snippets below call client(model), a function from a model id to a model; model is an alias such as "fast" or any allowed provider/model[#variant].

@ai-sdk/openai also works. Its default openai(id) uses the Responses API; openai.chat(id) uses Chat Completions.

Chat ​

ts
const { text, finishReason, usage } = await generateText({ model: client(model), prompt: "Reply with exactly: pong", maxOutputTokens: 1024 })

Tool calls ​

The SDK runs execute and sends the follow-up request. Plugboard only returns the call.

ts
const get_weather = tool({
  description: "Current weather for a city",
  inputSchema: z.object({ city: z.string().describe("City name") }),
  execute: async ({ city }) => {
    cities.push(city)
    return weatherResult
  },
})
const result = await generateText({ model: client(model), tools: { get_weather }, stopWhen: isStepCount(4), prompt: PROMPT, maxOutputTokens: 1024 })

Structured output ​

ts
const { output } = await generateText({ model: client(model), output: Output.object({ schema: Meal }), prompt: PROMPT, maxOutputTokens: 1024 })

Multi-turn on the Responses API ​

openai(id) sends store: true, so later turns refer to earlier answers by item_reference. Plugboard resolves those while it holds the answer (one hour, the last 1000 per app). For long-lived chats, pass providerOptions: { openai: { store: false } } so the SDK sends earlier turns in full:

ts
const get_weather = tool({
  description: "Current weather for a city",
  inputSchema: z.object({ city: z.string().describe("City name") }),
  execute: async ({ city }) => {
    cities.push(city)
    return weatherResult
  },
})
const result = await generateText({
  model: client(model),
  tools: { get_weather },
  stopWhen: isStepCount(4),
  prompt: PROMPT,
  maxOutputTokens: 1024,
  providerOptions: { openai: { store: false } },
})

Limits ​

  • Without supportsStructuredOutputs: true, createOpenAICompatible sends response_format: json_object with no schema, the model guesses the keys, and Output.object throws NoObjectGeneratedError.
  • The SDK has no model-list call. Use fetch on GET /v1/models.
  • The schema in structured output is not enforced by the provider. Validate the answer.