-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add model mapping configuration #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…names - Add model-mapping.json for official model name mappings - Add custom-mapping.json for custom model name mappings - Update CLI and service files to support model mapping configuration - Add config directory with modelMapping.ts for type definitions
WalkthroughAdds configurable model-name mapping support. Introduces a mapping config file (default: model-mapping.json), a loader and lookup utilities, CLI option to specify config, startup loading, and usage of mapped names across logs, OpenAI model listing, and Anthropic/Gemini model resolution. Updates docs and adds example mapping files. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User as User
participant CLI/Server as CLI / Server
participant Mapping as ModelMapping
participant Services as OpenAI/Anthropic/Gemini
rect rgb(236,248,255)
note over CLI/Server,Mapping: Startup
CLI/Server->>Mapping: loadModelMapping(configPath | env | default)
Mapping-->>CLI/Server: mappings loaded (idempotent)
CLI/Server->>Mapping: getMappedModelName(...) for display
Mapping-->>CLI/Server: mapped names
end
rect rgb(244,240,255)
note over User,Services: Request handling
User->>CLI/Server: List/Use model (modelId)
CLI/Server->>Mapping: getMappedModelName(modelId)
Mapping-->>CLI/Server: mappedId (or original)
CLI/Server->>Services: findModelById(mappedId)
Services-->>CLI/Server: model (if found)
CLI/Server-->>User: Response (ids reflect mapped names)
end
alt Model not found via direct id
CLI/Server->>Mapping: getOriginalModelName(modelId)
Mapping-->>CLI/Server: originalId or undefined
CLI/Server->>Services: fallback lookup using original/mapped
Services-->>CLI/Server: result or not found
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (11)
custom-mapping.json (1)
1-11: Add missing alias for parity with default mapping.Default mapping includes "mock-gpt-thinking-tag". For consistency and fewer surprises when users switch configs, mirror that alias here.
{ "mock-gpt-thinking": "custom-gpt-mini", + "mock-gpt-thinking-tag": "custom-gpt-mini", "gpt-4-mock": "custom-gpt-pro", "mock-gpt-markdown": "custom-gpt-markdown", "gpt-4o-image": "custom-dalle", "mock-claude-markdown": "custom-claude-pro", "gemini-1.5-pro": "custom-gemini-pro", "gemini-1.5-flash": "custom-gemini-flash", "gemini-pro": "custom-gemini-basic", "gemini-pro-vision": "custom-gemini-vision" }README.md (1)
489-517: Document precedence (CLI vs env) and fix minor grammar.
- Clarify that -c/--config overrides MODEL_MAPPING_CONFIG.
- Tweak “better user experience” → “a better user experience”.
-You can customize the model names displayed to users by creating a `model-mapping.json` file. This allows you to map internal model names to external names for better user experience. +You can customize the model names displayed to users by creating a `model-mapping.json` file. This allows you to map internal model names to external names for a better user experience. + +Note: +- The CLI option `-c/--config` takes precedence over the `MODEL_MAPPING_CONFIG` environment variable. +- Relative paths are resolved from the server's current working directory.model-mapping.json (1)
1-12: LGTM; consider staleness note for time-stamped targets.Mappings look consistent. Some targets (e.g., gemini-2.0-*-exp-2025-01-15) are time-stamped and may go stale; keeping them in an example/default file is fine, but consider a brief README note that these are illustrative and can be customized.
src/config/modelMapping.ts (2)
11-19: Use absolute path in logs for clarity.Helpful when the server is launched from an unexpected CWD.
-const CONFIG_FILE_PATH = process.env.MODEL_MAPPING_CONFIG || path.join(process.cwd(), 'model-mapping.json'); +const CONFIG_FILE_PATH = + process.env.MODEL_MAPPING_CONFIG + ? path.resolve(process.env.MODEL_MAPPING_CONFIG) + : path.resolve(process.cwd(), 'model-mapping.json');
50-52: Optional: cache reverse lookup for O(1) original-name queries.
getOriginalModelNameis O(n). If called frequently, build a reverse index when loading.src/cli.ts (1)
32-43: Log only when mappings are actually loaded.If loading fails or file is absent, printing a config path can imply success. Consider conditionally logging mapping count using
hasMappings().- console.log(` • Config file: ${options.config}`); + // Display config path only when mappings are present + try { + const { hasMappings } = await import('./config/modelMapping'); + if (hasMappings()) { + console.log(` • Config file: ${options.config}`); + } + } catch { + // no-op + }src/services/openaiService.ts (1)
846-856: Image model special-case ignores mapped namesIf gpt-4o-image is mapped (e.g., to "dall-e-3"), the current check won't match and the special image branch won't run. Import the reverse lookup and compare against the original ID.
Apply this diff within existing imports:
-import { getMappedModelName } from "../config/modelMapping"; +import { getMappedModelName, getOriginalModelName } from "../config/modelMapping";And update generateImage (outside the changed hunk) like this:
// inside generateImage(...) const model = request.model || "gpt-4o-image"; const originalModel = getOriginalModelName(model) ?? model; let imageUrls = mockImageUrls; if (originalModel === "gpt-4o-image") { imageUrls = [ImgData]; }Also applies to: 851-855
README.zh.md (1)
329-360: Clarify that requests accept both original and mapped model namesAdd one sentence so users know inbound requests can use either name.
服务器将自动加载配置并在控制台输出和 API 响应中显示映射后的模型名称。 + 同时,请求参数中的 `model` 可使用“原始名称”或“映射后名称”,服务会自动解析。src/utils/helpers.ts (1)
3-3: Lookup order is solid; consider centralizing to avoid driftThe direct → reverse → forward resolution sequence is correct and future‑proof.
To prevent the Gemini/Anthropic helpers from diverging, extract this resolution into a shared utility (e.g., resolveModelIdToInternal) and reuse it there.
Also applies to: 30-46
src/index.ts (2)
31-41: DRY the model list logging with a small table + loop.Reduces duplication and guarantees future additions automatically go through
getMappedModelName.console.log(`\n✨ Available models:`); console.log(` OpenAI Compatible:`); - console.log(` - ${getMappedModelName('mock-gpt-thinking')}: Model supporting thought process`); - console.log(` - ${getMappedModelName('gpt-4-mock')}: Model supporting function calls with tool calls format`); - console.log(` - ${getMappedModelName('mock-gpt-markdown')}: Model outputting standard Markdown`); - console.log(` - ${getMappedModelName('gpt-4o-image')}: Model specifically for image generation`); + const openAIModels: Array<[string, string]> = [ + ['mock-gpt-thinking', 'Model supporting thought process'], + ['gpt-4-mock', 'Model supporting function calls with tool calls format'], + ['mock-gpt-markdown', 'Model outputting standard Markdown'], + ['gpt-4o-image', 'Model specifically for image generation'], + ]; + for (const [id, desc] of openAIModels) { + console.log(` - ${getMappedModelName(id)}: ${desc}`); + } console.log(` Anthropic Compatible:`); - console.log(` - ${getMappedModelName('mock-claude-markdown')}: Claude markdown sample model`); + const anthropicModels: Array<[string, string]> = [ + ['mock-claude-markdown', 'Claude markdown sample model'], + ]; + for (const [id, desc] of anthropicModels) { + console.log(` - ${getMappedModelName(id)}: ${desc}`); + } console.log(` Gemini Compatible:`); - console.log(` - ${getMappedModelName('gemini-1.5-pro')}: Advanced multimodal AI model`); - console.log(` - ${getMappedModelName('gemini-1.5-flash')}: Fast and efficient model`); - console.log(` - ${getMappedModelName('gemini-pro')}: Versatile model for various tasks`); - console.log(` - ${getMappedModelName('gemini-pro-vision')}: Multimodal model for text and images`); + const geminiModels: Array<[string, string]> = [ + ['gemini-1.5-pro', 'Advanced multimodal AI model'], + ['gemini-1.5-flash', 'Fast and efficient model'], + ['gemini-pro', 'Versatile model for various tasks'], + ['gemini-pro-vision', 'Multimodal model for text and images'], + ]; + for (const [id, desc] of geminiModels) { + console.log(` - ${getMappedModelName(id)}: ${desc}`); + }
15-18: Bind to HOST when starting the server (log matches actual bind address).You log
HOSTbutapp.listendoesn’t use it; pass it to avoid confusion in environments using a non-default host.-app.listen(PORT, () => { +app.listen(PORT, HOST, () => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (11)
README.md(1 hunks)README.zh.md(1 hunks)custom-mapping.json(1 hunks)model-mapping.json(1 hunks)src/cli.ts(4 hunks)src/config/modelMapping.ts(1 hunks)src/index.ts(2 hunks)src/services/openaiService.ts(1 hunks)src/utils/anthropicHelpers.ts(2 hunks)src/utils/geminiHelpers.ts(2 hunks)src/utils/helpers.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
src/services/openaiService.ts (3)
src/types/index.ts (2)
ModelsResponse(10-13)Model(3-8)src/data/mockData.ts (1)
mockModels(7-48)src/config/modelMapping.ts (1)
getMappedModelName(46-48)
src/utils/geminiHelpers.ts (2)
src/config/modelMapping.ts (1)
getMappedModelName(46-48)src/data/geminiMockData.ts (1)
geminiMockModels(4-33)
src/utils/anthropicHelpers.ts (2)
src/config/modelMapping.ts (1)
getMappedModelName(46-48)src/data/anthropicMockData.ts (1)
anthropicMockModels(4-12)
src/cli.ts (1)
src/config/modelMapping.ts (2)
loadModelMapping(13-44)getMappedModelName(46-48)
src/index.ts (1)
src/config/modelMapping.ts (2)
loadModelMapping(13-44)getMappedModelName(46-48)
src/utils/helpers.ts (2)
src/data/mockData.ts (1)
mockModels(7-48)src/config/modelMapping.ts (2)
getOriginalModelName(50-52)getMappedModelName(46-48)
🪛 LanguageTool
README.md
[grammar] ~491-~491: There might be a mistake here.
Context: ... internal model names to external names for better user experience. **Example mode...
(QB_NEW_EN)
🔇 Additional comments (6)
src/cli.ts (2)
21-22: Good addition of --config; ensure README table is updated.The flag is correctly wired with a sensible default. Sync docs to avoid drift.
56-67: Nice touch mapping displayed model IDs.Keeps console output aligned with configured aliases.
src/services/openaiService.ts (1)
21-21: Model listing uses mapped IDs — good integrationReturning mapped IDs in /v1/models aligns responses with the configured mapping and remains compatible with downstream lookups.
Also applies to: 28-28
src/index.ts (3)
4-4: LGTM: correct imports from mapping module.
46-46: Usage example correctly reflects mapped names.Good call using
getMappedModelName('gpt-4-mock')so the sample always matches the configured alias.
12-14: Eager load concern is invalid – src/cli.ts never imports src/index.ts, so loadModelMapping(options.config) always runs first and respects the custom config path.Likely an incorrect or invalid review comment.
| ### Model Mapping Configuration | ||
|
|
||
| You can customize the model names displayed to users by creating a `model-mapping.json` file. This allows you to map internal model names to external names for better user experience. | ||
|
|
||
| **Example model-mapping.json:** | ||
| ```json | ||
| { | ||
| "mock-gpt-thinking": "gpt-4o-mini", | ||
| "gpt-4-mock": "gpt-4-turbo", | ||
| "mock-gpt-markdown": "gpt-4o", | ||
| "gpt-4o-image": "dall-e-3", | ||
| "mock-claude-markdown": "claude-3-opus-20240229", | ||
| "gemini-1.5-pro": "gemini-2.0-pro-exp-2025-01-15", | ||
| "gemini-1.5-flash": "gemini-2.0-flash-exp-2025-01-15", | ||
| "gemini-pro": "gemini-pro-1.0", | ||
| "gemini-pro-vision": "gemini-pro-vision-1.0" | ||
| } | ||
| ``` | ||
|
|
||
| **CLI Usage:** | ||
| ```bash | ||
| # Use custom model mapping configuration | ||
| npx mock-openai-api -c custom-mapping.json | ||
|
|
||
| # Or set via environment variable | ||
| MODEL_MAPPING_CONFIG=custom-mapping.json npx mock-openai-api | ||
| ``` | ||
|
|
||
| The server will automatically load the configuration and display mapped model names in the console output and API responses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the CLI options table to include --config.
The new option exists in src/cli.ts but is missing from the README table; users will miss it.
-| Option | Short | Description | Default |
-| ------------------ | ----- | --------------------------------- | --------- |
-| `--port <number>` | `-p` | Server port | `3000` |
-| `--host <address>` | `-H` | Server host address | `0.0.0.0` |
-| `--verbose` | `-v` | Enable request logging to console | `false` |
-| `--version` | | Show version number | |
-| `--help` | | Show help information | |
+| Option | Short | Description | Default |
+| -------------------- | ----- | --------------------------------------- | --------------------- |
+| `--port <number>` | `-p` | Server port | `3000` |
+| `--host <address>` | `-H` | Server host address | `0.0.0.0` |
+| `--verbose` | `-v` | Enable request logging to console | `false` |
+| `--config <path>` | `-c` | Path to model mapping config file | `./model-mapping.json`|
+| `--version` | | Show version number | |
+| `--help` | | Show help information | |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Model Mapping Configuration | |
| You can customize the model names displayed to users by creating a `model-mapping.json` file. This allows you to map internal model names to external names for better user experience. | |
| **Example model-mapping.json:** | |
| ```json | |
| { | |
| "mock-gpt-thinking": "gpt-4o-mini", | |
| "gpt-4-mock": "gpt-4-turbo", | |
| "mock-gpt-markdown": "gpt-4o", | |
| "gpt-4o-image": "dall-e-3", | |
| "mock-claude-markdown": "claude-3-opus-20240229", | |
| "gemini-1.5-pro": "gemini-2.0-pro-exp-2025-01-15", | |
| "gemini-1.5-flash": "gemini-2.0-flash-exp-2025-01-15", | |
| "gemini-pro": "gemini-pro-1.0", | |
| "gemini-pro-vision": "gemini-pro-vision-1.0" | |
| } | |
| ``` | |
| **CLI Usage:** | |
| ```bash | |
| # Use custom model mapping configuration | |
| npx mock-openai-api -c custom-mapping.json | |
| # Or set via environment variable | |
| MODEL_MAPPING_CONFIG=custom-mapping.json npx mock-openai-api | |
| ``` | |
| The server will automatically load the configuration and display mapped model names in the console output and API responses. | |
| | Option | Short | Description | Default | | |
| | -------------------- | ----- | --------------------------------------- | --------------------- | | |
| | `--port <number>` | `-p` | Server port | `3000` | | |
| | `--host <address>` | `-H` | Server host address | `0.0.0.0` | | |
| | `--verbose` | `-v` | Enable request logging to console | `false` | | |
| | `--config <path>` | `-c` | Path to model mapping config file | `./model-mapping.json`| | |
| | `--version` | | Show version number | | | |
| | `--help` | | Show help information | | |
🧰 Tools
🪛 LanguageTool
[grammar] ~491-~491: There might be a mistake here.
Context: ... internal model names to external names for better user experience. **Example mode...
(QB_NEW_EN)
🤖 Prompt for AI Agents
In README.md around lines 489 to 517, the CLI options table is missing the new
--config option introduced in src/cli.ts; add a table row describing --config
(and its short form if present), a concise description like "Path to custom
model-mapping JSON file", the default behavior, and an example usage line
showing npx mock-openai-api -c custom-mapping.json (and the equivalent
environment variable usage). Ensure the table formatting matches the existing
CLI options table style and that the example references MODEL_MAPPING_CONFIG as
shown elsewhere.
| export function loadModelMapping(configPath?: string): void { | ||
| if (configLoaded) { | ||
| return; | ||
| } | ||
|
|
||
| const configFilePath = configPath || CONFIG_FILE_PATH; | ||
|
|
||
| try { | ||
| if (fs.existsSync(configFilePath)) { | ||
| const configContent = fs.readFileSync(configFilePath, 'utf-8'); | ||
| const config = JSON.parse(configContent); | ||
|
|
||
| if (typeof config === 'object' && config !== null) { | ||
| modelMapping = config; | ||
| console.log(`✅ Loaded model mapping configuration from ${configFilePath}`); | ||
| console.log(`📋 Model mappings: ${Object.keys(modelMapping).length} mappings configured`); | ||
|
|
||
| if (Object.keys(modelMapping).length > 0) { | ||
| Object.entries(modelMapping).forEach(([original, mapped]) => { | ||
| console.log(` • ${original} → ${mapped}`); | ||
| }); | ||
| } | ||
| } | ||
| } else { | ||
| console.log(`ℹ️ No model mapping configuration found at ${configFilePath}`); | ||
| } | ||
| } catch (error) { | ||
| console.error(`❌ Failed to load model mapping configuration: ${error}`); | ||
| } | ||
|
|
||
| configLoaded = true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t set configLoaded=true on failure; allows second attempt with another path.
If the first call points to a non-existent or invalid file, configLoaded is still set to true, blocking subsequent loads (e.g., a later call with a valid default path). Move the flag to the successful load path.
export function loadModelMapping(configPath?: string): void {
if (configLoaded) {
return;
}
const configFilePath = configPath || CONFIG_FILE_PATH;
try {
if (fs.existsSync(configFilePath)) {
const configContent = fs.readFileSync(configFilePath, 'utf-8');
const config = JSON.parse(configContent);
- if (typeof config === 'object' && config !== null) {
- modelMapping = config;
+ if (typeof config === 'object' && config !== null) {
+ modelMapping = config;
console.log(`✅ Loaded model mapping configuration from ${configFilePath}`);
console.log(`📋 Model mappings: ${Object.keys(modelMapping).length} mappings configured`);
if (Object.keys(modelMapping).length > 0) {
Object.entries(modelMapping).forEach(([original, mapped]) => {
console.log(` • ${original} → ${mapped}`);
});
}
+ configLoaded = true;
}
} else {
console.log(`ℹ️ No model mapping configuration found at ${configFilePath}`);
}
} catch (error) {
console.error(`❌ Failed to load model mapping configuration: ${error}`);
}
-
- configLoaded = true;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function loadModelMapping(configPath?: string): void { | |
| if (configLoaded) { | |
| return; | |
| } | |
| const configFilePath = configPath || CONFIG_FILE_PATH; | |
| try { | |
| if (fs.existsSync(configFilePath)) { | |
| const configContent = fs.readFileSync(configFilePath, 'utf-8'); | |
| const config = JSON.parse(configContent); | |
| if (typeof config === 'object' && config !== null) { | |
| modelMapping = config; | |
| console.log(`✅ Loaded model mapping configuration from ${configFilePath}`); | |
| console.log(`📋 Model mappings: ${Object.keys(modelMapping).length} mappings configured`); | |
| if (Object.keys(modelMapping).length > 0) { | |
| Object.entries(modelMapping).forEach(([original, mapped]) => { | |
| console.log(` • ${original} → ${mapped}`); | |
| }); | |
| } | |
| } | |
| } else { | |
| console.log(`ℹ️ No model mapping configuration found at ${configFilePath}`); | |
| } | |
| } catch (error) { | |
| console.error(`❌ Failed to load model mapping configuration: ${error}`); | |
| } | |
| configLoaded = true; | |
| } | |
| export function loadModelMapping(configPath?: string): void { | |
| if (configLoaded) { | |
| return; | |
| } | |
| const configFilePath = configPath || CONFIG_FILE_PATH; | |
| try { | |
| if (fs.existsSync(configFilePath)) { | |
| const configContent = fs.readFileSync(configFilePath, 'utf-8'); | |
| const config = JSON.parse(configContent); | |
| if (typeof config === 'object' && config !== null) { | |
| modelMapping = config; | |
| console.log(`✅ Loaded model mapping configuration from ${configFilePath}`); | |
| console.log(`📋 Model mappings: ${Object.keys(modelMapping).length} mappings configured`); | |
| if (Object.keys(modelMapping).length > 0) { | |
| Object.entries(modelMapping).forEach(([original, mapped]) => { | |
| console.log(` • ${original} → ${mapped}`); | |
| }); | |
| } | |
| configLoaded = true; | |
| } | |
| } else { | |
| console.log(`ℹ️ No model mapping configuration found at ${configFilePath}`); | |
| } | |
| } catch (error) { | |
| console.error(`❌ Failed to load model mapping configuration: ${error}`); | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/config/modelMapping.ts around lines 13 to 44, configLoaded is currently
set to true unconditionally at the end of the function which prevents retrying
with another path after a failed or missing config load; move the assignment so
it only runs after a successful parse and assignment of modelMapping (i.e.,
after modelMapping = config and successful logs), and remove the unconditional
configLoaded = true from the function exit so that if the file is missing or
JSON parsing throws, subsequent calls can attempt loading again.
| try { | ||
| if (fs.existsSync(configFilePath)) { | ||
| const configContent = fs.readFileSync(configFilePath, 'utf-8'); | ||
| const config = JSON.parse(configContent); | ||
|
|
||
| if (typeof config === 'object' && config !== null) { | ||
| modelMapping = config; | ||
| console.log(`✅ Loaded model mapping configuration from ${configFilePath}`); | ||
| console.log(`📋 Model mappings: ${Object.keys(modelMapping).length} mappings configured`); | ||
|
|
||
| if (Object.keys(modelMapping).length > 0) { | ||
| Object.entries(modelMapping).forEach(([original, mapped]) => { | ||
| console.log(` • ${original} → ${mapped}`); | ||
| }); | ||
| } | ||
| } | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Validate mapping shape; reject/skip non-string values to avoid runtime surprises.
Currently any JSON object is accepted. Guard against arrays and non-string values; log warnings for skipped entries.
- if (typeof config === 'object' && config !== null) {
- modelMapping = config;
+ if (typeof config === 'object' && config !== null && !Array.isArray(config)) {
+ const next: ModelMappingConfig = {};
+ for (const [k, v] of Object.entries(config as Record<string, unknown>)) {
+ if (typeof k === 'string' && typeof v === 'string') {
+ next[k] = v;
+ } else {
+ console.warn(`⚠️ Skipping invalid mapping entry: ${String(k)} → ${String(v)}`);
+ }
+ }
+ modelMapping = next;🤖 Prompt for AI Agents
In src/config/modelMapping.ts around lines 20 to 36, the code currently accepts
any JSON object as modelMapping which can include arrays or non-string values;
update the loader to validate the mapping shape by ensuring the parsed config is
an object whose keys map to string values only, skip or reject any entries where
the mapped value is not a string (or where a value is an array/object), and log
a warning for each skipped entry including the key and the unexpected type; set
modelMapping to the filtered object (or empty if none valid) and keep the
existing success logs but report the count of valid mappings.
| import { MockModel } from "../types/index"; | ||
| import { anthropicMockModels } from "../data/anthropicMockData"; | ||
| import { ErrorResponse, StreamingEvent } from "../types/anthropic"; | ||
| import { getMappedModelName } from "../config/modelMapping"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anthropic model lookup also uses the wrong mapping direction
Same issue as Gemini: external IDs won’t resolve. Switch to reverse lookup first, keep direct and forward as fallbacks.
-import { getMappedModelName } from "../config/modelMapping";
+import { getMappedModelName, getOriginalModelName } from "../config/modelMapping";
@@
export function findModelById(modelId: string): MockModel | undefined {
- const mappedModelId = getMappedModelName(modelId);
- return anthropicMockModels.find(model => model.id === mappedModelId);
+ // 1) direct
+ const direct = anthropicMockModels.find(model => model.id === modelId);
+ if (direct) return direct;
+ // 2) external -> internal
+ const originalId = getOriginalModelName(modelId);
+ if (originalId) return anthropicMockModels.find(model => model.id === originalId);
+ // 3) internal -> external (unlikely to hit)
+ const mappedId = getMappedModelName(modelId);
+ return anthropicMockModels.find(model => model.id === mappedId);
}Also applies to: 31-33
🤖 Prompt for AI Agents
In src/utils/anthropicHelpers.ts around lines 4 and 31-33, the model lookup uses
the wrong mapping direction causing external IDs not to resolve; change the
lookup order to attempt a reverse mapping lookup first (map external ID ->
internal name), then fall back to the existing direct lookup, and finally the
forward mapping as last resort, returning the resolved internal model name;
update any helper functions or calls in those lines to perform reverse lookup
first and keep the current direct/forward logic as fallbacks.
| @@ -1,4 +1,5 @@ | |||
| import { geminiMockModels } from '../data/geminiMockData'; | |||
| import { getMappedModelName } from '../config/modelMapping'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong mapping direction causes lookups to fail for external names
getMappedModelName maps internal->external. For requests that send external (mapped) IDs, this returns the external again, so the lookup misses. Use getOriginalModelName first, with sensible fallbacks.
-import { getMappedModelName } from '../config/modelMapping';
+import { getMappedModelName, getOriginalModelName } from '../config/modelMapping';
@@
export function findGeminiModelById(modelId: string) {
// Remove 'models/' prefix if present
const cleanModelId = modelId.replace('models/', '');
- const mappedModelId = getMappedModelName(cleanModelId);
- return geminiMockModels.find(model => model.id === mappedModelId);
+ // 1) direct hit
+ const direct = geminiMockModels.find(model => model.id === cleanModelId);
+ if (direct) return direct;
+ // 2) external -> internal
+ const originalId = getOriginalModelName(cleanModelId);
+ if (originalId) return geminiMockModels.find(model => model.id === originalId);
+ // 3) last resort: internal -> external (unlikely to match, but harmless)
+ const mappedId = getMappedModelName(cleanModelId);
+ return geminiMockModels.find(model => model.id === mappedId);
}Also applies to: 33-35
🤖 Prompt for AI Agents
In src/utils/geminiHelpers.ts around lines 2 and also affecting lines 33-35, the
code imports and uses getMappedModelName (which maps internal->external) when
handling incoming external/mapped IDs, causing lookups to fail; change the logic
to call getOriginalModelName first to translate external names back to internal
names (with sensible fallbacks to the incoming value if no mapping exists), and
only use getMappedModelName where you need to produce external names for
outgoing responses; update any conditional branches on lines 33-35 to attempt
getOriginalModelName(inputName) before using getMappedModelName so lookups use
internal model names.
#17
Summary by CodeRabbit
New Features
Documentation