refactor: centralize model override validation

This commit is contained in:
Peter Steinberger
2026-01-09 20:07:20 +01:00
parent f0a909f6dd
commit 7e81980747
7 changed files with 204 additions and 59 deletions

View File

@@ -10,8 +10,7 @@ import {
resetModelCatalogCacheForTest,
} from "../agents/model-catalog.js";
import {
buildAllowedModelSet,
modelKey,
getModelRefStatus,
resolveConfiguredModelRef,
resolveHooksGmailModel,
} from "../agents/model-selection.js";
@@ -1782,22 +1781,21 @@ export async function startGatewayServer(
defaultModel: DEFAULT_MODEL,
});
const catalog = await loadModelCatalog({ config: cfgAtStart });
const key = modelKey(hooksModelRef.provider, hooksModelRef.model);
const allowed = buildAllowedModelSet({
const status = getModelRefStatus({
cfg: cfgAtStart,
catalog,
ref: hooksModelRef,
defaultProvider,
defaultModel,
});
if (!allowed.allowAny && !allowed.allowedKeys.has(key)) {
if (!status.allowed) {
logHooks.warn(
`hooks.gmail.model "${key}" not in agents.defaults.models allowlist (will use primary instead)`,
`hooks.gmail.model "${status.key}" not in agents.defaults.models allowlist (will use primary instead)`,
);
}
const inCatalog = catalog.some((e) => modelKey(e.provider, e.id) === key);
if (!inCatalog) {
if (!status.inCatalog) {
logHooks.warn(
`hooks.gmail.model "${key}" not in the model catalog (may fail at runtime)`,
`hooks.gmail.model "${status.key}" not in the model catalog (may fail at runtime)`,
);
}
}

View File

@@ -3,11 +3,8 @@ import { randomUUID } from "node:crypto";
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
import type { ModelCatalogEntry } from "../agents/model-catalog.js";
import {
buildAllowedModelSet,
buildModelAliasIndex,
modelKey,
resolveAllowedModelRef,
resolveConfiguredModelRef,
resolveModelRefFromString,
} from "../agents/model-selection.js";
import { normalizeGroupActivation } from "../auto-reply/group-activation.js";
import {
@@ -168,17 +165,6 @@ export async function applySessionsPatchToStore(params: {
defaultProvider: DEFAULT_PROVIDER,
defaultModel: DEFAULT_MODEL,
});
const aliasIndex = buildModelAliasIndex({
cfg,
defaultProvider: resolvedDefault.provider,
});
const resolved = resolveModelRefFromString({
raw: trimmed,
defaultProvider: resolvedDefault.provider,
aliasIndex,
});
if (!resolved) return invalid(`invalid model: ${trimmed}`);
if (!params.loadGatewayModelCatalog) {
return {
ok: false,
@@ -189,15 +175,15 @@ export async function applySessionsPatchToStore(params: {
};
}
const catalog = await params.loadGatewayModelCatalog();
const allowed = buildAllowedModelSet({
const resolved = resolveAllowedModelRef({
cfg,
catalog,
raw: trimmed,
defaultProvider: resolvedDefault.provider,
defaultModel: resolvedDefault.model,
});
const key = modelKey(resolved.ref.provider, resolved.ref.model);
if (!allowed.allowAny && !allowed.allowedKeys.has(key)) {
return invalid(`model not allowed: ${key}`);
if ("error" in resolved) {
return invalid(resolved.error);
}
if (
resolved.ref.provider === resolvedDefault.provider &&