feat: add model aliases + minimax shortlist

This commit is contained in:
Peter Steinberger
2025-12-26 23:26:14 +00:00
parent ae9a8ce34c
commit 5c8e1b6eef
7 changed files with 178 additions and 28 deletions

View File

@@ -9,8 +9,9 @@ import {
import { loadModelCatalog } from "../agents/model-catalog.js";
import {
buildAllowedModelSet,
buildModelAliasIndex,
modelKey,
parseModelRef,
resolveModelRefFromString,
resolveConfiguredModelRef,
} from "../agents/model-selection.js";
import {
@@ -252,16 +253,21 @@ export async function getReplyFromConfig(
});
const defaultProvider = mainModel.provider;
const defaultModel = mainModel.model;
const aliasIndex = buildModelAliasIndex({ cfg, defaultProvider });
let provider = defaultProvider;
let model = defaultModel;
if (opts?.isHeartbeat) {
const heartbeatRaw = agentCfg?.heartbeat?.model?.trim() ?? "";
const heartbeatRef = heartbeatRaw
? parseModelRef(heartbeatRaw, defaultProvider)
? resolveModelRefFromString({
raw: heartbeatRaw,
defaultProvider,
aliasIndex,
})
: null;
if (heartbeatRef) {
provider = heartbeatRef.provider;
model = heartbeatRef.model;
provider = heartbeatRef.ref.provider;
model = heartbeatRef.ref.model;
}
}
let contextTokens =
@@ -571,9 +577,12 @@ export async function getReplyFromConfig(
}
for (const entry of allowedModelCatalog) {
const label = `${entry.provider}/${entry.id}`;
const aliases = aliasIndex.byKey.get(label);
const aliasSuffix =
aliases && aliases.length > 0 ? ` (alias: ${aliases.join(", ")})` : "";
const suffix =
entry.name && entry.name !== entry.id ? `${entry.name}` : "";
lines.push(`- ${label}${suffix}`);
lines.push(`- ${label}${aliasSuffix}${suffix}`);
}
cleanupTyping();
return { text: lines.join("\n") };
@@ -598,26 +607,36 @@ export async function getReplyFromConfig(
}
let modelSelection:
| { provider: string; model: string; isDefault: boolean }
| { provider: string; model: string; isDefault: boolean; alias?: string }
| undefined;
if (hasModelDirective && rawModelDirective) {
const parsed = parseModelRef(rawModelDirective, defaultProvider);
if (!parsed) {
const resolved = resolveModelRefFromString({
raw: rawModelDirective,
defaultProvider,
aliasIndex,
});
if (!resolved) {
cleanupTyping();
return {
text: `Unrecognized model "${rawModelDirective}". Use /model to list available models.`,
};
}
const key = modelKey(parsed.provider, parsed.model);
const key = modelKey(resolved.ref.provider, resolved.ref.model);
if (allowedModelKeys.size > 0 && !allowedModelKeys.has(key)) {
cleanupTyping();
return {
text: `Model "${parsed.provider}/${parsed.model}" is not allowed. Use /model to list available models.`,
text: `Model "${resolved.ref.provider}/${resolved.ref.model}" is not allowed. Use /model to list available models.`,
};
}
const isDefault =
parsed.provider === defaultProvider && parsed.model === defaultModel;
modelSelection = { ...parsed, isDefault };
resolved.ref.provider === defaultProvider &&
resolved.ref.model === defaultModel;
modelSelection = {
provider: resolved.ref.provider,
model: resolved.ref.model,
isDefault,
alias: resolved.alias,
};
}
if (sessionEntry && sessionStore && sessionKey) {
@@ -665,10 +684,13 @@ export async function getReplyFromConfig(
}
if (modelSelection) {
const label = `${modelSelection.provider}/${modelSelection.model}`;
const labelWithAlias = modelSelection.alias
? `${modelSelection.alias} (${label})`
: label;
parts.push(
modelSelection.isDefault
? `Model reset to default (${label}).`
: `Model set to ${label}.`,
? `Model reset to default (${labelWithAlias}).`
: `Model set to ${labelWithAlias}.`,
);
}
if (hasQueueDirective && inlineQueueMode) {
@@ -701,22 +723,26 @@ export async function getReplyFromConfig(
updated = true;
}
if (hasModelDirective && rawModelDirective) {
const parsed = parseModelRef(rawModelDirective, defaultProvider);
if (parsed) {
const key = modelKey(parsed.provider, parsed.model);
const resolved = resolveModelRefFromString({
raw: rawModelDirective,
defaultProvider,
aliasIndex,
});
if (resolved) {
const key = modelKey(resolved.ref.provider, resolved.ref.model);
if (allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
const isDefault =
parsed.provider === defaultProvider &&
parsed.model === defaultModel;
resolved.ref.provider === defaultProvider &&
resolved.ref.model === defaultModel;
if (isDefault) {
delete sessionEntry.providerOverride;
delete sessionEntry.modelOverride;
} else {
sessionEntry.providerOverride = parsed.provider;
sessionEntry.modelOverride = parsed.model;
sessionEntry.providerOverride = resolved.ref.provider;
sessionEntry.modelOverride = resolved.ref.model;
}
provider = parsed.provider;
model = parsed.model;
provider = resolved.ref.provider;
model = resolved.ref.model;
contextTokens =
agentCfg?.contextTokens ??
lookupContextTokens(model) ??