diff --git a/Dockerfile b/Dockerfile index 8d9d57b..d205a53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ COPY package*.json ./ # Install dependencies with development environment for building ENV NODE_ENV=development -RUN npm install --no-optional +RUN npm install --no-optional --verbose # Copy source code COPY . . diff --git a/src/model-cache.ts b/src/model-cache.ts index 72a29a7..17412ca 100644 --- a/src/model-cache.ts +++ b/src/model-cache.ts @@ -71,17 +71,17 @@ export class ModelCache { public searchModels(params: { query?: string; provider?: string; - minContextLength?: number; - maxContextLength?: number; - maxPromptPrice?: number; - maxCompletionPrice?: number; + minContextLength?: number | string; + maxContextLength?: number | string; + maxPromptPrice?: number | string; + maxCompletionPrice?: number | string; capabilities?: { functions?: boolean; tools?: boolean; vision?: boolean; json_mode?: boolean; }; - limit?: number; + limit?: number | string; }): any[] { let results = this.getAllModels(); @@ -103,32 +103,52 @@ export class ModelCache { } // Filter by context length - if (params.minContextLength) { - results = results.filter( - (model) => model.context_length >= params.minContextLength - ); + if (params.minContextLength !== undefined) { + const minContextLength = typeof params.minContextLength === 'string' + ? parseInt(params.minContextLength, 10) + : params.minContextLength; + if (!isNaN(minContextLength)) { + results = results.filter( + (model) => model.context_length >= minContextLength + ); + } } - if (params.maxContextLength) { - results = results.filter( - (model) => model.context_length <= params.maxContextLength - ); + if (params.maxContextLength !== undefined) { + const maxContextLength = typeof params.maxContextLength === 'string' + ? parseInt(params.maxContextLength, 10) + : params.maxContextLength; + if (!isNaN(maxContextLength)) { + results = results.filter( + (model) => model.context_length <= maxContextLength + ); + } } // Filter by price - if (params.maxPromptPrice) { - results = results.filter( - (model) => - !model.pricing?.prompt || model.pricing.prompt <= params.maxPromptPrice - ); + if (params.maxPromptPrice !== undefined) { + const maxPromptPrice = typeof params.maxPromptPrice === 'string' + ? parseFloat(params.maxPromptPrice) + : params.maxPromptPrice; + if (!isNaN(maxPromptPrice)) { + results = results.filter( + (model) => + !model.pricing?.prompt || model.pricing.prompt <= maxPromptPrice + ); + } } - if (params.maxCompletionPrice) { - results = results.filter( - (model) => - !model.pricing?.completion || - model.pricing.completion <= params.maxCompletionPrice - ); + if (params.maxCompletionPrice !== undefined) { + const maxCompletionPrice = typeof params.maxCompletionPrice === 'string' + ? parseFloat(params.maxCompletionPrice) + : params.maxCompletionPrice; + if (!isNaN(maxCompletionPrice)) { + results = results.filter( + (model) => + !model.pricing?.completion || + model.pricing.completion <= maxCompletionPrice + ); + } } // Filter by capabilities @@ -150,8 +170,13 @@ export class ModelCache { } // Apply limit - if (params.limit && params.limit > 0) { - results = results.slice(0, params.limit); + if (params.limit !== undefined) { + const limit = typeof params.limit === 'string' + ? parseInt(params.limit, 10) + : params.limit; + if (!isNaN(limit) && limit > 0) { + results = results.slice(0, limit); + } } return results; diff --git a/src/tool-handlers/search-models.ts b/src/tool-handlers/search-models.ts index 0a0a27c..7df65e4 100644 --- a/src/tool-handlers/search-models.ts +++ b/src/tool-handlers/search-models.ts @@ -4,17 +4,17 @@ import { OpenRouterAPIClient } from '../openrouter-api.js'; export interface SearchModelsToolRequest { query?: string; provider?: string; - minContextLength?: number; - maxContextLength?: number; - maxPromptPrice?: number; - maxCompletionPrice?: number; + minContextLength?: number | string; + maxContextLength?: number | string; + maxPromptPrice?: number | string; + maxCompletionPrice?: number | string; capabilities?: { functions?: boolean; tools?: boolean; vision?: boolean; json_mode?: boolean; }; - limit?: number; + limit?: number | string; } export async function handleSearchModels(