(options: GenerateOptions<T>)
| 22 | } |
| 23 | |
| 24 | async generateObject<T>(options: GenerateOptions<T>): Promise<GenerateObjectResult<T>> { |
| 25 | const { |
| 26 | model, |
| 27 | schema, |
| 28 | prompt, |
| 29 | } = options; |
| 30 | |
| 31 | try { |
| 32 | // Primary attempt with main model |
| 33 | const result = await generateObject({ |
| 34 | model: getModel(model), |
| 35 | schema, |
| 36 | prompt, |
| 37 | maxTokens: getToolConfig(model).maxTokens, |
| 38 | temperature: getToolConfig(model).temperature, |
| 39 | }); |
| 40 | |
| 41 | this.tokenTracker.trackUsage(model, result.usage); |
| 42 | return result; |
| 43 | |
| 44 | } catch (error) { |
| 45 | // First fallback: Try manual JSON parsing of the error response |
| 46 | try { |
| 47 | const errorResult = await this.handleGenerateObjectError<T>(error); |
| 48 | this.tokenTracker.trackUsage(model, errorResult.usage); |
| 49 | return errorResult; |
| 50 | |
| 51 | } catch (parseError) { |
| 52 | // Second fallback: Try with fallback model if provided |
| 53 | const fallbackModel = getModel('fallback'); |
| 54 | if (NoObjectGeneratedError.isInstance(parseError)) { |
| 55 | const failedOutput = (parseError as any).text; |
| 56 | console.error(`${model} failed on object generation ${failedOutput} -> manual parsing failed again -> trying fallback model`, fallbackModel); |
| 57 | try { |
| 58 | const fallbackResult = await generateObject({ |
| 59 | model: fallbackModel, |
| 60 | schema, |
| 61 | prompt: `Extract the desired information from this text: \n ${failedOutput}`, |
| 62 | maxTokens: getToolConfig('fallback').maxTokens, |
| 63 | temperature: getToolConfig('fallback').temperature, |
| 64 | }); |
| 65 | |
| 66 | this.tokenTracker.trackUsage(model, fallbackResult.usage); |
| 67 | return fallbackResult; |
| 68 | } catch (fallbackError) { |
| 69 | // If fallback model also fails, try parsing its error response |
| 70 | return await this.handleGenerateObjectError<T>(fallbackError); |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | // If no fallback model or all attempts failed, throw the original error |
| 75 | throw error; |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | private async handleGenerateObjectError<T>(error: unknown): Promise<GenerateObjectResult<T>> { |
| 81 | if (NoObjectGeneratedError.isInstance(error)) { |
no test coverage detected