fix(frontend): show session catalog in pi management
This commit is contained in:
@@ -23,7 +23,10 @@ function renderManagement() {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
server.use(http.get("/api/pi-management/status", () => HttpResponse.json(readyStatus)));
|
||||
server.use(
|
||||
http.get("/api/pi-management/status", () => HttpResponse.json(readyStatus)),
|
||||
http.get("/api/models", () => HttpResponse.json({ models: [] })),
|
||||
);
|
||||
});
|
||||
|
||||
test("shows the catalog default as read-only installation state", async () => {
|
||||
@@ -49,6 +52,22 @@ test("shows the catalog default as read-only installation state", async () => {
|
||||
expect(document.querySelector('input[type="password"]')).toBeNull();
|
||||
});
|
||||
|
||||
test("shows every session model exposed by Core", async () => {
|
||||
server.use(http.get("/api/models", () => HttpResponse.json({ models: [
|
||||
{ provider: "zai", id: "glm-5.3", name: "GLM 5.3", reasoning: true },
|
||||
{ provider: "deepseek", id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", reasoning: true },
|
||||
{ provider: "deepseek", id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", reasoning: true },
|
||||
{ provider: "local-qwen", id: "qwen3.6-35b-a3b", name: "Local Qwen 3.6 35B A3B", reasoning: false },
|
||||
] })));
|
||||
renderManagement();
|
||||
|
||||
const catalog = await screen.findByRole("region", { name: "Session models" });
|
||||
expect(catalog).toHaveTextContent("GLM 5.3");
|
||||
expect(catalog).toHaveTextContent("DeepSeek V4 Pro");
|
||||
expect(catalog).toHaveTextContent("DeepSeek V4 Flash");
|
||||
expect(catalog).toHaveTextContent("Local Qwen 3.6 35B A3B");
|
||||
});
|
||||
|
||||
test("tests the catalog default without mutating credential presence", async () => {
|
||||
const user = userEvent.setup();
|
||||
let tests = 0;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getPiManagementStatus,
|
||||
runPiManagementTest,
|
||||
} from "../api/pi-management";
|
||||
import { listModels } from "../api/models";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { WorkAreaPanel } from "./WorkAreaPanel";
|
||||
|
||||
@@ -280,6 +281,7 @@ export function PiManagement({ open, onClose }: { open: boolean; onClose: () =>
|
||||
const [smokeState, setSmokeState] = useState<SmokeState>();
|
||||
const [logsRequested, setLogsRequested] = useState(false);
|
||||
const statusQuery = useQuery({ queryKey: ["pi-management", "status"], queryFn: getPiManagementStatus, enabled: open });
|
||||
const modelsQuery = useQuery({ queryKey: ["models"], queryFn: listModels, enabled: open });
|
||||
const logsQuery = useQuery({ queryKey: ["pi-management", "logs"], queryFn: getPiManagementLogs, enabled: open && logsRequested });
|
||||
const catalogReady = Boolean(
|
||||
statusQuery.data?.config.provider
|
||||
@@ -402,6 +404,44 @@ export function PiManagement({ open, onClose }: { open: boolean; onClose: () =>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<section aria-label="Session models" className="border-t border-border/70 pt-5">
|
||||
<div className="flex flex-wrap items-baseline justify-between gap-2">
|
||||
<div>
|
||||
<h3 className="font-heading text-sm font-semibold">Session models</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">Models currently available for interactive sessions in this installation.</p>
|
||||
</div>
|
||||
{modelsQuery.data && (
|
||||
<span className="font-mono text-xs tabular-nums text-muted-foreground">{modelsQuery.data.models.length} available</span>
|
||||
)}
|
||||
</div>
|
||||
{modelsQuery.isLoading ? (
|
||||
<p className="mt-4 text-sm text-muted-foreground">Loading session models…</p>
|
||||
) : modelsQuery.isError ? (
|
||||
<div className="mt-4 flex flex-wrap items-center justify-between gap-3" role="alert">
|
||||
<p className="text-sm text-destructive">Could not load the session model catalog.</p>
|
||||
<Button size="sm" variant="ghost" onClick={() => { void modelsQuery.refetch(); }}>Retry models</Button>
|
||||
</div>
|
||||
) : modelsQuery.data?.models.length ? (
|
||||
<ul className="mt-4 divide-y divide-border/70 border-y border-border/70">
|
||||
{modelsQuery.data.models.map((model) => {
|
||||
const isDefault = statusQuery.data.config.provider === model.provider
|
||||
&& statusQuery.data.config.model === model.id;
|
||||
return (
|
||||
<li key={model.provider + "/" + model.id} className="flex min-w-0 items-center justify-between gap-4 py-3">
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-sm font-semibold" title={model.name}>{model.name}</p>
|
||||
<p className="mt-0.5 truncate font-mono text-xs text-muted-foreground" title={model.provider + "/" + model.id}>{model.provider}/{model.id}</p>
|
||||
</div>
|
||||
{isDefault && <span className="shrink-0 rounded-md bg-muted px-2 py-1 text-xs font-semibold text-foreground">Default</span>}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
) : (
|
||||
<p className="mt-4 text-sm text-muted-foreground">No session models are configured for this installation.</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<section aria-label="Sanitized diagnostics" className="border-t border-border/70 pt-5">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div><h3 className="font-heading text-sm font-semibold">Sanitized diagnostics</h3><p className="mt-1 text-sm text-muted-foreground">Shows at most 200 recent lines with declared secret values removed.</p></div>
|
||||
|
||||
Reference in New Issue
Block a user