it("renders model rows and optional current-model indicator", () => { const cases = [
{
name: "no current model",
currentModel: undefined,
firstText: "claude-sonnet-4",
},
{
name: "current model marked",
currentModel: "anthropic/claude-sonnet-4",
firstText: "claude-sonnet-4 ✓",
},
{
name: "legacy bare model id fallback still marks current model",
currentModel: "claude-sonnet-4",
firstText: "claude-sonnet-4 ✓",
},
] as const; for (const testCase of cases) { const result = buildModelsKeyboard({
provider: "anthropic",
models: ["claude-sonnet-4", "claude-opus-4"],
currentModel: testCase.currentModel,
currentPage: 1,
totalPages: 1,
}); // 2 model rows + back button
expect(result, testCase.name).toHaveLength(3);
expect(result[0]?.[0]?.text).toBe(testCase.firstText);
expect(result[0]?.[0]?.callback_data).toBe("mdl_sel_anthropic/claude-sonnet-4");
expect(result[1]?.[0]?.text).toBe("claude-opus-4");
expect(result[2]?.[0]?.text).toBe("<< Back");
}
});
it("uses modelNames for display text when provided", () => { const modelNames = new Map([
["nexos/a1b2c3d4-e5f6-7890-abcd-ef1234567890", "Claude Sonnet 4"],
["nexos/claude-opus-4", "Claude Opus 4"],
]); const result = buildModelsKeyboard({
provider: "nexos",
models: ["a1b2c3d4-e5f6-7890-abcd-ef1234567890", "claude-opus-4"],
currentPage: 1,
totalPages: 1,
modelNames,
}); // 2 model rows + back button
expect(result).toHaveLength(3);
expect(result[0]?.[0]?.text).toBe("Claude Sonnet 4");
expect(result[1]?.[0]?.text).toBe("Claude Opus 4"); // callback_data still uses the raw model ID, not the display name
expect(result[0]?.[0]?.callback_data).toBe( "mdl_sel_nexos/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
);
});
it("falls back to model ID when modelNames does not contain an entry", () => { const modelNames = new Map([["anthropic/known-id", "Known Model"]]); const result = buildModelsKeyboard({
provider: "anthropic",
models: ["known-id", "unknown-id"],
currentPage: 1,
totalPages: 1,
modelNames,
});
expect(result[0]?.[0]?.text).toBe("Known Model");
expect(result[1]?.[0]?.text).toBe("unknown-id");
});
it("does not mark same-id models from other providers as current", () => { const result = buildModelsKeyboard({
provider: "openai-codex",
models: ["gpt-5.4", "gpt-5.3-codex-spark"],
currentModel: "github-copilot/gpt-5.4",
currentPage: 1,
totalPages: 1,
});
for (const row of result) { for (const button of row) { const bytes = Buffer.byteLength(button.callback_data, "utf8");
expect(bytes).toBeLessThanOrEqual(64);
}
}
});
it("skips models that would exceed callback_data limit", () => { const models = [ "short-model", "this-is-an-extremely-long-model-name-that-definitely-exceeds-the-sixty-four-byte-limit", "another-short",
]; const result = buildModelsKeyboard({
provider: "openrouter",
models,
currentPage: 1,
totalPages: 1,
});
// Should have 2 model buttons (skipping the long one) + back const modelButtons = result.filter((row) => !row[0]?.callback_data.startsWith("mdl_back"));
expect(modelButtons.length).toBe(2);
expect(modelButtons[0]?.[0]?.text).toBe("short-model");
expect(modelButtons[1]?.[0]?.text).toBe("another-short");
});
});
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-13)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.