mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 10:41:23 +00:00
fix openrouter model picker refs (#63416)
* fix openrouter model picker refs Signed-off-by: sallyom <somalley@redhat.com> * test(ui): cover openrouter slash-id /model resolution --------- Signed-off-by: sallyom <somalley@redhat.com> Co-authored-by: Vignesh Natarajan <vignesh.natarajan92@gmail.com>
This commit is contained in:
@@ -35,6 +35,37 @@ describe("chat-model-ref helpers", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("prefixes provider-native model ids that already contain slashes", () => {
|
||||
expect(
|
||||
buildChatModelOption({
|
||||
id: "google/gemma-4-26b-a4b-it",
|
||||
provider: "openrouter",
|
||||
} as never),
|
||||
).toEqual({
|
||||
value: "openrouter/google/gemma-4-26b-a4b-it",
|
||||
label: "google/gemma-4-26b-a4b-it · openrouter",
|
||||
});
|
||||
expect(
|
||||
resolvePreferredServerChatModel("Google/Gemma-4-26b-a4b-it", "openrouter", [
|
||||
{ id: "google/gemma-4-26b-a4b-it", provider: "openrouter" } as never,
|
||||
]),
|
||||
).toEqual({
|
||||
value: "openrouter/google/gemma-4-26b-a4b-it",
|
||||
source: "server",
|
||||
});
|
||||
});
|
||||
|
||||
it("reuses already-qualified catalog ids without double-prefixing them", () => {
|
||||
expect(
|
||||
resolvePreferredServerChatModel("OpenAI/GPT-4O", "openai", [
|
||||
{ id: "openai/gpt-4o", provider: "openai" } as never,
|
||||
]),
|
||||
).toEqual({
|
||||
value: "openai/gpt-4o",
|
||||
source: "server",
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes raw overrides when the catalog match is unique", () => {
|
||||
expect(normalizeChatModelOverrideValue(createChatModelOverride("gpt-5-mini"), catalog)).toBe(
|
||||
"openai/gpt-5-mini",
|
||||
@@ -102,7 +133,6 @@ describe("chat-model-ref helpers", () => {
|
||||
).toEqual({
|
||||
value: "openai/gpt-5-mini",
|
||||
source: "server",
|
||||
reason: "ambiguous",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -113,6 +113,20 @@ export function resolvePreferredServerChatModel(
|
||||
if (!trimmedModel) {
|
||||
return { value: "", source: "empty", reason: "empty" };
|
||||
}
|
||||
const trimmedProvider = provider?.trim();
|
||||
if (trimmedProvider) {
|
||||
const providerMatch = catalog.find(
|
||||
(entry) =>
|
||||
entry.provider?.trim().toLowerCase() === trimmedProvider.toLowerCase() &&
|
||||
entry.id.trim().toLowerCase() === trimmedModel.toLowerCase(),
|
||||
);
|
||||
if (providerMatch) {
|
||||
return {
|
||||
value: buildChatModelOption(providerMatch).value,
|
||||
source: "server",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const overrideResolution = resolveChatModelOverride(
|
||||
createChatModelOverride(trimmedModel),
|
||||
@@ -151,8 +165,15 @@ export function formatChatModelDisplay(value: string): string {
|
||||
|
||||
export function buildChatModelOption(entry: ModelCatalogEntry): { value: string; label: string } {
|
||||
const provider = entry.provider?.trim();
|
||||
const value = (() => {
|
||||
if (!provider) {
|
||||
return entry.id;
|
||||
}
|
||||
const providerPrefix = `${provider.toLowerCase()}/`;
|
||||
return entry.id.toLowerCase().startsWith(providerPrefix) ? entry.id : `${provider}/${entry.id}`;
|
||||
})();
|
||||
return {
|
||||
value: buildQualifiedChatModelValue(entry.id, provider),
|
||||
value,
|
||||
label: provider ? `${entry.id} · ${provider}` : entry.id,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -359,6 +359,37 @@ describe("executeSlashCommand directives", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps openrouter-prefixed refs when patched model ids include slashes", async () => {
|
||||
const request = vi.fn(async (method: string, _payload?: unknown) => {
|
||||
if (method === "sessions.patch") {
|
||||
return createResolvedModelPatch("google/gemma-4-26b-a4b-it", "openrouter");
|
||||
}
|
||||
throw new Error(`unexpected method: ${method}`);
|
||||
});
|
||||
|
||||
const result = await executeSlashCommand(
|
||||
{ request } as unknown as GatewayBrowserClient,
|
||||
"main",
|
||||
"model",
|
||||
"google/gemma-4-26b-a4b-it",
|
||||
{
|
||||
chatModelCatalog: [
|
||||
{
|
||||
id: "google/gemma-4-26b-a4b-it",
|
||||
name: "Gemma 4 26B",
|
||||
provider: "openrouter",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.sessionPatch?.modelOverride).toEqual({
|
||||
kind: "qualified",
|
||||
value: "openrouter/google/gemma-4-26b-a4b-it",
|
||||
});
|
||||
expect(request).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("falls back to the patched server provider when catalog lookup fails", async () => {
|
||||
const request = vi.fn(async (method: string, _payload?: unknown) => {
|
||||
if (method === "sessions.patch") {
|
||||
|
||||
Reference in New Issue
Block a user