Skip to content

Migrate to Vercel AI SDK for unified LLM abstraction - #6

Open
vivekhaldar wants to merge 2 commits into
DorsaRoh:mainfrom
vivekhaldar:vercel-ai-sdk-migration
Open

Migrate to Vercel AI SDK for unified LLM abstraction#6
vivekhaldar wants to merge 2 commits into
DorsaRoh:mainfrom
vivekhaldar:vercel-ai-sdk-migration

Conversation

@vivekhaldar

Copy link
Copy Markdown

Motivation

The current implementation uses two separate SDKs (@anthropic-ai/sdk and openai) with nearly identical streaming logic duplicated for each provider (~70 lines each). This works, but:

  1. Adding new providers requires copy-pasting — Want to add Google Gemini or Mistral? You'd need to write another 70-line streaming function.

  2. Maintenance burden — Bug fixes or improvements to streaming logic need to be applied in two places.

  3. Inconsistent error handling — Each SDK has slightly different error formats that need individual handling.

Solution

Replace both SDKs with the Vercel AI SDK (ai package), which provides:

  • Unified interface — One streamText() function works with any provider
  • Trivial provider additions — Adding Gemini = import { google } from '@ai-sdk/google'
  • Battle-tested — Used in production by Vercel's v0 and thousands of other apps
  • Active maintenance — Regular updates, good TypeScript support

Changes

Dependencies

- "@anthropic-ai/sdk": "^0.32.1"
- "openai": "^6.15.0"
+ "ai": "^6.0.5"
+ "@ai-sdk/anthropic": "^3.0.2"
+ "@ai-sdk/openai": "^3.0.2"

Code

  • app/api/claude/route.ts — Replaced dual streaming functions with unified streamToClient() using AI SDK's streamText()
  • lib/ai/providers.ts (new) — Extracted provider utilities for testability
  • lib/__tests__/providers.test.ts (new) — 21 tests for provider detection and validation

Metrics

Metric Before After
API route lines ~400 ~280
Streaming functions 2 1
Test count 42 63

Backward Compatibility

The frontend is unchanged. The SSE format (data: {"type": "content_block_delta", ...}) is preserved, so the existing streaming consumer works without modification.

Testing

pnpm test        # All 63 tests pass
pnpm lint        # TypeScript check passes
pnpm dev         # Manual testing works

Future Possibilities

With this foundation, adding new providers becomes trivial:

import { google } from '@ai-sdk/google';
import { mistral } from '@ai-sdk/mistral';

// Just add to createModel():
if (provider === "google") return google(modelId);
if (provider === "mistral") return mistral(modelId);

- Replace @anthropic-ai/sdk and openai with ai, @ai-sdk/anthropic, @ai-sdk/openai
- Unify streaming logic into single streamToClient function using AI SDK's streamText
- Extract provider utilities to lib/ai/providers.ts for testability
- Add 21 new tests for provider detection and API key validation
- Maintain backward-compatible SSE format for frontend

The migration reduces the API route from ~400 lines to ~280 lines and makes
adding new providers trivial (just import the provider package).
@vercel

vercel Bot commented Jan 2, 2026

Copy link
Copy Markdown

@vivekhaldar is attempting to deploy a commit to the dorsaroh's projects Team on Vercel.

A member of the Team first needs to authorize it.

@gitguardian

gitguardian Bot commented Jan 2, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
- - Generic High Entropy Secret 80acb21 lib/tests/providers.test.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

The truncateChatHistory and formatChatHistory functions were accidentally
removed during the migration. This restores them to preserve conversational
context when editing existing compositions.
@vivekhaldar
vivekhaldar marked this pull request as ready for review January 2, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant