From 686375ba724a605a94d509659ce13ad4b448542a Mon Sep 17 00:00:00 2001 From: backryun Date: Thu, 23 Jul 2026 17:24:14 +0900 Subject: [PATCH] fix(devin-cli): refresh shared model catalog (#8227) --- .../providers/registry/devin-cli/index.ts | 57 +---------- .../providers/registry/devin/catalog.ts | 98 +++++++++++++++++++ open-sse/executors/devin-cli.ts | 6 +- tests/unit/devin-cli-catalog.test.ts | 35 +++++++ 4 files changed, 138 insertions(+), 58 deletions(-) create mode 100644 open-sse/config/providers/registry/devin/catalog.ts create mode 100644 tests/unit/devin-cli-catalog.test.ts diff --git a/open-sse/config/providers/registry/devin-cli/index.ts b/open-sse/config/providers/registry/devin-cli/index.ts index 4fd1b7684e..d7dde480c5 100644 --- a/open-sse/config/providers/registry/devin-cli/index.ts +++ b/open-sse/config/providers/registry/devin-cli/index.ts @@ -1,4 +1,5 @@ import type { RegistryEntry } from "../../shared.ts"; +import { DEVIN_MODEL_CATALOG } from "../devin/catalog.ts"; export const devin_cliProvider: RegistryEntry = { id: "devin-cli", @@ -10,59 +11,5 @@ export const devin_cliProvider: RegistryEntry = { authHeader: "Authorization", authPrefix: "Bearer ", defaultContextLength: 200000, - models: [ - // Cognition / SWE — default model family recommended for coding tasks - { id: "swe-1.6-fast", name: "SWE-1.6 Fast" }, - { id: "swe-1.6", name: "SWE-1.6" }, - { id: "swe-1.5-fast", name: "SWE-1.5 Fast" }, - { id: "swe-1.5", name: "SWE-1.5" }, - // Claude Opus 4.7 - { id: "claude-opus-4.7-max", name: "Claude Opus 4.7 Max", contextLength: 200000 }, - { id: "claude-opus-4.7-high", name: "Claude Opus 4.7 High", contextLength: 200000 }, - { id: "claude-opus-4.7-medium", name: "Claude Opus 4.7 Medium", contextLength: 200000 }, - { id: "claude-opus-4.7-low", name: "Claude Opus 4.7 Low", contextLength: 200000 }, - // Claude Sonnet/Opus 4.6 - { - id: "claude-sonnet-4.6-thinking-1m", - name: "Claude Sonnet 4.6 Thinking 1M", - contextLength: 1000000, - }, - { - id: "claude-sonnet-4.6-thinking", - name: "Claude Sonnet 4.6 Thinking", - contextLength: 200000, - }, - { id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", contextLength: 200000 }, - { id: "claude-opus-4.6-thinking", name: "Claude Opus 4.6 Thinking", contextLength: 200000 }, - { id: "claude-opus-4.6", name: "Claude Opus 4.6", contextLength: 200000 }, - // Claude 4.5 - { id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5", contextLength: 200000 }, - { id: "claude-haiku-4.5", name: "Claude Haiku 4.5", contextLength: 200000 }, - // GPT-5.5 - { id: "gpt-5.5-xhigh", name: "GPT-5.5 XHigh", contextLength: 200000 }, - { id: "gpt-5.5-high", name: "GPT-5.5 High", contextLength: 200000 }, - { id: "gpt-5.5-medium", name: "GPT-5.5 Medium", contextLength: 200000 }, - { id: "gpt-5.5-low", name: "GPT-5.5 Low", contextLength: 200000 }, - // GPT-5.4 - { id: "gpt-5.4-high", name: "GPT-5.4 High", contextLength: 200000 }, - { id: "gpt-5.4-medium", name: "GPT-5.4 Medium", contextLength: 200000 }, - { id: "gpt-5.4-low", name: "GPT-5.4 Low", contextLength: 200000 }, - // GPT-5.3 Codex - { id: "gpt-5.3-codex-high", name: "GPT-5.3 Codex High", contextLength: 200000 }, - { id: "gpt-5.3-codex-medium", name: "GPT-5.3 Codex Medium", contextLength: 200000 }, - { id: "gpt-5.3-codex-low", name: "GPT-5.3 Codex Low", contextLength: 200000 }, - // GPT-5.2 - { id: "gpt-5.2-high", name: "GPT-5.2 High", contextLength: 200000 }, - { id: "gpt-5.2-medium", name: "GPT-5.2 Medium", contextLength: 200000 }, - { id: "gpt-5.2-low", name: "GPT-5.2 Low", contextLength: 200000 }, - // Gemini - { id: "gemini-3.1-pro-high", name: "Gemini 3.1 Pro High", contextLength: 1000000 }, - { id: "gemini-3.1-pro-low", name: "Gemini 3.1 Pro Low", contextLength: 1000000 }, - { id: "gemini-3.0-flash-high", name: "Gemini 3 Flash High", contextLength: 1000000 }, - { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", contextLength: 1000000 }, - // Others - { id: "deepseek-v4", name: "DeepSeek V4", contextLength: 64000 }, - { id: "kimi-k2.6", name: "Kimi K2.6", contextLength: 131000 }, - { id: "glm-5.1", name: "GLM-5.1", contextLength: 128000 }, - ], + models: DEVIN_MODEL_CATALOG, }; diff --git a/open-sse/config/providers/registry/devin/catalog.ts b/open-sse/config/providers/registry/devin/catalog.ts new file mode 100644 index 0000000000..2ef8567890 --- /dev/null +++ b/open-sse/config/providers/registry/devin/catalog.ts @@ -0,0 +1,98 @@ +import type { RegistryModel } from "../../shared.ts"; + +export const DEVIN_MODEL_CATALOG: RegistryModel[] = [ + // Cognition / SWE — default model family recommended for coding tasks + { id: "swe-1-7-lightning", name: "SWE-1.7 Lightning", contextLength: 202752 }, + { id: "swe-1-7", name: "SWE-1.7", contextLength: 262000 }, + { id: "swe-1-6-fast", name: "SWE-1.6 Fast" }, + { id: "swe-1-6", name: "SWE-1.6" }, + // Claude Fable 5 + { id: "claude-5-fable-max", name: "Claude Fable 5 Max", contextLength: 1000000 }, + { id: "claude-5-fable-xhigh", name: "Claude Fable 5 XHigh", contextLength: 1000000 }, + { id: "claude-5-fable-high", name: "Claude Fable 5 High", contextLength: 1000000 }, + { id: "claude-5-fable-medium", name: "Claude Fable 5 Medium", contextLength: 1000000 }, + { id: "claude-5-fable-low", name: "Claude Fable 5 Low", contextLength: 1000000 }, + // Claude Opus 4.8 + { id: "claude-opus-4-8-max", name: "Claude Opus 4.8 Max", contextLength: 1000000 }, + { id: "claude-opus-4-8-xhigh", name: "Claude Opus 4.8 XHigh", contextLength: 1000000 }, + { id: "claude-opus-4-8-high", name: "Claude Opus 4.8 High", contextLength: 1000000 }, + { id: "claude-opus-4-8-medium", name: "Claude Opus 4.8 Medium", contextLength: 1000000 }, + { id: "claude-opus-4-8-low", name: "Claude Opus 4.8 Low", contextLength: 1000000 }, + // Claude Opus 4.7 + { id: "claude-opus-4-7-max", name: "Claude Opus 4.7 Max", contextLength: 1000000 }, + { id: "claude-opus-4-7-xhigh", name: "Claude Opus 4.7 XHigh", contextLength: 1000000 }, + { id: "claude-opus-4-7-high", name: "Claude Opus 4.7 High", contextLength: 1000000 }, + { id: "claude-opus-4-7-medium", name: "Claude Opus 4.7 Medium", contextLength: 1000000 }, + { id: "claude-opus-4-7-low", name: "Claude Opus 4.7 Low", contextLength: 1000000 }, + // Claude Opus 4.6 + { + id: "claude-opus-4-6-thinking-1m", + name: "Claude Opus 4.6 Thinking 1M", + contextLength: 1000000, + }, + { id: "claude-opus-4-6-thinking", name: "Claude Opus 4.6 Thinking", contextLength: 200000 }, + { id: "claude-opus-4-6-1m", name: "Claude Opus 4.6 1M", contextLength: 1000000 }, + { id: "claude-opus-4-6", name: "Claude Opus 4.6", contextLength: 200000 }, + // Claude Sonnet 5 + { id: "claude-sonnet-5-max", name: "Claude Sonnet 5 Max", contextLength: 1000000 }, + { id: "claude-sonnet-5-xhigh", name: "Claude Sonnet 5 XHigh", contextLength: 1000000 }, + { id: "claude-sonnet-5-high", name: "Claude Sonnet 5 High", contextLength: 1000000 }, + { id: "claude-sonnet-5-medium", name: "Claude Sonnet 5 Medium", contextLength: 1000000 }, + { id: "claude-sonnet-5-low", name: "Claude Sonnet 5 Low", contextLength: 1000000 }, + // Claude Sonnet 4.6 + { + id: "claude-sonnet-4-6-thinking-1m", + name: "Claude Sonnet 4.6 Thinking 1M", + contextLength: 1000000, + }, + { + id: "claude-sonnet-4-6-thinking", + name: "Claude Sonnet 4.6 Thinking", + contextLength: 200000, + }, + { id: "claude-sonnet-4-6-1m", name: "Claude Sonnet 4.6 1M", contextLength: 1000000 }, + { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", contextLength: 200000 }, + // GPT-5.6 + { id: "gpt-5-6-sol-max", name: "GPT-5.6 Sol Max", contextLength: 1000000 }, + { id: "gpt-5-6-sol-xhigh", name: "GPT-5.6 Sol XHigh", contextLength: 1000000 }, + { id: "gpt-5-6-sol-high", name: "GPT-5.6 Sol High", contextLength: 1000000 }, + { id: "gpt-5-6-sol-medium", name: "GPT-5.6 Sol Medium", contextLength: 1000000 }, + { id: "gpt-5-6-sol-low", name: "GPT-5.6 Sol Low", contextLength: 1000000 }, + /// Terra + { id: "gpt-5-6-terra-max", name: "GPT-5.6 Terra Max", contextLength: 1000000 }, + { id: "gpt-5-6-terra-xhigh", name: "GPT-5.6 Terra XHigh", contextLength: 1000000 }, + { id: "gpt-5-6-terra-high", name: "GPT-5.6 Terra High", contextLength: 1000000 }, + { id: "gpt-5-6-terra-medium", name: "GPT-5.6 Terra Medium", contextLength: 1000000 }, + { id: "gpt-5-6-terra-low", name: "GPT-5.6 Terra Low", contextLength: 1000000 }, + /// Luna + { id: "gpt-5-6-luna-max", name: "GPT-5.6 Luna Max", contextLength: 1000000 }, + { id: "gpt-5-6-luna-xhigh", name: "GPT-5.6 Luna XHigh", contextLength: 1000000 }, + { id: "gpt-5-6-luna-high", name: "GPT-5.6 Luna High", contextLength: 1000000 }, + { id: "gpt-5-6-luna-medium", name: "GPT-5.6 Luna Medium", contextLength: 1000000 }, + { id: "gpt-5-6-luna-low", name: "GPT-5.6 Luna Low", contextLength: 1000000 }, + // GPT-5.5 + { id: "gpt-5-5-xhigh", name: "GPT-5.5 XHigh", contextLength: 272000 }, + { id: "gpt-5-5-high", name: "GPT-5.5 High", contextLength: 272000 }, + { id: "gpt-5-5-medium", name: "GPT-5.5 Medium", contextLength: 272000 }, + { id: "gpt-5-5-low", name: "GPT-5.5 Low", contextLength: 272000 }, + // Gemini + { id: "gemini-3-1-pro-high", name: "Gemini 3.1 Pro High", contextLength: 1048576 }, + { id: "gemini-3-1-pro-low", name: "Gemini 3.1 Pro Low", contextLength: 1048576 }, + { id: "gemini-3-5-flash-high", name: "Gemini 3.5 Flash High", contextLength: 1048576 }, + { id: "gemini-3-5-flash-medium", name: "Gemini 3.5 Flash Medium", contextLength: 1048576 }, + { id: "gemini-3-5-flash-low", name: "Gemini 3.5 Flash Low", contextLength: 1048576 }, + { id: "gemini-3-5-flash-minimal", name: "Gemini 3.5 Flash Minimal", contextLength: 1048576 }, + // Grok + { id: "grok-4-5-high", name: "Grok 4.5 High", contextLength: 500000 }, + { id: "grok-4-5-medium", name: "Grok 4.5 Medium", contextLength: 500000 }, + { id: "grok-4-5-low", name: "Grok 4.5 Low", contextLength: 500000 }, + // GLM + { id: "glm-5-2-max-1m", name: "GLM-5.2 Max 1M", contextLength: 1000000 }, + { id: "glm-5-2-max", name: "GLM-5.2 Max" }, + { id: "glm-5-2-1m", name: "GLM-5.2 High 1M", contextLength: 1000000 }, + { id: "glm-5-2", name: "GLM-5.2 High" }, + // Others + { id: "deepseek-v4", name: "DeepSeek V4 Pro", contextLength: 1048576 }, + { id: "nemotron-3-ultra-nvfp4", name: "Nemotron 3 Ultra", contextLength: 262144 }, + { id: "kimi-k2-7", name: "Kimi K2.7", contextLength: 262144 }, +]; diff --git a/open-sse/executors/devin-cli.ts b/open-sse/executors/devin-cli.ts index 528cd25308..1f5b307ab8 100644 --- a/open-sse/executors/devin-cli.ts +++ b/open-sse/executors/devin-cli.ts @@ -21,9 +21,9 @@ * 4. ~/.local/share/devin/bin/devin (Linux installer) * * Model selection: - * Passed directly to ACP session/new as `model` param (e.g. "swe-1.6-fast", - * "claude-sonnet-4.6", "gpt-5.5-high"). Devin CLI resolves them against its - * model_configs_v2.bin catalog on startup. + * Passed directly to ACP session/new as `model` param (e.g. "swe-1-6-fast", + * "claude-sonnet-4-6", "gpt-5-5-high"). Devin CLI resolves them against its + * model_configs_v4.bin catalog on startup. */ import { spawn } from "node:child_process"; diff --git a/tests/unit/devin-cli-catalog.test.ts b/tests/unit/devin-cli-catalog.test.ts new file mode 100644 index 0000000000..cfcf19fa5d --- /dev/null +++ b/tests/unit/devin-cli-catalog.test.ts @@ -0,0 +1,35 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { devin_cliProvider } from "../../open-sse/config/providers/registry/devin-cli/index.ts"; +import { DEVIN_MODEL_CATALOG } from "../../open-sse/config/providers/registry/devin/catalog.ts"; + +test("Devin CLI uses the shared catalog without duplicate model ids", () => { + const ids = DEVIN_MODEL_CATALOG.map((model) => model.id); + + assert.equal(devin_cliProvider.models, DEVIN_MODEL_CATALOG); + assert.equal(new Set(ids).size, ids.length); + assert.ok(ids.every((id) => !id.toLowerCase().includes("byok"))); +}); + +test("Devin CLI catalog includes the refreshed native model ids", () => { + const ids = new Set(DEVIN_MODEL_CATALOG.map((model) => model.id)); + + for (const id of [ + "swe-1-7-lightning", + "claude-5-fable-max", + "gpt-5-6-sol-max", + "gpt-5-5-high", + "glm-5-2-max-1m", + ]) { + assert.ok(ids.has(id), `expected refreshed Devin model id: ${id}`); + } +}); + +test("Devin CLI catalog does not expose retired dotted or review model ids", () => { + const ids = new Set(DEVIN_MODEL_CATALOG.map((model) => model.id)); + + for (const id of ["swe-1.6-fast", "swe-1.6", "claude-opus-4.7-review"]) { + assert.equal(ids.has(id), false, `retired Devin model id must stay absent: ${id}`); + } +});