fix build errors

This commit is contained in:
dal 2025-08-24 21:42:38 -06:00
parent 455888cdcd
commit 980a786d21
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
2 changed files with 61 additions and 43 deletions

View File

@ -2,20 +2,21 @@ import type { ModelMessage } from 'ai';
/** /**
* Converts AI SDK v4 CoreMessage to v5 ModelMessage * Converts AI SDK v4 CoreMessage to v5 ModelMessage
* *
* Key differences: * Key differences:
* - ImagePart: mimeType mediaType * - ImagePart: mimeType mediaType
* - FilePart: mimeType mediaType, added optional filename * - FilePart: mimeType mediaType, added optional filename
* - ToolResultPart: result output (with structured type) * - ToolResultPart: result output (with structured type)
* - ToolCallPart: remains the same (args field) * - ToolCallPart: remains the same (args field)
*/ */
export function convertCoreMessageToModelMessage(message: any): ModelMessage { export function convertCoreMessageToModelMessage(message: unknown): ModelMessage {
// Handle null/undefined // Handle null/undefined
if (!message || typeof message !== 'object' || !message.role) { if (!message || typeof message !== 'object' || !('role' in message)) {
return message as ModelMessage; return message as ModelMessage;
} }
const { role, content } = message; const msg = message as Record<string, unknown>;
const { role, content } = msg;
switch (role) { switch (role) {
case 'system': case 'system':
@ -33,14 +34,15 @@ export function convertCoreMessageToModelMessage(message: any): ModelMessage {
content, content,
}; };
} }
if (Array.isArray(content)) { if (Array.isArray(content)) {
return { return {
role: 'user', role: 'user',
content: content.map(convertContentPart), // biome-ignore lint/suspicious/noExplicitAny: necessary for v4 to v5 conversion
content: content.map(convertContentPart) as any,
}; };
} }
return { role: 'user', content: '' }; return { role: 'user', content: '' };
case 'assistant': case 'assistant':
@ -51,14 +53,15 @@ export function convertCoreMessageToModelMessage(message: any): ModelMessage {
content, content,
}; };
} }
if (Array.isArray(content)) { if (Array.isArray(content)) {
return { return {
role: 'assistant', role: 'assistant',
content: content.map(convertContentPart), // biome-ignore lint/suspicious/noExplicitAny: necessary for v4 to v5 conversion
content: content.map(convertContentPart) as any,
}; };
} }
return { role: 'assistant', content: '' }; return { role: 'assistant', content: '' };
case 'tool': case 'tool':
@ -66,10 +69,11 @@ export function convertCoreMessageToModelMessage(message: any): ModelMessage {
if (Array.isArray(content)) { if (Array.isArray(content)) {
return { return {
role: 'tool', role: 'tool',
content: content.map(convertToolResultPart), // biome-ignore lint/suspicious/noExplicitAny: necessary for v4 to v5 conversion
content: content.map(convertToolResultPart) as any,
}; };
} }
return { role: 'tool', content: [] }; return { role: 'tool', content: [] };
default: default:
@ -81,20 +85,21 @@ export function convertCoreMessageToModelMessage(message: any): ModelMessage {
/** /**
* Convert content parts from v4 to v5 format * Convert content parts from v4 to v5 format
*/ */
function convertContentPart(part: any): any { function convertContentPart(part: unknown): unknown {
if (!part || typeof part !== 'object' || !part.type) { if (!part || typeof part !== 'object' || !('type' in part)) {
return part; return part;
} }
switch (part.type) { const p = part as Record<string, unknown>;
switch (p.type) {
case 'text': case 'text':
// Text parts remain the same // Text parts remain the same
return part; return part;
case 'image': case 'image':
// Convert mimeType → mediaType // Convert mimeType → mediaType
if ('mimeType' in part) { if ('mimeType' in p) {
const { mimeType, ...rest } = part; const { mimeType, ...rest } = p;
return { return {
...rest, ...rest,
mediaType: mimeType, mediaType: mimeType,
@ -104,8 +109,8 @@ function convertContentPart(part: any): any {
case 'file': case 'file':
// Convert mimeType → mediaType // Convert mimeType → mediaType
if ('mimeType' in part) { if ('mimeType' in p) {
const { mimeType, ...rest } = part; const { mimeType, ...rest } = p;
return { return {
...rest, ...rest,
mediaType: mimeType, mediaType: mimeType,
@ -114,7 +119,11 @@ function convertContentPart(part: any): any {
return part; return part;
case 'tool-call': case 'tool-call':
// Tool calls remain the same (args field stays) // Tool calls: args → input (AI SDK v5 change)
if ('args' in p) {
const { args, ...rest } = p;
return { ...rest, input: args };
}
return part; return part;
default: default:
@ -125,17 +134,23 @@ function convertContentPart(part: any): any {
/** /**
* Convert tool result parts from v4 to v5 format * Convert tool result parts from v4 to v5 format
*/ */
function convertToolResultPart(part: any): any { function convertToolResultPart(part: unknown): unknown {
if (!part || typeof part !== 'object' || part.type !== 'tool-result') { if (!part || typeof part !== 'object') {
return part;
}
const p = part as Record<string, unknown>;
if (p.type !== 'tool-result') {
return part; return part;
} }
// Convert result → output with proper structure // Convert result → output with proper structure
if ('result' in part && !('output' in part)) { if ('result' in p && !('output' in p)) {
const { result, experimental_content, isError, ...rest } = part; const { result, experimental_content, isError, ...rest } = p;
// Convert result to structured output format // Convert result to structured output format
let output; let output: { type: string; value: unknown };
if (isError) { if (isError) {
// Error results // Error results
if (typeof result === 'string') { if (typeof result === 'string') {
@ -151,20 +166,20 @@ function convertToolResultPart(part: any): any {
output = { type: 'json', value: result }; output = { type: 'json', value: result };
} }
} }
return { return {
...rest, ...rest,
output, output,
}; };
} }
return part; return part;
} }
/** /**
* Converts an array of v4 CoreMessages to v5 ModelMessages * Converts an array of v4 CoreMessages to v5 ModelMessages
*/ */
export function convertCoreMessagesToModelMessages(messages: any[]): ModelMessage[] { export function convertCoreMessagesToModelMessages(messages: unknown[]): ModelMessage[] {
if (!Array.isArray(messages)) { if (!Array.isArray(messages)) {
return []; return [];
} }
@ -175,7 +190,7 @@ export function convertCoreMessagesToModelMessages(messages: any[]): ModelMessag
* Helper to check if content is already in v5 format * Helper to check if content is already in v5 format
* Useful when migrating codebases that might have mixed formats * Useful when migrating codebases that might have mixed formats
*/ */
export function isV5ContentFormat(content: any): boolean { export function isV5ContentFormat(content: unknown): boolean {
// Check for tool result with v5 output field // Check for tool result with v5 output field
if (Array.isArray(content) && content.length > 0) { if (Array.isArray(content) && content.length > 0) {
const firstItem = content[0]; const firstItem = content[0];
@ -190,12 +205,15 @@ export function isV5ContentFormat(content: any): boolean {
* Smart conversion that handles both v4 and v5 formats * Smart conversion that handles both v4 and v5 formats
* Useful during migration when you might have mixed message formats * Useful during migration when you might have mixed message formats
*/ */
export function ensureModelMessageFormat(message: any): ModelMessage { export function ensureModelMessageFormat(message: unknown): ModelMessage {
// Already in v5 format if tool messages have 'output' field // Already in v5 format if tool messages have 'output' field
if (message?.role === 'tool' && isV5ContentFormat(message.content)) { if (message && typeof message === 'object' && 'role' in message && 'content' in message) {
return message as ModelMessage; const msg = message as Record<string, unknown>;
if (msg.role === 'tool' && isV5ContentFormat(msg.content)) {
return message as ModelMessage;
}
} }
// Convert from v4 format // Convert from v4 format
return convertCoreMessageToModelMessage(message); return convertCoreMessageToModelMessage(message);
} }

View File

@ -72,7 +72,7 @@ export function convertCoreToModel(messages: unknown): ModelMessage[] {
content: content.map(convertToolResultPart), content: content.map(convertToolResultPart),
} as ModelMessage; } as ModelMessage;
} }
return { ...msg, content: [] } as ModelMessage; return { role: 'tool', content: [] } as ModelMessage;
default: default:
return msg as ModelMessage; return msg as ModelMessage;
@ -83,7 +83,7 @@ export function convertCoreToModel(messages: unknown): ModelMessage[] {
/** /**
* Convert content parts from v4 to v5 format * Convert content parts from v4 to v5 format
*/ */
function convertContentPart(part: unknown): any { function convertContentPart(part: unknown): unknown {
if (!part || typeof part !== 'object') { if (!part || typeof part !== 'object') {
return part; return part;
} }
@ -133,13 +133,13 @@ function convertContentPart(part: unknown): any {
/** /**
* Convert tool result parts from v4 to v5 format * Convert tool result parts from v4 to v5 format
*/ */
function convertToolResultPart(part: unknown): any { function convertToolResultPart(part: unknown): unknown {
if (!part || typeof part !== 'object') { if (!part || typeof part !== 'object') {
return part; return part;
} }
const p = part as Record<string, unknown>; const p = part as Record<string, unknown>;
if (p.type !== 'tool-result') { if (p.type !== 'tool-result') {
return part; return part;
} }
@ -147,9 +147,9 @@ function convertToolResultPart(part: unknown): any {
// Convert result → structured output // Convert result → structured output
if ('result' in p && !('output' in p)) { if ('result' in p && !('output' in p)) {
const { result, experimental_content, isError, ...rest } = p; const { result, experimental_content, isError, ...rest } = p;
// Convert to v5's structured output format // Convert to v5's structured output format
let output; let output: { type: string; value: unknown };
if (isError) { if (isError) {
// Error results // Error results
if (typeof result === 'string') { if (typeof result === 'string') {
@ -165,13 +165,13 @@ function convertToolResultPart(part: unknown): any {
output = { type: 'json', value: result }; output = { type: 'json', value: result };
} }
} }
return { return {
...rest, ...rest,
output, output,
}; };
} }
return part; return part;
} }