fix(models): handle out-of-range pages
This commit is contained in:
@@ -74,11 +74,20 @@ describe("/models command", () => {
|
|||||||
const result = await handleCommands(params);
|
const result = await handleCommands(params);
|
||||||
expect(result.shouldContinue).toBe(false);
|
expect(result.shouldContinue).toBe(false);
|
||||||
expect(result.reply?.text).toContain("Models (anthropic)");
|
expect(result.reply?.text).toContain("Models (anthropic)");
|
||||||
|
expect(result.reply?.text).toContain("page 1/");
|
||||||
expect(result.reply?.text).toContain("anthropic/claude-opus-4-5");
|
expect(result.reply?.text).toContain("anthropic/claude-opus-4-5");
|
||||||
expect(result.reply?.text).toContain("Switch: /model <provider/model>");
|
expect(result.reply?.text).toContain("Switch: /model <provider/model>");
|
||||||
expect(result.reply?.text).toContain("All: /models anthropic all");
|
expect(result.reply?.text).toContain("All: /models anthropic all");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("errors on out-of-range pages", async () => {
|
||||||
|
const params = buildParams("/models anthropic 4", cfg);
|
||||||
|
const result = await handleCommands(params);
|
||||||
|
expect(result.shouldContinue).toBe(false);
|
||||||
|
expect(result.reply?.text).toContain("Page out of range");
|
||||||
|
expect(result.reply?.text).toContain("valid: 1-");
|
||||||
|
});
|
||||||
|
|
||||||
it("handles unknown providers", async () => {
|
it("handles unknown providers", async () => {
|
||||||
const params = buildParams("/models not-a-provider", cfg);
|
const params = buildParams("/models not-a-provider", cfg);
|
||||||
const result = await handleCommands(params);
|
const result = await handleCommands(params);
|
||||||
|
|||||||
@@ -143,23 +143,44 @@ export const handleModelsCommand: CommandHandler = async (params, allowTextComma
|
|||||||
const models = [...(byProvider.get(provider) ?? new Set<string>())].sort();
|
const models = [...(byProvider.get(provider) ?? new Set<string>())].sort();
|
||||||
const total = models.length;
|
const total = models.length;
|
||||||
|
|
||||||
|
if (total === 0) {
|
||||||
|
const lines: string[] = [
|
||||||
|
`Models (${provider}) — none`,
|
||||||
|
"",
|
||||||
|
"Browse: /models",
|
||||||
|
"Switch: /model <provider/model>",
|
||||||
|
];
|
||||||
|
return { reply: { text: lines.join("\n") }, shouldContinue: false };
|
||||||
|
}
|
||||||
|
|
||||||
const effectivePageSize = all ? total : pageSize;
|
const effectivePageSize = all ? total : pageSize;
|
||||||
const startIndex = (page - 1) * effectivePageSize;
|
const pageCount = effectivePageSize > 0 ? Math.ceil(total / effectivePageSize) : 1;
|
||||||
|
const safePage = all ? 1 : Math.max(1, Math.min(page, pageCount));
|
||||||
|
|
||||||
|
if (!all && page !== safePage) {
|
||||||
|
const lines: string[] = [
|
||||||
|
`Page out of range: ${page} (valid: 1-${pageCount})`,
|
||||||
|
"",
|
||||||
|
`Try: /models ${provider} ${safePage}`,
|
||||||
|
`All: /models ${provider} all`,
|
||||||
|
];
|
||||||
|
return { reply: { text: lines.join("\n") }, shouldContinue: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
const startIndex = (safePage - 1) * effectivePageSize;
|
||||||
const endIndexExclusive = Math.min(total, startIndex + effectivePageSize);
|
const endIndexExclusive = Math.min(total, startIndex + effectivePageSize);
|
||||||
const pageModels = models.slice(startIndex, endIndexExclusive);
|
const pageModels = models.slice(startIndex, endIndexExclusive);
|
||||||
|
|
||||||
const header = `Models (${provider}) — showing ${startIndex + 1}-${endIndexExclusive} of ${total}`;
|
const header = `Models (${provider}) — showing ${startIndex + 1}-${endIndexExclusive} of ${total} (page ${safePage}/${pageCount})`;
|
||||||
|
|
||||||
const lines: string[] = [header];
|
const lines: string[] = [header];
|
||||||
for (const id of pageModels) {
|
for (const id of pageModels) {
|
||||||
lines.push(`- ${provider}/${id}`);
|
lines.push(`- ${provider}/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageCount = effectivePageSize > 0 ? Math.ceil(total / effectivePageSize) : 1;
|
|
||||||
|
|
||||||
lines.push("", "Switch: /model <provider/model>");
|
lines.push("", "Switch: /model <provider/model>");
|
||||||
if (!all && page < pageCount) {
|
if (!all && safePage < pageCount) {
|
||||||
lines.push(`More: /models ${provider} ${page + 1}`);
|
lines.push(`More: /models ${provider} ${safePage + 1}`);
|
||||||
}
|
}
|
||||||
if (!all) {
|
if (!all) {
|
||||||
lines.push(`All: /models ${provider} all`);
|
lines.push(`All: /models ${provider} all`);
|
||||||
|
|||||||
Reference in New Issue
Block a user