1- import axios from "axios"
1+ import axios from "axios"
22
33import type { ModelInfo } from "@roo-code/types"
44
55import type { ApiHandlerOptions } from "../../../shared/api"
66import { getCachedZooCodeToken , getZooCodeBaseUrl } from "../../../services/zoo-code-auth"
77
8- // Reuse the same schemas and parsing logic from vercel-ai-gateway since the API format is identical
9- import { type VercelAiGatewayModel , parseVercelAiGatewayModel } from "./vercel-ai-gateway"
10-
11- import { z } from "zod"
12-
13- /**
14- * ZooGatewayPricing (same format as Vercel AI Gateway)
15- */
16-
17- const zooGatewayPricingSchema = z . object ( {
18- input : z . string ( ) . optional ( ) ,
19- output : z . string ( ) . optional ( ) ,
20- input_cache_write : z . string ( ) . optional ( ) ,
21- input_cache_read : z . string ( ) . optional ( ) ,
22- image : z . string ( ) . optional ( ) ,
23- } )
24-
25- /**
26- * ZooGatewayModel (same format as Vercel AI Gateway)
27- */
28-
29- const zooGatewayModelSchema = z . object ( {
30- id : z . string ( ) ,
31- object : z . string ( ) ,
32- created : z . number ( ) ,
33- owned_by : z . string ( ) ,
34- name : z . string ( ) ,
35- description : z . string ( ) ,
36- context_window : z . number ( ) ,
37- max_tokens : z . number ( ) ,
38- type : z . string ( ) ,
39- pricing : zooGatewayPricingSchema ,
40- } )
41-
42- /**
43- * ZooGatewayModelsResponse
44- */
45-
46- const zooGatewayModelsResponseSchema = z . object ( {
47- object : z . string ( ) ,
48- data : z . array ( zooGatewayModelSchema ) ,
49- } )
50-
51- type ZooGatewayModelsResponse = z . infer < typeof zooGatewayModelsResponseSchema >
8+ import {
9+ type VercelAiGatewayModel ,
10+ parseVercelAiGatewayModel ,
11+ vercelAiGatewayModelsResponseSchema ,
12+ } from "./vercel-ai-gateway"
5213
5314// Bound model discovery so a network stall can't hang provider initialization paths.
5415const MODEL_DISCOVERY_TIMEOUT_MS = 15_000
@@ -72,21 +33,18 @@ export async function getZooGatewayModels(options?: ApiHandlerOptions): Promise<
7233 }
7334
7435 try {
75- const response = await axios . get < ZooGatewayModelsResponse > ( `${ baseURL } /models` , {
36+ const response = await axios . get ( `${ baseURL } /models` , {
7637 headers,
7738 timeout : MODEL_DISCOVERY_TIMEOUT_MS ,
7839 } )
79- const result = zooGatewayModelsResponseSchema . safeParse ( response . data )
80-
81- // Fall back to the raw response only when it looks structurally sound; otherwise return
82- // an empty list rather than crashing on `response.data.data` being undefined.
83- const data = result . success ? result . data . data : Array . isArray ( response . data ?. data ) ? response . data . data : [ ]
40+ const result = vercelAiGatewayModelsResponseSchema . safeParse ( response . data )
8441
8542 if ( ! result . success ) {
8643 console . error ( `Zoo Gateway models response is invalid ${ JSON . stringify ( result . error . format ( ) ) } ` )
44+ return models
8745 }
8846
89- for ( const model of data ) {
47+ for ( const model of result . data . data ) {
9048 const { id } = model
9149
9250 // Only include language models for chat inference.
@@ -95,8 +53,7 @@ export async function getZooGatewayModels(options?: ApiHandlerOptions): Promise<
9553 continue
9654 }
9755
98- // Parse model using the same logic as Vercel AI Gateway since formats are identical
99- models [ id ] = parseZooGatewayModel ( { id, model : model as VercelAiGatewayModel } )
56+ models [ id ] = parseZooGatewayModel ( { id, model } )
10057 }
10158 } catch ( error ) {
10259 // Log only safe fields; never serialize the full error object because it
@@ -123,6 +80,5 @@ export async function getZooGatewayModels(options?: ApiHandlerOptions): Promise<
12380 */
12481
12582export const parseZooGatewayModel = ( { id, model } : { id : string ; model : VercelAiGatewayModel } ) : ModelInfo => {
126- // Reuse the parsing logic from vercel-ai-gateway
12783 return parseVercelAiGatewayModel ( { id, model } )
12884}
0 commit comments