FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
werewolf006
werewolf006Townie
Remix of valdottown/Townie
Public
Like
Townie
Home
Code
17
.claude
1
.vscode
1
backend
5
frontend
7
prompts
2
shared
1
test-list-file
1
test-val
.cursorrules
.gitignore
.vtignore
AI_SDK_V5_MIGRATION_GUIDE.md
CLAUDE.md
README.md
TODOs.md
deno.json
H
index.ts
Branches
2
Pull requests
Remixes
1
History
Environment variables
13
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
AI_SDK_V5_MIGRATION_GUIDE.md
Code
/
AI_SDK_V5_MIGRATION_GUIDE.md
Search
…
AI_SDK_V5_MIGRATION_GUIDE.md

AI SDK v4 to v5 Migration Guide

Overview

This document provides complete migration instructions for upgrading the Townie codebase from AI SDK v4 to v5. This migration involves breaking changes in message structure, package organization, and API changes.

Package Version Updates

Core Packages

Update all AI SDK imports from v4 to v5:

Backend files (backend/routes/send-message.ts, backend/tools/*.ts):

// BEFORE (v4): import { createAnthropic } from "npm:@ai-sdk/anthropic@1.2.12"; import { convertToCoreMessages, type CoreUserMessage, streamText, } from "npm:ai@4.3.19"; import { tool } from "npm:ai@4.3.19"; // AFTER (v5): import { createAnthropic } from "npm:@ai-sdk/anthropic@2.0.0"; import { convertToCoreMessages, type CoreUserMessage, streamText, } from "npm:ai@5.0.0"; import { tool } from "npm:ai@5.0.0";

Frontend file (index.ts):

// BEFORE (v4): "@ai-sdk/react": "https://esm.sh/@ai-sdk/react@1.2.12?deps=react@18.2.0,react-dom@18.2.0,zod@3.25.76", // AFTER (v5): "@ai-sdk/react": "https://esm.sh/@ai-sdk/react@2.0.0?deps=react@18.2.0,react-dom@18.2.0,zod@3.25.76",

Breaking Changes & Required Code Updates

1. Message Structure Changes (send-message.ts)

Message Content Format Change: Messages now use a parts array structure instead of a content string.

Lines 120-128 - Update CoreUserMessage creation:

// BEFORE (v4): const newUserMessage: CoreUserMessage = { role: "user", content: typeof lastUserMessageContent === "string" ? [{ type: "text", text: lastUserMessageContent, }] : lastUserMessageContent, }; // AFTER (v5): const newUserMessage: CoreUserMessage = { role: "user", content: typeof lastUserMessageContent === "string" ? [{ type: "text", text: lastUserMessageContent, }] : lastUserMessageContent, // This stays the same as it's already in parts format };

Lines 142-147 - Update image part format:

// BEFORE (v4): newUserMessage.content.push({ type: "image", image: image.url, mimeType, }); // AFTER (v5): newUserMessage.content.push({ type: "image", url: image.url, // Changed from 'image' to 'url' mimeType, });

2. Parameter Renames (send-message.ts)

Line 200 - Rename maxTokens parameter:

// BEFORE (v4): maxTokens: 4_096 * 10, // AFTER (v5): maxOutputTokens: 4_096 * 10, // Renamed from maxTokens

3. Tool Schema Updates

All tool files (backend/tools/text-editor.ts, backend/tools/fetch.ts, backend/tools/traces.ts, backend/tools/think.ts, backend/tools/change-val-type.ts):

Update the tool() function calls to use inputSchema instead of schema:

// BEFORE (v4): export function makeTextEditorTool({ bearerToken, project, branch_id }: ToolConfig) { return tool({ description: "...", parameters: z.object({ // schema definitions }), // ... rest of tool }); } // AFTER (v5): export function makeTextEditorTool({ bearerToken, project, branch_id }: ToolConfig) { return tool({ description: "...", inputSchema: z.object({ // Changed from 'parameters' to 'inputSchema' // schema definitions - these stay the same }), // ... rest of tool }); }

4. Frontend useChat Hook (useChatLogic.ts)

The useChat hook API remains largely compatible, but message structure changes:

Lines 32-76 - The useChat hook usage stays the same, but internally messages now use parts structure:

// The useChat call itself doesn't change, but be aware that: // - messages[].content is now a parts array // - Image handling in the body.images mapping may need adjustment

Type System Updates

CoreUserMessage Type Changes

The CoreUserMessage type now expects content as a parts array:

// BEFORE (v4): interface CoreUserMessage { role: "user"; content: string | Array<TextPart | ImagePart>; } // AFTER (v5): interface CoreUserMessage { role: "user"; content: Array<TextPart | ImagePart>; // Always an array now } // ImagePart structure change: // BEFORE: { type: "image", image: string, mimeType?: string } // AFTER: { type: "image", url: string, mimeType?: string }

Files That Need Updates

Priority 1 - Core Functionality

  1. backend/routes/send-message.ts - Main API endpoint

    • Package imports (lines 2, 3-7)
    • Image part format (lines 142-147)
    • maxTokens → maxOutputTokens (line 200)
  2. index.ts - Package version for frontend

    • @ai-sdk/react version update

Priority 2 - Tool Definitions

  1. backend/tools/text-editor.ts - parameters → inputSchema
  2. backend/tools/fetch.ts - parameters → inputSchema
  3. backend/tools/traces.ts - parameters → inputSchema
  4. backend/tools/think.ts - parameters → inputSchema
  5. backend/tools/change-val-type.ts - parameters → inputSchema

Priority 3 - Frontend (Lower Risk)

  1. frontend/hooks/useChatLogic.ts - Import update only (line 1)

Testing Checklist

After making changes, verify:

  1. Basic chat functionality - Send text messages
  2. Image uploads - Send messages with images
  3. Tool execution - Verify each tool (text-editor, fetch, traces, think, change-val-type)
  4. Streaming - Ensure message streaming still works
  5. Error handling - Test error scenarios
  6. Sound effects - Verify completion sounds work
  7. Message formatting - Check assistant message display

Potential Issues & Solutions

Issue: Type errors with message content

Solution: Ensure all message.content references expect parts array format

Issue: Image display broken

Solution: Check image part format uses url instead of image property

Issue: Tool execution fails

Solution: Verify all tools use inputSchema instead of parameters

Issue: Frontend build errors

Solution: Check @ai-sdk/react version compatibility with React 18.2.0

Migration Order

  1. Backend first: Update send-message.ts and tools
  2. Test backend: Use API directly to verify functionality
  3. Frontend second: Update index.ts and useChatLogic.ts
  4. Full integration test: Test complete user flow

Rollback Plan

If migration fails:

  1. Revert package versions to v4:
    • npm:ai@4.3.19
    • npm:@ai-sdk/anthropic@1.2.12
    • @ai-sdk/react@1.2.12
  2. Revert code changes:
    • maxOutputTokens → maxTokens
    • inputSchema → parameters
    • url → image in image parts
  3. Test functionality before proceeding

Additional Notes

  • Val Town Compatibility: Ensure ESM imports work with Val Town platform
  • React 18.2.0 Pinning: Maintain React version pinning for compatibility
  • Zod Compatibility: AI SDK v5 supports both Zod 3 and 4
  • No Breaking Changes: Most streaming and error handling should remain compatible

This migration primarily affects message structure and tool definitions. The core streaming and chat functionality should work similarly once the breaking changes are addressed.

Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesCLIAI agentsCode intelligenceSlack integrationsGTMPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.