@@ -7,6 +7,7 @@
|
|||||||
- Memory: allow custom OpenAI-compatible embedding endpoints for memory search (remote baseUrl/apiKey/headers). (#819 — thanks @mukhtharcm)
|
- Memory: allow custom OpenAI-compatible embedding endpoints for memory search (remote baseUrl/apiKey/headers). (#819 — thanks @mukhtharcm)
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
- Models/Google: normalize Gemini 3 model ids to preview variants before runtime selection. (#795 — thanks @thewilloftheshadow)
|
||||||
- TUI: keep the last streamed response instead of replacing it with “(no output)”. (#747 — thanks @thewilloftheshadow)
|
- TUI: keep the last streamed response instead of replacing it with “(no output)”. (#747 — thanks @thewilloftheshadow)
|
||||||
- Slack: accept slash commands with or without leading `/` for custom command configs. (#798 — thanks @thewilloftheshadow)
|
- Slack: accept slash commands with or without leading `/` for custom command configs. (#798 — thanks @thewilloftheshadow)
|
||||||
- Onboarding/Configure: refuse to proceed with invalid configs; run `clawdbot doctor` first to avoid wiping custom fields. (#764 — thanks @mukhtharcm)
|
- Onboarding/Configure: refuse to proceed with invalid configs; run `clawdbot doctor` first to avoid wiping custom fields. (#764 — thanks @mukhtharcm)
|
||||||
|
|||||||
@@ -107,6 +107,24 @@ describe("parseModelRef", () => {
|
|||||||
model: "claude-opus-4-5",
|
model: "claude-opus-4-5",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("normalizes google gemini 3 models to preview ids", () => {
|
||||||
|
expect(parseModelRef("google/gemini-3-pro", "anthropic")).toEqual({
|
||||||
|
provider: "google",
|
||||||
|
model: "gemini-3-pro-preview",
|
||||||
|
});
|
||||||
|
expect(parseModelRef("google/gemini-3-flash", "anthropic")).toEqual({
|
||||||
|
provider: "google",
|
||||||
|
model: "gemini-3-flash-preview",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes default-provider google models", () => {
|
||||||
|
expect(parseModelRef("gemini-3-pro", "google")).toEqual({
|
||||||
|
provider: "google",
|
||||||
|
model: "gemini-3-pro-preview",
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("resolveHooksGmailModel", () => {
|
describe("resolveHooksGmailModel", () => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { ClawdbotConfig } from "../config/config.js";
|
import type { ClawdbotConfig } from "../config/config.js";
|
||||||
import type { ModelCatalogEntry } from "./model-catalog.js";
|
import type { ModelCatalogEntry } from "./model-catalog.js";
|
||||||
|
import { normalizeGoogleModelId } from "./models-config.providers.js";
|
||||||
|
|
||||||
export type ModelRef = {
|
export type ModelRef = {
|
||||||
provider: string;
|
provider: string;
|
||||||
@@ -47,6 +48,12 @@ function normalizeAnthropicModelId(model: string): string {
|
|||||||
return trimmed;
|
return trimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeProviderModelId(provider: string, model: string): string {
|
||||||
|
if (provider === "anthropic") return normalizeAnthropicModelId(model);
|
||||||
|
if (provider === "google") return normalizeGoogleModelId(model);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
export function parseModelRef(
|
export function parseModelRef(
|
||||||
raw: string,
|
raw: string,
|
||||||
defaultProvider: string,
|
defaultProvider: string,
|
||||||
@@ -56,16 +63,14 @@ export function parseModelRef(
|
|||||||
const slash = trimmed.indexOf("/");
|
const slash = trimmed.indexOf("/");
|
||||||
if (slash === -1) {
|
if (slash === -1) {
|
||||||
const provider = normalizeProviderId(defaultProvider);
|
const provider = normalizeProviderId(defaultProvider);
|
||||||
const model =
|
const model = normalizeProviderModelId(provider, trimmed);
|
||||||
provider === "anthropic" ? normalizeAnthropicModelId(trimmed) : trimmed;
|
|
||||||
return { provider, model };
|
return { provider, model };
|
||||||
}
|
}
|
||||||
const providerRaw = trimmed.slice(0, slash).trim();
|
const providerRaw = trimmed.slice(0, slash).trim();
|
||||||
const provider = normalizeProviderId(providerRaw);
|
const provider = normalizeProviderId(providerRaw);
|
||||||
const model = trimmed.slice(slash + 1).trim();
|
const model = trimmed.slice(slash + 1).trim();
|
||||||
if (!provider || !model) return null;
|
if (!provider || !model) return null;
|
||||||
const normalizedModel =
|
const normalizedModel = normalizeProviderModelId(provider, model);
|
||||||
provider === "anthropic" ? normalizeAnthropicModelId(model) : model;
|
|
||||||
return { provider, model: normalizedModel };
|
return { provider, model: normalizedModel };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user