Show how each bot message was generated

Every bot message gets an info button that opens its details: the
provider and model behind it, tokens and cost, the job that ran it, each
model used and every call in order. Each model call now records how it
was made in token_usages.settings (generation settings sent, whose
settings they were, pinned or automatic model, fallbacks), shown per
model in the modal.

Live replies now carry their token usage, from the job's push and the
live relay alike, so it shows without a reload.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-25 04:33:47 +01:00
co-authored by Claude Opus 5.5
parent feec69adca
commit c13b9ea826
48 changed files with 1307 additions and 57 deletions
@@ -44,6 +44,24 @@ describe("buildUsageCall", () => {
prompt_tokens: 1200,
completion_tokens: 340,
cost: 0.0042,
settings: { model_source: "auto" },
});
});
test("keeps the settings sent and the models that failed first", () => {
const call = buildUsageCall({
harness: "text",
candidate: candidate({ source: "pinned" }),
settings: { settings_source: "bot", params: { temperature: 0.3 }, max_tokens: 800 },
failed: ["2:other/model"],
});
expect(call.settings).toEqual({
model_source: "pinned",
settings_source: "bot",
params: { temperature: 0.3 },
max_tokens: 800,
fell_back_from: ["2:other/model"],
});
});
+19 -3
View File
@@ -1,18 +1,29 @@
import type { HarnessCandidate, HarnessUsage } from "../types";
import type { HarnessUsageCall } from "./types";
import type { HarnessCallSettings, HarnessUsageCall } from "./types";
type Params = {
harness: HarnessUsageCall["harness"];
candidate: HarnessCandidate;
usage?: HarnessUsage;
/**
* How the call was made beyond the model: the settings it sent and
* whose they were. The model's source and the fallback are filled in
* here.
*/
settings?: Omit<HarnessCallSettings, "model_source" | "fell_back_from">;
/**
* The candidates that failed before this one (`withCandidates`).
*/
failed?: string[];
};
/**
* The candidate that really answered a call, and what it reported, as the
* row `recordHarnessUsage` writes. Providers that report no usage at all
* still get a row (no tokens), so a call is never invisible.
* still get a row (no tokens), so a call is never invisible. Its settings
* say how it was made, for a message's details.
*/
export default function buildUsageCall({ harness, candidate, usage }: Params): HarnessUsageCall {
export default function buildUsageCall({ harness, candidate, usage, settings, failed }: Params): HarnessUsageCall {
return {
harness,
provider_id: candidate.provider.id,
@@ -22,6 +33,11 @@ export default function buildUsageCall({ harness, candidate, usage }: Params): H
prompt_tokens: Number(usage?.prompt_tokens) || 0,
completion_tokens: Number(usage?.completion_tokens) || 0,
cost: typeof usage?.cost == "number" && Number.isFinite(usage.cost) ? usage.cost : undefined,
settings: {
model_source: candidate.source,
...settings,
...(failed?.length ? { fell_back_from: failed } : {}),
},
};
}
@@ -0,0 +1,20 @@
import { describe, expect, test } from "bun:test";
import flattenSentParams from "./flatten-sent-params";
describe("flattenSentParams", () => {
test("reads the nested reasoning effort back by its setting key", () => {
expect(flattenSentParams({ params: { temperature: 0.3, reasoning: { effort: "high" } } })).toEqual({
temperature: 0.3,
reasoning_effort: "high",
});
});
test("keeps a zero and drops empty fields", () => {
expect(flattenSentParams({ params: { temperature: 0, seed: "" } })).toEqual({ temperature: 0 });
});
test("is undefined when nothing was sent", () => {
expect(flattenSentParams({ params: {} })).toBeUndefined();
expect(flattenSentParams({ params: null })).toBeUndefined();
});
});
+26
View File
@@ -0,0 +1,26 @@
type Params = {
/**
* Keyed by the field sent on the wire (`grabChatParams`).
*/
params?: Record<string, number | string | { effort: string }> | null;
};
/**
* The generation settings a call sent, keyed by their setting
* (`HarnessParameters`) rather than the wire: OpenRouter's nested
* `reasoning: { effort }` reads back as `reasoning_effort`. Empty fields
* are left out; undefined when nothing was sent.
*/
export default function flattenSentParams({ params }: Params) {
const flat: Record<string, number | string> = {};
for (const [key, value] of Object.entries(params || {})) {
if (value && typeof value == "object") {
if (value.effort) flat[key == "reasoning" ? "reasoning_effort" : key] = String(value.effort);
} else if (typeof value == "number" || (typeof value == "string" && value)) {
flat[key] = value;
}
}
return Object.keys(flat).length ? flat : undefined;
}
@@ -52,6 +52,7 @@ export default async function recordHarnessUsage({ scope, call }: Params) {
prompt_tokens: Math.max(0, Math.round(call.prompt_tokens || 0)),
completion_tokens: Math.max(0, Math.round(call.completion_tokens || 0)),
cost: typeof call.cost == "number" && Number.isFinite(call.cost) ? call.cost : undefined,
settings: call.settings ? JSON.stringify(call.settings) : undefined,
};
try {
+28
View File
@@ -30,6 +30,33 @@ export type HarnessUsageScope = {
* asked, and which candidate answered. Both are filled in by the call's
* own entry point, never by the code that runs it.
*/
export type HarnessCallSettings = {
/**
* `pinned`: the model picked in the setting. `auto`: an automatic pick.
*/
model_source: "pinned" | "auto";
/**
* Whose setting the call used: the workspace's, the bot's own or the
* install's default. Left out when the call overrode it.
*/
settings_source?: "default" | "bot" | "workspace";
/**
* The generation settings sent, by their setting key
* (`HarnessParameters`: `temperature`, `reasoning_effort`, ...).
*/
params?: Record<string, number | string>;
max_tokens?: number;
/**
* The voice asked for (speech).
*/
voice?: string;
/**
* The candidates (`<provider id>:<slug>`) that failed before this one
* answered, in the order they were tried.
*/
fell_back_from?: string[];
};
export type HarnessUsageCall = {
harness: "text" | "vision" | "transcription" | "speech" | "image" | "embedding";
provider_id?: number;
@@ -39,6 +66,7 @@ export type HarnessUsageCall = {
prompt_tokens: number;
completion_tokens: number;
cost?: number;
settings?: HarnessCallSettings;
};
/**