1- import { generateObject , generateText , LanguageModel } from 'ai' ;
2- import { z } from 'zod' ;
1+ import { generateObject , generateText , jsonSchema , LanguageModel } from 'ai' ;
32
43import { AIProvider } from '@launchdarkly/server-sdk-ai' ;
54import 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