MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / OpenRouterHandler

Class OpenRouterHandler

src/api/providers/openrouter.ts:141–683  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

139}
140
141export class OpenRouterHandler extends BaseProvider implements SingleCompletionHandler {
142 protected options: ApiHandlerOptions
143 private client: OpenAI
144 protected models: ModelRecord = {}
145 protected endpoints: ModelRecord = {}
146 private readonly providerName = "OpenRouter"
147 private currentReasoningDetails: any[] = []
148
149 constructor(options: ApiHandlerOptions) {
150 super()
151 this.options = options
152
153 const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1"
154 const apiKey = this.options.openRouterApiKey ?? "not-provided"
155
156 this.client = new OpenAI({ baseURL, apiKey, defaultHeaders: DEFAULT_HEADERS, timeout: this.timeoutMs })
157
158 // Load models asynchronously to populate cache before getModel() is called
159 this.loadDynamicModels().catch((error) => {
160 console.error("[OpenRouterHandler] Failed to load dynamic models:", error)
161 })
162 }
163
164 private async loadDynamicModels(): Promise<void> {
165 try {
166 const [models, endpoints] = await Promise.all([
167 getModels({ provider: "openrouter" }),
168 getModelEndpoints({
169 router: "openrouter",
170 modelId: this.options.openRouterModelId,
171 endpoint: this.options.openRouterSpecificProvider,
172 }),
173 ])
174
175 this.models = models
176 this.endpoints = endpoints
177 } catch (error) {
178 console.error("[OpenRouterHandler] Error loading dynamic models:", {
179 error: error instanceof Error ? error.message : String(error),
180 stack: error instanceof Error ? error.stack : undefined,
181 })
182 }
183 }
184
185 getReasoningDetails(): any[] | undefined {
186 return this.currentReasoningDetails.length > 0 ? this.currentReasoningDetails : undefined
187 }
188
189 /**
190 * Handle OpenRouter streaming error response and report to telemetry.
191 * OpenRouter may include metadata.raw with the actual upstream provider error.
192 * @param error The error object (not wrapped - receives the error directly)
193 */
194 private handleStreamingError(error: OpenRouterError, modelId: string, operation: string): never {
195 const rawString = error?.metadata?.raw
196 const parsedError = extractErrorFromMetadataRaw(rawString)
197 const rawErrorMessage = parsedError || error?.message || "Unknown error"
198

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected