Vercel AI SDK
The Vercel AI SDK’s OpenAI and Anthropic providers both accept a baseURL. Point them at TapPass and every streamText, generateText, and tool invocation is governed.
Setup (OpenAI)
Section titled “Setup (OpenAI)”import { openai, createOpenAI } from "@ai-sdk/openai";import { streamText } from "ai";
const tappass = createOpenAI({ baseURL: "https://tappass.example.com/v1", apiKey: process.env.TAPPASS_API_KEY,});
const { textStream } = await streamText({ model: tappass("gpt-4o-mini"), prompt: "Hello",});
for await (const chunk of textStream) process.stdout.write(chunk);Setup (Anthropic)
Section titled “Setup (Anthropic)”import { createAnthropic } from "@ai-sdk/anthropic";import { streamText } from "ai";
const tappass = createAnthropic({ baseURL: "https://tappass.example.com", apiKey: process.env.TAPPASS_API_KEY,});
const { textStream } = await streamText({ model: tappass("claude-3-5-sonnet-20241022"), prompt: "Hello",});Tool calls
Section titled “Tool calls”import { streamText, tool } from "ai";import { z } from "zod";
const { textStream } = await streamText({ model: tappass("gpt-4o-mini"), prompt: "Check the weather in Brussels", tools: { weather: tool({ description: "Get the weather", parameters: z.object({ city: z.string() }), execute: async ({ city }) => `Sunny in ${city}`, }), },});Every tool call is audited — use tool_decision.rego to approve/block specific tools server-side.
Per-request headers
Section titled “Per-request headers”const tappass = createOpenAI({ baseURL: "https://tappass.example.com/v1", apiKey: process.env.TAPPASS_API_KEY, headers: { "X-Agent-Id": "next-app-chat", "X-Governance-Flags": "pii=mask,budget=dev", },});Next.js route handler
Section titled “Next.js route handler”import { streamText } from "ai";import { tappass } from "@/lib/tappass";
export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: tappass("gpt-4o-mini"), messages }); return result.toDataStreamResponse();}