mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 04:42:10 +03:00
fix(logs): avoid giant provider pills for failed auto family requests (#8867)
* fix(logs): avoid giant provider pills for failed auto family requests * refactor(logs): extract resolveRejectedComboProvider + cover it The provider label was decided inline in handleChat, which has no test harness — the change shipped untested and pushed chat.ts over its frozen size (1848 > 1845). Moved to rejectedRequestUsage.ts next to summarizeComboAttemptedModels, the helper it replaces on this path. chat.ts shrinks back under its baseline (no rebaseline needed) and the logic gets three cases in the suite that already covers its sibling: auto/* collapses to "auto", a named combo keeps its name, and bare "auto" (no slash) is NOT collapsed — that one is a combo request, not a family request. Also rebased on the current release tip and added the changelog fragment. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com> Co-authored-by: rafaeldrincon <rafaeldrincon@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
1
changelog.d/fixes/8867-rejected-combo-provider-label.md
Normal file
1
changelog.d/fixes/8867-rejected-combo-provider-label.md
Normal file
@@ -0,0 +1 @@
|
||||
- **Logs**: a failed `auto/<family>` request no longer writes every attempted model into `call_logs.provider` — the logs page builds its quick-filter pills from that column, so one failure produced a giant chip that flooded the filter row. Rejected combo requests are now labelled `auto` (for `auto/*`) or by the combo's own name
|
||||
@@ -908,13 +908,13 @@ export async function handleChat(
|
||||
// (success:false) so gate/breaker-rejected traffic is counted per key — support-mesh 2026-07-08.
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const { recordRejectedRequestUsage, summarizeComboAttemptedModels } =
|
||||
const { recordRejectedRequestUsage, resolveRejectedComboProvider } =
|
||||
await import("./rejectedRequestUsage");
|
||||
await recordRejectedRequestUsage({
|
||||
status: response.status,
|
||||
model: body?.model || resolvedModelStr,
|
||||
requestedModel: body?.model || resolvedModelStr,
|
||||
provider: summarizeComboAttemptedModels(combo?.models),
|
||||
provider: resolveRejectedComboProvider(body?.model || resolvedModelStr, combo.name),
|
||||
endpoint: clientRawRequest?.endpoint,
|
||||
error: await getComboFailureLogError(response, combo.name),
|
||||
comboName: combo.name,
|
||||
|
||||
@@ -127,3 +127,20 @@ export function summarizeComboAttemptedModels(models: unknown): string {
|
||||
.filter((entry): entry is string => Boolean(entry));
|
||||
return modelStrings.length > 0 ? modelStrings.join(", ") : "-";
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider label for a REJECTED combo request (#8867).
|
||||
*
|
||||
* summarizeComboAttemptedModels() joins every attempted model, which is right for
|
||||
* diagnostics but wrong for `call_logs.provider`: the logs page builds its quick-filter
|
||||
* pills from that column, so one failed `auto/gemma` turned into a chip listing a dozen
|
||||
* models and flooded the filter row. Keep it short and categorical instead — `auto` for
|
||||
* auto/* requests, otherwise the combo's own name.
|
||||
*/
|
||||
export function resolveRejectedComboProvider(
|
||||
model: string | null | undefined,
|
||||
comboName: string | null | undefined
|
||||
): string {
|
||||
if (typeof model === "string" && model.startsWith("auto/")) return "auto";
|
||||
return comboName || "combo";
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ process.env.DATA_DIR = TEST_DATA_DIR;
|
||||
const core = await import("../../src/lib/db/core.ts");
|
||||
const usageHistory = await import("../../src/lib/usage/usageHistory.ts");
|
||||
const callLogs = await import("../../src/lib/usage/callLogs.ts");
|
||||
const { recordRejectedRequestUsage, summarizeComboAttemptedModels } =
|
||||
const { recordRejectedRequestUsage, summarizeComboAttemptedModels, resolveRejectedComboProvider } =
|
||||
await import("../../src/sse/handlers/rejectedRequestUsage.ts");
|
||||
|
||||
test.beforeEach(() => {
|
||||
@@ -175,3 +175,24 @@ test("summarizeComboAttemptedModels falls back to '-' for empty, missing, or inv
|
||||
assert.equal(summarizeComboAttemptedModels("not-an-array"), "-");
|
||||
assert.equal(summarizeComboAttemptedModels([{ kind: "combo-ref" }, { foo: "bar" }]), "-");
|
||||
});
|
||||
|
||||
test("#8867: resolveRejectedComboProvider keeps the provider label short for auto/* failures", () => {
|
||||
// The logs page builds quick-filter pills from call_logs.provider — a failed
|
||||
// auto/<family> used to write every attempted model there and flood the filter row.
|
||||
assert.equal(resolveRejectedComboProvider("auto/gemma", "my-combo"), "auto");
|
||||
assert.equal(resolveRejectedComboProvider("auto/gemini", null), "auto");
|
||||
assert.equal(resolveRejectedComboProvider("auto/anything-at-all", undefined), "auto");
|
||||
});
|
||||
|
||||
test("#8867: a non-auto combo failure is labelled with the combo name", () => {
|
||||
assert.equal(resolveRejectedComboProvider("gpt-5.6-sol", "balanced-load"), "balanced-load");
|
||||
assert.equal(resolveRejectedComboProvider(null, "balanced-load"), "balanced-load");
|
||||
});
|
||||
|
||||
test("#8867: falls back to 'combo' when there is no name, and 'auto' never leaks into it", () => {
|
||||
assert.equal(resolveRejectedComboProvider("gpt-5.6-sol", null), "combo");
|
||||
assert.equal(resolveRejectedComboProvider(undefined, undefined), "combo");
|
||||
assert.equal(resolveRejectedComboProvider("", ""), "combo");
|
||||
// bare "auto" (no slash) is NOT a family request — it must not be collapsed
|
||||
assert.equal(resolveRejectedComboProvider("auto", "named-combo"), "named-combo");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user