From 46c42d4a0dee5429a2f0b50d0eae42426feef4f7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 19 Jun 2026 13:05:46 +0800 Subject: [PATCH] refactor(providers): drop unused model defaults helpers --- extensions/byteplus/live.test.ts | 4 +- extensions/byteplus/models.ts | 8 -- extensions/fireworks/index.test.ts | 11 +- extensions/fireworks/provider-catalog.ts | 1 - extensions/github-copilot/models-defaults.ts | 57 ---------- extensions/github-copilot/models.test.ts | 103 ------------------- 6 files changed, 8 insertions(+), 176 deletions(-) delete mode 100644 extensions/github-copilot/models-defaults.ts diff --git a/extensions/byteplus/live.test.ts b/extensions/byteplus/live.test.ts index 72aa71ead28..a0b0bd6a44a 100644 --- a/extensions/byteplus/live.test.ts +++ b/extensions/byteplus/live.test.ts @@ -6,7 +6,7 @@ import { isLiveTestEnabled, } from "openclaw/plugin-sdk/test-env"; import { describe, expect, it } from "vitest"; -import { BYTEPLUS_CODING_BASE_URL, BYTEPLUS_DEFAULT_COST } from "./models.js"; +import { BYTEPLUS_CODING_BASE_URL } from "./models.js"; const BYTEPLUS_KEY = process.env.BYTEPLUS_API_KEY ?? ""; const BYTEPLUS_CODING_MODEL = process.env.BYTEPLUS_CODING_MODEL?.trim() || "ark-code-latest"; @@ -33,7 +33,7 @@ describeLive("byteplus coding plan live", () => { baseUrl: BYTEPLUS_CODING_BASE_URL, reasoning: false, input: ["text"], - cost: BYTEPLUS_DEFAULT_COST, + cost: { input: 0.0001, output: 0.0002, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256000, maxTokens: 4096, }; diff --git a/extensions/byteplus/models.ts b/extensions/byteplus/models.ts index 04322481c33..d380d42c6d7 100644 --- a/extensions/byteplus/models.ts +++ b/extensions/byteplus/models.ts @@ -20,14 +20,6 @@ export const BYTEPLUS_BASE_URL = BYTEPLUS_MANIFEST_PROVIDER.baseUrl; /** Base URL for BytePlus Plan coding APIs from the manifest catalog. */ export const BYTEPLUS_CODING_BASE_URL = BYTEPLUS_CODING_MANIFEST_PROVIDER.baseUrl; -/** Fallback cost shape retained for callers that need BytePlus defaults. */ -export const BYTEPLUS_DEFAULT_COST = { - input: 0.0001, - output: 0.0002, - cacheRead: 0, - cacheWrite: 0, -}; - /** BytePlus general model catalog entries. */ export const BYTEPLUS_MODEL_CATALOG: ModelDefinitionConfig[] = BYTEPLUS_MANIFEST_PROVIDER.models; /** BytePlus coding/planning model catalog entries. */ diff --git a/extensions/fireworks/index.test.ts b/extensions/fireworks/index.test.ts index 837b5341839..415b6588890 100644 --- a/extensions/fireworks/index.test.ts +++ b/extensions/fireworks/index.test.ts @@ -15,10 +15,11 @@ import { FIREWORKS_DEFAULT_CONTEXT_WINDOW, FIREWORKS_DEFAULT_MAX_TOKENS, FIREWORKS_DEFAULT_MODEL_ID, - FIREWORKS_K2_6_MODEL_ID, } from "./provider-catalog.js"; import { resolveThinkingProfile } from "./provider-policy-api.js"; +const FIREWORKS_KIMI_K2_6_MODEL_ID = "accounts/fireworks/models/kimi-k2p6"; + function createFireworksDefaultRuntimeModel(params: { reasoning: boolean }): ProviderRuntimeModel { return { id: FIREWORKS_DEFAULT_MODEL_ID, @@ -65,7 +66,7 @@ describe("fireworks provider plugin", () => { throw new Error("expected Fireworks catalog models"); } expect(models.map((model) => model.id)).toEqual([ - FIREWORKS_K2_6_MODEL_ID, + FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID, ]); expect(models[0]?.reasoning).toBe(false); @@ -144,7 +145,7 @@ describe("fireworks provider plugin", () => { it("defers manifest catalog models to core static-catalog resolution", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); - for (const modelId of [FIREWORKS_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID]) { + for (const modelId of [FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID]) { const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", @@ -172,7 +173,7 @@ describe("fireworks provider plugin", () => { expect( provider.resolveThinkingProfile?.({ provider: "fireworks", - modelId: FIREWORKS_K2_6_MODEL_ID, + modelId: FIREWORKS_KIMI_K2_6_MODEL_ID, }), ).toEqual({ levels: [{ id: "off" }], @@ -184,7 +185,7 @@ describe("fireworks provider plugin", () => { modelId: "accounts/fireworks/models/qwen3.6-plus", }), ).toBeUndefined(); - expect(resolveThinkingProfile({ modelId: FIREWORKS_K2_6_MODEL_ID })).toEqual({ + expect(resolveThinkingProfile({ modelId: FIREWORKS_KIMI_K2_6_MODEL_ID })).toEqual({ levels: [{ id: "off" }], defaultLevel: "off", }); diff --git a/extensions/fireworks/provider-catalog.ts b/extensions/fireworks/provider-catalog.ts index 93c54c1ce3f..020b1aefa94 100644 --- a/extensions/fireworks/provider-catalog.ts +++ b/extensions/fireworks/provider-catalog.ts @@ -13,7 +13,6 @@ const FIREWORKS_MANIFEST_PROVIDER = buildManifestModelProviderConfig({ export const FIREWORKS_BASE_URL = FIREWORKS_MANIFEST_PROVIDER.baseUrl; export const FIREWORKS_DEFAULT_MODEL_ID = "accounts/fireworks/routers/kimi-k2p5-turbo"; -export const FIREWORKS_K2_6_MODEL_ID = "accounts/fireworks/models/kimi-k2p6"; function requireFireworksManifestModel(id: string): ModelDefinitionConfig { const model = FIREWORKS_MANIFEST_PROVIDER.models.find((entry) => entry.id === id); diff --git a/extensions/github-copilot/models-defaults.ts b/extensions/github-copilot/models-defaults.ts deleted file mode 100644 index 894af2b9f9c..00000000000 --- a/extensions/github-copilot/models-defaults.ts +++ /dev/null @@ -1,57 +0,0 @@ -// Github Copilot plugin module implements models defaults behavior. -import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared"; -import { - resolveCopilotModelCompat, - resolveCopilotTransportApi, - resolveStaticCopilotModelOverride, -} from "./model-metadata.js"; - -const DEFAULT_CONTEXT_WINDOW = 128_000; -const DEFAULT_MAX_TOKENS = 8192; - -// Copilot model ids vary by plan/org and can change. -// We keep this list intentionally broad; if a model isn't available Copilot will -// return an error and users can remove it from their config. -const DEFAULT_MODEL_IDS = [ - "claude-opus-4.6", - "claude-opus-4.7", - "claude-opus-4.8", - "claude-sonnet-4.6", - "gemini-2.5-pro", - "gemini-3-flash", - "gemini-3.1-pro", - "gpt-5.3-codex", - "gpt-5.4", - "gpt-5.4-mini", - "gpt-5.4-nano", - "gpt-5.5", - "raptor-mini", - "goldeneye", -] as const; - -export function getDefaultCopilotModelIds(): string[] { - return [...DEFAULT_MODEL_IDS]; -} - -export function buildCopilotModelDefinition(modelId: string): ModelDefinitionConfig { - const id = modelId.trim(); - if (!id) { - throw new Error("Model id required"); - } - const staticOverride = resolveStaticCopilotModelOverride(id); - const compat = staticOverride?.compat ?? resolveCopilotModelCompat(id); - return { - id, - name: staticOverride?.name ?? id, - api: staticOverride?.api ?? resolveCopilotTransportApi(id), - reasoning: staticOverride?.reasoning ?? false, - input: staticOverride?.input ?? ["text", "image"], - cost: staticOverride?.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: staticOverride?.contextWindow ?? DEFAULT_CONTEXT_WINDOW, - maxTokens: staticOverride?.maxTokens ?? DEFAULT_MAX_TOKENS, - ...(staticOverride?.thinkingLevelMap - ? { thinkingLevelMap: staticOverride.thinkingLevelMap } - : {}), - ...(compat ? { compat } : {}), - }; -} diff --git a/extensions/github-copilot/models.test.ts b/extensions/github-copilot/models.test.ts index 51e634ae0b5..eb61bded130 100644 --- a/extensions/github-copilot/models.test.ts +++ b/extensions/github-copilot/models.test.ts @@ -1,7 +1,6 @@ // Github Copilot tests cover models plugin behavior. import { createProviderUsageFetch, makeResponse } from "openclaw/plugin-sdk/test-env"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { buildCopilotModelDefinition, getDefaultCopilotModelIds } from "./models-defaults.js"; import { deriveCopilotApiBaseUrlFromToken, resolveCopilotApiToken } from "./token.js"; import { fetchCopilotUsage } from "./usage.js"; @@ -54,108 +53,6 @@ function requireResolvedModel(ctx: ProviderResolveDynamicModelContext) { return result; } -describe("github-copilot model defaults", () => { - describe("getDefaultCopilotModelIds", () => { - it("includes claude-opus-4.7", () => { - expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.7"); - expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.6"); - }); - - it("includes claude-opus-4.8", () => { - expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.8"); - }); - - it("includes claude-sonnet-4.6", () => { - expect(getDefaultCopilotModelIds()).toContain("claude-sonnet-4.6"); - }); - - it("excludes retired and old Claude fallback rows", () => { - expect(getDefaultCopilotModelIds()).not.toContain("claude-sonnet-4"); - expect(getDefaultCopilotModelIds()).not.toContain("claude-sonnet-4.5"); - expect(getDefaultCopilotModelIds()).not.toContain("claude-opus-4.5"); - expect(getDefaultCopilotModelIds()).not.toContain("claude-haiku-4.5"); - expect(getDefaultCopilotModelIds()).not.toContain("grok-code-fast-1"); - }); - - it("returns a mutable copy", () => { - const a = getDefaultCopilotModelIds(); - const b = getDefaultCopilotModelIds(); - expect(a).not.toBe(b); - expect(a).toEqual(b); - }); - }); - - describe("buildCopilotModelDefinition", () => { - it("builds a valid definition for claude-sonnet-4.6", () => { - const def = buildCopilotModelDefinition("claude-sonnet-4.6"); - expect(def.id).toBe("claude-sonnet-4.6"); - expect(def.api).toBe("anthropic-messages"); - expect(def.compat).toBeUndefined(); - }); - - it.each(["claude-haiku-4.5", "claude-sonnet-4-5"])( - "disables eager tool streaming for Copilot Claude 4.5 model %s", - (modelId) => { - expect(buildCopilotModelDefinition(modelId).compat).toEqual({ - supportsEagerToolInputStreaming: false, - }); - }, - ); - - it("uses static metadata overrides for gpt-5.5 fallback rows", () => { - const def = buildCopilotModelDefinition("gpt-5.5"); - expect(def).toEqual({ - id: "gpt-5.5", - name: "GPT-5.5", - api: "openai-responses", - reasoning: true, - input: ["text", "image"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 400_000, - maxTokens: 128_000, - }); - }); - - it("uses static metadata overrides for Claude Opus 1M fallback rows", () => { - const def = buildCopilotModelDefinition("claude-opus-4.7-1m-internal"); - expect(def).toEqual({ - id: "claude-opus-4.7-1m-internal", - name: "Claude Opus 4.7 (1M context)", - api: "anthropic-messages", - reasoning: true, - input: ["text", "image"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 1_000_000, - maxTokens: 64_000, - thinkingLevelMap: { xhigh: "xhigh", max: null }, - compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"] }, - }); - }); - - it("trims whitespace from model id", () => { - const def = buildCopilotModelDefinition(" gpt-4o "); - expect(def.id).toBe("gpt-4o"); - expect(def.api).toBe("openai-responses"); - }); - - it("routes Gemini models through Chat Completions with Copilot compat flags", () => { - const def = buildCopilotModelDefinition("gemini-3.1-pro-preview"); - expect(def.api).toBe("openai-completions"); - expect(def.compat).toEqual({ - supportsStore: false, - supportsDeveloperRole: false, - supportsUsageInStreaming: false, - maxTokensField: "max_tokens", - }); - }); - - it("throws on empty model id", () => { - expect(() => buildCopilotModelDefinition("")).toThrow("Model id required"); - expect(() => buildCopilotModelDefinition(" ")).toThrow("Model id required"); - }); - }); -}); - describe("resolveCopilotForwardCompatModel", () => { it("returns undefined for empty modelId", () => { expect(resolveCopilotForwardCompatModel(createMockCtx(""))).toBeUndefined();