refactor(quality-score): update provider prestige logic and adjust top-K size for improved candidate selection

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-07-24 16:16:12 -07:00
parent 5f55cee7df
commit ab05d74071
3 changed files with 64 additions and 40 deletions

View file

@ -26,8 +26,10 @@ from __future__ import annotations
# Tunables (constants, not flags)
# ---------------------------------------------------------------------------
# Top-K size for deterministic spread inside the locked tier.
_QUALITY_TOP_K: int = 5
# Top-K size for deterministic spread inside the locked tier. Auto only
# ever pins one of the K best-scoring candidates, so this is the effective
# "shortlist" size regardless of how large the OpenRouter catalogue is.
_QUALITY_TOP_K: int = 4
# Hard health gate: any cfg whose best non-null uptime is below this %
# is excluded from Auto-mode selection entirely.
@ -74,39 +76,20 @@ _TINY_LEGACY_PENALTY_PATTERNS: tuple[str, ...] = (
# ---------------------------------------------------------------------------
# OpenRouter-side provider slug (the prefix before ``/`` in the model id).
# Tiers are coarse: frontier labs > strong open / fast-moving labs >
# specialist labs > everything else.
# Deliberately frontier-labs-only: anything not listed falls through to the
# neutral default (15) so smaller labs can't out-prestige the big four and
# crowd into the Auto top-K shortlist.
PROVIDER_PRESTIGE_OR: dict[str, int] = {
# Frontier labs
"openai": 50,
"anthropic": 50,
"google": 50,
"x-ai": 50,
# Strong open / fast-moving labs
"deepseek": 38,
"qwen": 38,
"meta-llama": 38,
"mistralai": 38,
"cohere": 38,
"nvidia": 38,
"alibaba": 38,
# Specialist / regional / strong second-tier
"microsoft": 28,
"01-ai": 28,
"minimax": 28,
"moonshot": 28,
"z-ai": 28,
"nousresearch": 28,
"ai21": 28,
"perplexity": 28,
# Smaller / niche providers
"liquid": 18,
"cognitivecomputations": 18,
"venice": 18,
"inflection": 18,
}
# YAML provider field (the upstream API shape the operator selected).
# Frontier-labs-only, mirroring PROVIDER_PRESTIGE_OR; unlisted providers get
# the neutral default (15). ``ollama_chat`` / ``custom`` stay listed because
# they sit *below* the default — removing them would raise their score.
PROVIDER_PRESTIGE_YAML: dict[str, int] = {
"azure": 50,
"openai": 50,
@ -114,16 +97,6 @@ PROVIDER_PRESTIGE_YAML: dict[str, int] = {
"gemini": 50,
"vertex_ai": 50,
"xai": 50,
"mistral": 38,
"deepseek": 38,
"cohere": 38,
"groq": 30,
"together_ai": 28,
"fireworks_ai": 28,
"perplexity": 28,
"bedrock": 28,
"openrouter": 25,
"requesty": 25,
"ollama_chat": 12,
"custom": 12,
}

View file

@ -0,0 +1,40 @@
/**
* Self-check: the app must run on ONE jotai store.
*
* Regression guard for the "screenshot never sent" bug: wrapping the tree in
* jotai-tanstack-query's QueryClientAtomProvider mounted a second jotai
* <Provider> store, so hook writes (pending screenshot data URLs, mentions)
* were invisible to the chat stream engine's getDefaultStore() reads and
* user_images arrived empty at the backend.
*
* Run: pnpm exec tsx lib/query-client/query-client.provider.check.tsx
*/
import assert from "node:assert";
import { getDefaultStore, useStore } from "jotai";
import { queryClientAtom } from "jotai-tanstack-query";
import { renderToString } from "react-dom/server";
import { ReactQueryClientProvider } from "./query-client.provider";
let seenStore: unknown;
function Probe() {
seenStore = useStore();
return null;
}
renderToString(
<ReactQueryClientProvider>
<Probe />
</ReactQueryClientProvider>
);
assert.strictEqual(
seenStore,
getDefaultStore(),
"jotai hooks inside ReactQueryClientProvider must use the default store " +
"(a nested jotai <Provider> would hide composer atom writes from the chat engine)"
);
assert.ok(
getDefaultStore().get(queryClientAtom),
"queryClientAtom must be hydrated into the default store"
);
console.log("OK: single jotai store, queryClientAtom hydrated");

View file

@ -1,5 +1,7 @@
"use client";
import { QueryClientAtomProvider } from "jotai-tanstack-query/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { getDefaultStore } from "jotai";
import { queryClientAtom } from "jotai-tanstack-query";
import dynamic from "next/dynamic";
import { queryClient } from "./client";
@ -8,11 +10,20 @@ const ReactQueryDevtools = dynamic(
{ ssr: false }
);
// Do NOT use jotai-tanstack-query's QueryClientAtomProvider here: it mounts
// its own jotai <Provider>, which creates a SECOND jotai store for the React
// tree. Hook writes (e.g. pending screenshot data URLs, @-mentions) then land
// in that provider store while the chat stream engine reads via
// getDefaultStore(), so user_images silently arrived empty at the backend.
// Instead, keep the whole app on the one default store and hydrate the
// query-client atom into it directly.
getDefaultStore().set(queryClientAtom, queryClient);
export function ReactQueryClientProvider({ children }: { children: React.ReactNode }) {
return (
<QueryClientAtomProvider client={queryClient}>
<QueryClientProvider client={queryClient}>
{children}
{process.env.NODE_ENV === "development" && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientAtomProvider>
</QueryClientProvider>
);
}