1- import axios from "axios"
2-
31import { RooModelsResponseSchema } from "@roo-code/types"
42
53import type { ModelRecord } from "../../../shared/api"
@@ -25,26 +23,34 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
2523 headers [ "Authorization" ] = `Bearer ${ apiKey } `
2624 }
2725
28- // Normalize the URL to ensure proper /v1/models endpoint construction
29- // Remove any trailing /v1 to avoid duplication
30- const urlObj = new URL ( baseUrl )
31- let pathname = urlObj . pathname . replace ( / \/ + $ / , "" ) . replace ( / \/ + / g, "/" )
32- // Remove trailing /v1 if present to avoid /v1/v1/models
33- if ( pathname . endsWith ( "/v1" ) ) {
34- pathname = pathname . slice ( 0 , - 3 )
26+ // Construct the models endpoint URL
27+ // Strip trailing /v1 if present to avoid /v1/v1/models
28+ const normalizedBase = baseUrl . endsWith ( "/v1" ) ? baseUrl . slice ( 0 , - 3 ) : baseUrl
29+ const url = `${ normalizedBase } /v1/models`
30+
31+ // Use fetch with AbortController for better timeout handling
32+ const controller = new AbortController ( )
33+ const timeoutId = setTimeout ( ( ) => controller . abort ( ) , 10000 )
34+
35+ const response = await fetch ( url , {
36+ headers,
37+ signal : controller . signal ,
38+ } )
39+
40+ clearTimeout ( timeoutId )
41+
42+ if ( ! response . ok ) {
43+ throw new Error ( `HTTP ${ response . status } : ${ response . statusText } ` )
3544 }
36- urlObj . pathname = pathname + "/v1/models"
37- const url = urlObj . href
3845
39- // Added timeout to prevent indefinite hanging
40- const response = await axios . get ( url , { headers, timeout : 10000 } )
46+ const data = await response . json ( )
4147 const models : ModelRecord = { }
4248
4349 // Validate response against schema
44- const parsed = RooModelsResponseSchema . safeParse ( response . data )
50+ const parsed = RooModelsResponseSchema . safeParse ( data )
4551
4652 if ( ! parsed . success ) {
47- console . error ( "Error fetching Roo Code Cloud models: Unexpected response format" , response . data )
53+ console . error ( "Error fetching Roo Code Cloud models: Unexpected response format" , data )
4854 console . error ( "Validation errors:" , parsed . error . format ( ) )
4955 throw new Error ( "Failed to fetch Roo Code Cloud models: Unexpected response format." )
5056 }
@@ -88,16 +94,24 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
8894 return models
8995 } catch ( error : any ) {
9096 console . error ( "Error fetching Roo Code Cloud models:" , error . message ? error . message : error )
91- if ( axios . isAxiosError ( error ) && error . response ) {
92- throw new Error (
93- `Failed to fetch Roo Code Cloud models: ${ error . response . status } ${ error . response . statusText } . Check base URL and API key.` ,
94- )
95- } else if ( axios . isAxiosError ( error ) && error . request ) {
97+
98+ // Handle abort/timeout
99+ if ( error . name === "AbortError" ) {
100+ throw new Error ( "Failed to fetch Roo Code Cloud models: Request timed out after 10 seconds." )
101+ }
102+
103+ // Handle fetch errors
104+ if ( error . message ?. includes ( "HTTP" ) ) {
105+ throw new Error ( `Failed to fetch Roo Code Cloud models: ${ error . message } . Check base URL and API key.` )
106+ }
107+
108+ // Handle network errors
109+ if ( error instanceof TypeError ) {
96110 throw new Error (
97111 "Failed to fetch Roo Code Cloud models: No response from server. Check Roo Code Cloud server status and base URL." ,
98112 )
99- } else {
100- throw new Error ( `Failed to fetch Roo Code Cloud models: ${ error . message || "An unknown error occurred." } ` )
101113 }
114+
115+ throw new Error ( `Failed to fetch Roo Code Cloud models: ${ error . message || "An unknown error occurred." } ` )
102116 }
103117}
0 commit comments