From 84191c0d676912e4e06d8f62ea36b9ed7bf35eb4 Mon Sep 17 00:00:00 2001 From: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Date: Sat, 2 May 2026 22:15:03 +0000 Subject: [PATCH] fix(clawsweeper): address review for automerge-openclaw-openclaw-73388 (2) --- extensions/arcee/index.test.ts | 70 +++++++++++++++++++++++++--------- extensions/arcee/index.ts | 6 +-- extensions/arcee/models.ts | 44 ++++++++++++++++++++- 3 files changed, 96 insertions(+), 24 deletions(-) diff --git a/extensions/arcee/index.test.ts b/extensions/arcee/index.test.ts index 3e9b00ca603..7943059cb72 100644 --- a/extensions/arcee/index.test.ts +++ b/extensions/arcee/index.test.ts @@ -295,34 +295,66 @@ describe("arcee provider plugin", () => { ], }); + const trinityRuntimeModel = { + name: "Trinity Large Thinking", + api: "openai-completions", + reasoning: true, + input: ["text"], + contextWindow: 262144, + maxTokens: 80000, + cost: { + input: 0.25, + output: 0.9, + cacheRead: 0.25, + cacheWrite: 0.25, + }, + compat: { + supportsReasoningEffort: false, + }, + }; + + const trinityCompat = { + supportsReasoningEffort: false, + supportsTools: false, + }; + expect( provider.contributeResolvedModelCompat?.({ provider: "arcee", modelId: "arcee/trinity-large-thinking", model: { + ...trinityRuntimeModel, provider: "arcee", id: "arcee/trinity-large-thinking", - name: "Trinity Large Thinking", - api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", - reasoning: true, - input: ["text"], - contextWindow: 262144, - maxTokens: 80000, - cost: { - input: 0.25, - output: 0.9, - cacheRead: 0.25, - cacheWrite: 0.25, - }, - compat: { - supportsReasoningEffort: false, - }, }, } as never), - ).toEqual({ - supportsReasoningEffort: false, - supportsTools: false, - }); + ).toEqual(trinityCompat); + + expect( + provider.contributeResolvedModelCompat?.({ + provider: "arcee", + modelId: "trinity-large-thinking", + model: { + ...trinityRuntimeModel, + provider: "arcee", + id: "trinity-large-thinking", + baseUrl: "https://api.arcee.ai/api/v1", + }, + } as never), + ).toEqual(trinityCompat); + + expect( + provider.contributeResolvedModelCompat?.({ + provider: "openrouter", + modelId: "trinity-large-thinking", + model: { + ...trinityRuntimeModel, + provider: "openrouter", + id: "trinity-large-thinking", + baseUrl: "https://openrouter.ai/api/v1", + }, + } as never), + ).toBeUndefined(); }); }); diff --git a/extensions/arcee/index.ts b/extensions/arcee/index.ts index 29e9b2def57..e8eec9d1969 100644 --- a/extensions/arcee/index.ts +++ b/extensions/arcee/index.ts @@ -7,7 +7,7 @@ import { import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared"; import { ARCEE_TRINITY_LARGE_THINKING_COMPAT, - isArceeTrinityLargeThinkingModelId, + shouldContributeArceeTrinityLargeThinkingCompat, } from "./models.js"; import { applyArceeConfig, @@ -127,8 +127,8 @@ export default definePluginEntry({ }), normalizeConfig: ({ providerConfig }) => normalizeArceeProviderConfig(providerConfig), normalizeResolvedModel: ({ model }) => normalizeArceeResolvedModel(model), - contributeResolvedModelCompat: ({ modelId, model }) => - isArceeTrinityLargeThinkingModelId(model.id) || isArceeTrinityLargeThinkingModelId(modelId) + contributeResolvedModelCompat: (ctx) => + shouldContributeArceeTrinityLargeThinkingCompat(ctx) ? ARCEE_TRINITY_LARGE_THINKING_COMPAT : undefined, normalizeTransport: ({ api, baseUrl }) => { diff --git a/extensions/arcee/models.ts b/extensions/arcee/models.ts index dfcb0f19f53..8c7ac699a94 100644 --- a/extensions/arcee/models.ts +++ b/extensions/arcee/models.ts @@ -9,9 +9,49 @@ export const ARCEE_TRINITY_LARGE_THINKING_COMPAT = { supportsTools: false, } as const satisfies ModelCompatConfig; +const ARCEE_PROVIDER_ID = "arcee"; +const ARCEE_TRINITY_LARGE_THINKING_ID = "trinity-large-thinking"; +const ARCEE_TRINITY_LARGE_THINKING_REF = `${ARCEE_PROVIDER_ID}/${ARCEE_TRINITY_LARGE_THINKING_ID}`; + +function normalizeModelId(modelId: string): string { + return modelId.trim().toLowerCase(); +} + +function normalizeBaseUrl(baseUrl: unknown): string { + return typeof baseUrl === "string" ? baseUrl.trim().replace(/\/+$/, "") : ""; +} + export function isArceeTrinityLargeThinkingModelId(modelId: string): boolean { - const normalized = modelId.trim().toLowerCase(); - return normalized === "trinity-large-thinking" || normalized === "arcee/trinity-large-thinking"; + const normalized = normalizeModelId(modelId); + return ( + normalized === ARCEE_TRINITY_LARGE_THINKING_ID || + normalized === ARCEE_TRINITY_LARGE_THINKING_REF + ); +} + +export function shouldContributeArceeTrinityLargeThinkingCompat(params: { + provider?: unknown; + modelId: string; + model: { id: string; provider?: unknown; baseUrl?: unknown }; +}): boolean { + const modelId = normalizeModelId(params.modelId); + const resolvedId = normalizeModelId(params.model.id); + if ( + modelId === ARCEE_TRINITY_LARGE_THINKING_REF || + resolvedId === ARCEE_TRINITY_LARGE_THINKING_REF + ) { + return true; + } + if ( + modelId !== ARCEE_TRINITY_LARGE_THINKING_ID && + resolvedId !== ARCEE_TRINITY_LARGE_THINKING_ID + ) { + return false; + } + if (params.provider === ARCEE_PROVIDER_ID || params.model.provider === ARCEE_PROVIDER_ID) { + return true; + } + return normalizeBaseUrl(params.model.baseUrl) === normalizeBaseUrl(ARCEE_BASE_URL); } export const ARCEE_MODEL_CATALOG: ModelDefinitionConfig[] = [