()
| 62 | function applyPdfFileParserPlugin(body, messages = []) { |
| 63 | if (!hasPdfContent(messages)) return; |
| 64 | body.plugins = [ |
| 65 | { |
| 66 | id: 'file-parser', |
| 67 | pdf: { |
| 68 | engine: 'mistral-ocr' |
| 69 | } |
| 70 | } |
| 71 | ]; |
| 72 | } |
| 73 | |
| 74 | export class OpenRouterAPI { |
| 75 | constructor(options = {}) { |
| 76 | this.options = options; |
| 77 | this.networkTransport = options.networkTransport || networkProxy; |
| 78 | this.baseUrl = 'https://openrouter.ai/api/v1'; |
| 79 | |
| 80 | // Load display name overrides from centralized config |
| 81 | const defaults = getDefaultModelConfig(); |
| 82 | this.displayNameOverrides = { ...defaults.displayNameOverrides }; |
| 83 | } |
| 84 | |
| 85 | |
| 86 | // Request-scoped leases isolate concurrent title/completion calls. Products |
| 87 | // own credential acquisition, budget policy and cleanup, not SSE parsing. |
| 88 | async withRequestAccess(token, options, operation) { |
| 89 | const access = this.options.acquireRequestAccess |
| 90 | ? await this.options.acquireRequestAccess(token, options) |
| 91 | : this.defaultRequestAccess(token); |
| 92 | try { |
| 93 | if (options.signal?.aborted) { |
| 94 | const error = new DOMException('The operation was aborted.', 'AbortError'); |
| 95 | error.isCancelled = true; |
| 96 | throw error; |
| 97 | } |
| 98 | const request = Object.create(this); |
| 99 | request._requestAccess = access; |
| 100 | request.baseUrl = access.baseUrl; |
| 101 | return await operation(request, access.apiKey || token); |
| 102 | } catch (error) { |
| 103 | this.options.onRequestError?.(error); |
| 104 | throw error; |
| 105 | } finally { |
| 106 | try { |
| 107 | await access.release?.(); |
| 108 | } finally { |
| 109 | // Refresh errors cannot turn a successful response into failure. |
| 110 | try { await this.options.onRequestFinished?.(); } catch { /* best effort */ } |
| 111 | } |
| 112 | } |
| 113 | } |
no test coverage detected