Skip to content

Commit 5030975

Browse files
committed
remove zod dependency and fix object structure
1 parent 99a6194 commit 5030975

File tree

2 files changed

+58
-108
lines changed

2 files changed

+58
-108
lines changed

packages/ai-providers/server-ai-vercel/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
"jest": "^29.6.1",
4949
"prettier": "^3.0.0",
5050
"ts-jest": "^29.1.1",
51-
"typescript": "5.1.6",
52-
"zod": "^3.22.0"
51+
"typescript": "5.1.6"
5352
},
5453
"peerDependencies": {
5554
"@ai-sdk/anthropic": "^2.0.0",
@@ -58,8 +57,7 @@
5857
"@ai-sdk/mistral": "^2.0.0",
5958
"@ai-sdk/openai": "^2.0.0",
6059
"@launchdarkly/server-sdk-ai": "^0.12.2",
61-
"ai": "^4.0.0 || ^5.0.0",
62-
"zod": "^3.22.0"
60+
"ai": "^4.0.0 || ^5.0.0"
6361
},
6462
"peerDependenciesMeta": {
6563
"@ai-sdk/anthropic": {

packages/ai-providers/server-ai-vercel/src/VercelProvider.ts

Lines changed: 56 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { generateObject, generateText, LanguageModel } from 'ai';
2-
import { z } from 'zod';
1+
import { generateObject, generateText, jsonSchema, LanguageModel } from 'ai';
32

43
import { AIProvider } from '@launchdarkly/server-sdk-ai';
54
import type {
@@ -47,28 +46,40 @@ export class VercelProvider extends AIProvider {
4746
* Invoke the Vercel AI model with an array of messages.
4847
*/
4948
async invokeModel(messages: LDMessage[]): Promise<ChatResponse> {
50-
// Call Vercel AI generateText
51-
// Type assertion: our MinLanguageModel is compatible with the expected LanguageModel interface
52-
// The generateText function will work with any object that has the required properties
53-
const result = await generateText({
54-
model: this._model,
55-
messages,
56-
...this._parameters,
57-
});
49+
try {
50+
// Call Vercel AI generateText
51+
const result = await generateText({
52+
model: this._model,
53+
messages,
54+
...this._parameters,
55+
});
5856

59-
// Create the assistant message
60-
const assistantMessage: LDMessage = {
61-
role: 'assistant',
62-
content: result.text,
63-
};
57+
// Create the assistant message
58+
const assistantMessage: LDMessage = {
59+
role: 'assistant',
60+
content: result.text,
61+
};
6462

65-
// Extract metrics including token usage and success status
66-
const metrics = VercelProvider.createAIMetrics(result);
63+
// Extract metrics including token usage and success status
64+
const metrics = VercelProvider.createAIMetrics(result);
6765

68-
return {
69-
message: assistantMessage,
70-
metrics,
71-
};
66+
return {
67+
message: assistantMessage,
68+
metrics,
69+
};
70+
} catch (error) {
71+
this.logger?.warn('Vercel AI model invocation failed:', error);
72+
73+
return {
74+
message: {
75+
role: 'assistant',
76+
content: '',
77+
},
78+
metrics: {
79+
success: false,
80+
},
81+
};
82+
}
7283
}
7384

7485
/**
@@ -78,25 +89,32 @@ export class VercelProvider extends AIProvider {
7889
messages: LDMessage[],
7990
responseStructure: Record<string, unknown>,
8091
): Promise<StructuredResponse> {
81-
// Convert responseStructure to Zod schema
82-
const schema = VercelProvider.convertToZodSchema(responseStructure);
83-
84-
// Call Vercel AI generateObject
85-
const result = await generateObject({
86-
model: this._model,
87-
messages,
88-
schema,
89-
...this._parameters,
90-
});
92+
try {
93+
const result = await generateObject({
94+
model: this._model,
95+
messages,
96+
schema: jsonSchema(responseStructure),
97+
...this._parameters,
98+
});
9199

92-
// Extract metrics including token usage and success status
93-
const metrics = VercelProvider.createAIMetrics(result);
100+
const metrics = VercelProvider.createAIMetrics(result);
94101

95-
return {
96-
data: result.object,
97-
rawResponse: JSON.stringify(result.object),
98-
metrics,
99-
};
102+
return {
103+
data: result.object as Record<string, unknown>,
104+
rawResponse: JSON.stringify(result.object),
105+
metrics,
106+
};
107+
} catch (error) {
108+
this.logger?.warn('Vercel AI structured model invocation failed:', error);
109+
110+
return {
111+
data: {},
112+
rawResponse: '',
113+
metrics: {
114+
success: false,
115+
},
116+
};
117+
}
100118
}
101119

102120
/**
@@ -151,72 +169,6 @@ export class VercelProvider extends AIProvider {
151169
};
152170
}
153171

154-
/**
155-
* Convert a response structure object to a Zod schema.
156-
* This method recursively converts a generic object structure to a Zod schema
157-
* that can be used with Vercel AI SDK's generateObject function.
158-
*
159-
* @param responseStructure The structure object to convert
160-
* @returns A Zod schema representing the structure
161-
*/
162-
static convertToZodSchema(responseStructure: Record<string, unknown>): z.ZodSchema {
163-
const shape: Record<string, z.ZodSchema> = {};
164-
165-
Object.entries(responseStructure).forEach(([key, value]) => {
166-
// eslint-disable-next-line no-underscore-dangle
167-
shape[key] = VercelProvider._convertValueToZodSchema(value);
168-
});
169-
170-
return z.object(shape);
171-
}
172-
173-
/**
174-
* Convert a single value to a Zod schema.
175-
* This is a helper method for convertToZodSchema that handles different value types.
176-
*
177-
* @param value The value to convert
178-
* @returns A Zod schema for the value
179-
*/
180-
private static _convertValueToZodSchema(value: unknown): z.ZodSchema {
181-
if (value === null || value === undefined) {
182-
return z.any();
183-
}
184-
185-
if (typeof value === 'string') {
186-
return z.string();
187-
}
188-
189-
if (typeof value === 'number') {
190-
return z.number();
191-
}
192-
193-
if (typeof value === 'boolean') {
194-
return z.boolean();
195-
}
196-
197-
if (Array.isArray(value)) {
198-
if (value.length === 0) {
199-
return z.array(z.any());
200-
}
201-
// Use the first element to determine the array type
202-
// eslint-disable-next-line no-underscore-dangle
203-
const elementSchema = VercelProvider._convertValueToZodSchema(value[0]);
204-
return z.array(elementSchema);
205-
}
206-
207-
if (typeof value === 'object') {
208-
const shape: Record<string, z.ZodSchema> = {};
209-
Object.entries(value).forEach(([key, val]) => {
210-
// eslint-disable-next-line no-underscore-dangle
211-
shape[key] = VercelProvider._convertValueToZodSchema(val);
212-
});
213-
return z.object(shape);
214-
}
215-
216-
// Fallback for any other type
217-
return z.any();
218-
}
219-
220172
/**
221173
* Create a Vercel AI model from an AI configuration.
222174
* This method creates a Vercel AI model based on the provider configuration.

0 commit comments

Comments
 (0)