This commit is contained in:
Rick 2026-11-05 05:44:34 +00:00 • committed by GitHub
commit bdeb681adf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 25 deletions

View file

@ -368,7 +368,24 @@ describe("Request ID column", () => {
});
describe("Model column", () => {
it("lists every model used across a conversation, not only the representative call's model", () => {
it("keeps a long conversation's inline cell to the latest call's model", () => {
const conversationCall: Partial<LogEntry> = {
request_id: "req-session",
model: "gpt-5.6",
session_id: "sess-1",
session_total_count: 4,
session_models: ["claude-sonnet-5", "gemini-3-pro", "gpt-5.6", "o4-mini"],
};
renderRows([logEntry(conversationCall)]);
expect(screen.getByText("gpt-5.6")).toBeInTheDocument();
for (const otherModel of ["claude-sonnet-5", "gemini-3-pro", "o4-mini"]) {
expect(screen.queryByText(otherModel)).not.toBeInTheDocument();
}
});
it("reveals the conversation's other models in the hover popup", async () => {
const user = userEvent.setup();
const conversationCall: Partial<LogEntry> = {
request_id: "req-session",
model: "gpt-5.6",
@ -378,12 +395,14 @@ describe("Model column", () => {
};
renderRows([logEntry(conversationCall)]);
expect(screen.getByText("claude-sonnet-5, gpt-5.6")).toBeInTheDocument();
expect(screen.queryByText("gpt-5.6")).not.toBeInTheDocument();
await user.hover(screen.getByText("+1"));
expect(await screen.findByText("claude-sonnet-5")).toBeInTheDocument();
});
it("marks a conversation whose model list was capped by the server", () => {
const cappedCall = {
it("flags a conversation whose model list was capped by the server", async () => {
const user = userEvent.setup();
const cappedCall: Partial<LogEntry> = {
request_id: "req-capped",
model: "gpt-5.6",
session_id: "sess-2",
@ -393,13 +412,16 @@ describe("Model column", () => {
};
renderRows([logEntry(cappedCall)]);
expect(screen.getByText("claude-sonnet-5, gpt-5.6, ...")).toBeInTheDocument();
await user.hover(screen.getByText("+1"));
expect(await screen.findByText("More models not shown")).toBeInTheDocument();
});
it("keeps a single call's own model", () => {
it("keeps a single call's own model and shows no overflow marker", () => {
renderRows([logEntry({ request_id: "req-single", model: "gpt-5.6" })]);
expect(screen.getByText("gpt-5.6")).toBeInTheDocument();
expect(screen.queryByText(/^\+\d+$/)).not.toBeInTheDocument();
});
});

View file

@ -329,28 +329,42 @@ export const getRequestLogsTableColumns = (
enableSorting: true,
cell: ({ row }) => {
const log = row.original;
const provider = log.custom_llm_provider;
const sessionModels = log.session_models ?? [];
const modelNames = sessionModels.length > 0 ? sessionModels : [log.model ?? ""];
const modelLabel = log.session_models_truncated ? `${modelNames.join(", ")}, ...` : modelNames.join(", ");
const isSingleModel = modelNames.length === 1;
const latestModel = log.model || sessionModels[0] || "";
const otherModels = sessionModels.filter((model) => model !== latestModel);
const models = [latestModel, ...otherModels].filter((model) => model !== "");
if (models.length === 0) return <span className="text-muted-foreground">-</span>;
return (
<div className="flex items-center space-x-2">
{provider && isSingleModel && (
<img
src={getLogoUrl(log, provider)}
alt=""
className="w-4 h-4"
onError={(event) => {
event.currentTarget.style.display = "none";
}}
/>
)}
<div className="flex min-w-0 items-center">
<CellTooltip
content={modelLabel}
content={
<div className="flex max-w-[280px] flex-col gap-0.5">
{models.map((model) => (
<span key={model}>{model}</span>
))}
{log.session_models_truncated === true && (
<span className="text-muted-foreground">More models not shown</span>
)}
</div>
}
trigger={
<span className={isSingleModel ? "max-w-[15ch] truncate block" : "min-w-0 truncate block"}>
{modelLabel}
<span className="inline-flex min-w-0 items-center gap-1.5">
{log.custom_llm_provider && (
<img
src={getLogoUrl(log, log.custom_llm_provider)}
alt=""
className="w-4 h-4 shrink-0"
onError={(event) => {
event.currentTarget.style.display = "none";
}}
/>
)}
<span className="max-w-[22ch] truncate">{latestModel}</span>
{otherModels.length > 0 && (
<span className="shrink-0 rounded-full border border-border px-1 text-[10px] leading-4 text-muted-foreground">
+{otherModels.length}
</span>
)}
</span>
}
/>