refactor: declone model picker model ref parsing

This commit is contained in:
Peter Steinberger 2026-03-14 01:23:24 +00:00
parent c0831927b0
commit 91d9573b55
4 changed files with 38 additions and 14 deletions

View File

@ -60,6 +60,15 @@ describe("Mattermost model picker", () => {
expect(view.buttons[0]?.[0]?.text).toBe("Browse providers"); expect(view.buttons[0]?.[0]?.text).toBe("Browse providers");
}); });
it("trims accidental model spacing in Mattermost current-model text", () => {
const view = renderMattermostModelSummaryView({
ownerUserId: "user-1",
currentModel: " OpenAI/ gpt-5 ",
});
expect(view.text).toContain("Current: openai/gpt-5");
});
it("renders providers and models with Telegram-style navigation", () => { it("renders providers and models with Telegram-style navigation", () => {
const providersView = renderMattermostProviderPickerView({ const providersView = renderMattermostProviderPickerView({
ownerUserId: "user-1", ownerUserId: "user-1",

View File

@ -36,15 +36,13 @@ export type MattermostModelPickerRenderedView = {
function splitModelRef(modelRef?: string | null): { provider: string; model: string } | null { function splitModelRef(modelRef?: string | null): { provider: string; model: string } | null {
const trimmed = modelRef?.trim(); const trimmed = modelRef?.trim();
if (!trimmed) { const match = trimmed?.match(/^([^/]+)\/(.+)$/u);
if (!match) {
return null; return null;
} }
const slashIndex = trimmed.indexOf("/"); const provider = normalizeProviderId(match[1]);
if (slashIndex <= 0 || slashIndex >= trimmed.length - 1) { // Mattermost copy should normalize accidental whitespace around the model.
return null; const model = match[2].trim();
}
const provider = normalizeProviderId(trimmed.slice(0, slashIndex));
const model = trimmed.slice(slashIndex + 1).trim();
if (!provider || !model) { if (!provider || !model) {
return null; return null;
} }

View File

@ -415,6 +415,24 @@ describe("Discord model picker rendering", () => {
expect(payload.components?.[0]?.type).toBe(ComponentType.ActionRow); expect(payload.components?.[0]?.type).toBe(ComponentType.ActionRow);
}); });
it("preserves the stored model suffix spacing in Discord current-model text", () => {
const data = createModelsProviderData({ openai: [" gpt-5", "gpt-4o"] });
const rendered = renderDiscordModelPickerProvidersView({
command: "model",
userId: "99",
data,
currentModel: " OpenAI/ gpt-5 ",
layout: "classic",
});
const payload = serializePayload(toDiscordModelPickerMessagePayload(rendered)) as {
content?: string;
};
expect(payload.content).toContain("Current model: openai/ gpt-5");
});
it("renders model view with select menu and explicit submit button", () => { it("renders model view with select menu and explicit submit button", () => {
const data = createModelsProviderData({ const data = createModelsProviderData({
openai: ["gpt-4.1", "gpt-4o", "o3"], openai: ["gpt-4.1", "gpt-4o", "o3"],

View File

@ -233,15 +233,14 @@ function paginateItems<T>(params: {
function parseCurrentModelRef(raw?: string): DiscordModelPickerCurrentModelRef | null { function parseCurrentModelRef(raw?: string): DiscordModelPickerCurrentModelRef | null {
const trimmed = raw?.trim(); const trimmed = raw?.trim();
if (!trimmed) { const match = trimmed?.match(/^([^/]+)\/(.+)$/u);
if (!match) {
return null; return null;
} }
const slashIndex = trimmed.indexOf("/"); const provider = normalizeProviderId(match[1]);
if (slashIndex <= 0 || slashIndex >= trimmed.length - 1) { // Preserve the model suffix exactly as entered after "/" so select defaults
return null; // continue to mirror the stored ref for Discord interactions.
} const model = match[2];
const provider = normalizeProviderId(trimmed.slice(0, slashIndex));
const model = trimmed.slice(slashIndex + 1);
if (!provider || !model) { if (!provider || !model) {
return null; return null;
} }