mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-04-28 06:19:46 +00:00
feat(cli): derive Claude CLI model defaults from provider registry dynamically (#1393)
Integrated into release/v3.6.9
This commit is contained in:
parent
01ae037205
commit
891189bbf3
6 changed files with 78 additions and 11 deletions
18
CLAUDE.md
18
CLAUDE.md
|
|
@ -6,13 +6,15 @@
|
|||
## Quick Start
|
||||
|
||||
```bash
|
||||
npm install # Install deps (auto-generates .env from .env.example)
|
||||
npm run dev # Dev server at http://localhost:20128
|
||||
npm run build # Production build (Next.js 16 standalone)
|
||||
npm run lint # ESLint (0 errors expected; warnings are pre-existing)
|
||||
npm run typecheck:core # TypeScript check (should be clean)
|
||||
npm run test:coverage # Unit tests + coverage gate (60% min)
|
||||
npm run check # lint + test combined
|
||||
npm install # Install deps (auto-generates .env from .env.example)
|
||||
npm run dev # Dev server at http://localhost:20128
|
||||
npm run build # Production build (Next.js 16 standalone)
|
||||
npm run lint # ESLint (0 errors expected; warnings are pre-existing)
|
||||
npm run typecheck:core # TypeScript check (should be clean)
|
||||
npm run typecheck:noimplicit:core # Strict check (no implicit any)
|
||||
npm run test:coverage # Unit tests + coverage gate (60% min)
|
||||
npm run check # lint + test combined
|
||||
npm run check:cycles # Detect circular dependencies
|
||||
```
|
||||
|
||||
### Running a Single Test
|
||||
|
|
@ -172,6 +174,8 @@ Client → /v1/chat/completions (Next.js route)
|
|||
**PR rule**: If you change production code in `src/`, `open-sse/`, `electron/`, or `bin/`,
|
||||
you must include or update tests in the same PR.
|
||||
|
||||
**Test layer preference**: unit first → integration (multi-module or DB state) → e2e (UI/workflow only). Encode bug reproductions as automated tests before or alongside the fix.
|
||||
|
||||
---
|
||||
|
||||
## Git Workflow
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ RUN apt-get update \
|
|||
|
||||
COPY package*.json ./
|
||||
COPY scripts/postinstall.mjs ./scripts/postinstall.mjs
|
||||
COPY scripts/postinstallSupport.mjs ./scripts/postinstallSupport.mjs
|
||||
COPY scripts/native-binary-compat.mjs ./scripts/native-binary-compat.mjs
|
||||
COPY scripts/postinstallSupport.mjs ./scripts/postinstallSupport.mjs
|
||||
RUN if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi
|
||||
|
|
|
|||
|
|
@ -2149,3 +2149,22 @@ export function getProviderCategory(provider: string): "oauth" | "apikey" {
|
|||
if (!entry) return "apikey"; // Safe default for unknown providers
|
||||
return entry.authType === "apikey" ? "apikey" : "oauth";
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the latest opus/sonnet/haiku model IDs from the `claude` registry entry.
|
||||
* Picks the first model whose ID matches each family pattern — registry order
|
||||
* determines precedence, so newer models should be listed first.
|
||||
*/
|
||||
export function getClaudeCodeDefaultModels(): {
|
||||
opus: string;
|
||||
sonnet: string;
|
||||
haiku: string;
|
||||
} {
|
||||
const models = REGISTRY.claude?.models ?? [];
|
||||
const find = (pattern: RegExp) => models.find((m) => pattern.test(m.id))?.id ?? "";
|
||||
return {
|
||||
opus: find(/opus/i),
|
||||
sonnet: find(/sonnet/i),
|
||||
haiku: find(/haiku/i),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ export default function ClaudeToolCard({
|
|||
}
|
||||
|
||||
tool.defaultModels.forEach((model) => {
|
||||
const targetModel = modelMappings[model.alias];
|
||||
const targetModel = modelMappings[model.alias] || model.defaultValue || "";
|
||||
if (targetModel && model.envKey) env[model.envKey] = targetModel;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
// CLI Tools configuration
|
||||
import { getClaudeCodeDefaultModels } from "@omniroute/open-sse/config/providerRegistry";
|
||||
|
||||
const _cc = getClaudeCodeDefaultModels();
|
||||
|
||||
export const CLI_TOOLS = {
|
||||
claude: {
|
||||
id: "claude",
|
||||
|
|
@ -19,26 +23,42 @@ export const CLI_TOOLS = {
|
|||
settingsFile: "~/.claude/settings.json",
|
||||
defaultCommand: "claude",
|
||||
defaultModels: [
|
||||
{
|
||||
id: "model",
|
||||
name: "Default Model",
|
||||
alias: "model",
|
||||
envKey: "ANTHROPIC_MODEL",
|
||||
defaultValue: _cc.sonnet ? `cc/${_cc.sonnet}` : "cc/claude-sonnet-4-5-20250929",
|
||||
isTopLevel: true,
|
||||
},
|
||||
{
|
||||
id: "smallFast",
|
||||
name: "Small Fast Model",
|
||||
alias: "smallFast",
|
||||
envKey: "ANTHROPIC_SMALL_FAST_MODEL",
|
||||
defaultValue: _cc.haiku ? `cc/${_cc.haiku}` : "cc/claude-haiku-4-5-20251001",
|
||||
isTopLevel: true,
|
||||
},
|
||||
{
|
||||
id: "opus",
|
||||
name: "Claude Opus",
|
||||
alias: "opus",
|
||||
envKey: "ANTHROPIC_DEFAULT_OPUS_MODEL",
|
||||
defaultValue: "cc/claude-opus-4-5-20251101",
|
||||
defaultValue: _cc.opus ? `cc/${_cc.opus}` : "cc/claude-opus-4-5-20251101",
|
||||
},
|
||||
{
|
||||
id: "sonnet",
|
||||
name: "Claude Sonnet",
|
||||
alias: "sonnet",
|
||||
envKey: "ANTHROPIC_DEFAULT_SONNET_MODEL",
|
||||
defaultValue: "cc/claude-sonnet-4-5-20250929",
|
||||
defaultValue: _cc.sonnet ? `cc/${_cc.sonnet}` : "cc/claude-sonnet-4-5-20250929",
|
||||
},
|
||||
{
|
||||
id: "haiku",
|
||||
name: "Claude Haiku",
|
||||
alias: "haiku",
|
||||
envKey: "ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
||||
defaultValue: "cc/claude-haiku-4-5-20251001",
|
||||
defaultValue: _cc.haiku ? `cc/${_cc.haiku}` : "cc/claude-haiku-4-5-20251001",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
23
tests/unit/claude-cli-defaults.test.ts
Normal file
23
tests/unit/claude-cli-defaults.test.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { getClaudeCodeDefaultModels } from "../../open-sse/config/providerRegistry.ts";
|
||||
|
||||
test("getClaudeCodeDefaultModels returns expected default models", () => {
|
||||
const models = getClaudeCodeDefaultModels();
|
||||
|
||||
// They should be non-empty strings because providerRegistry is populated statically
|
||||
assert.ok(typeof models.opus === "string");
|
||||
assert.ok(typeof models.sonnet === "string");
|
||||
assert.ok(typeof models.haiku === "string");
|
||||
|
||||
// Check that the returned IDs match the expected patterns
|
||||
if (models.opus) {
|
||||
assert.match(models.opus, /opus/i);
|
||||
}
|
||||
if (models.sonnet) {
|
||||
assert.match(models.sonnet, /sonnet/i);
|
||||
}
|
||||
if (models.haiku) {
|
||||
assert.match(models.haiku, /haiku/i);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue