Skip to content

feat(consensus): swap dead Kimi for NanoGPT + 48h stale-hide gate (L1) - #3172

Open
0motionguy wants to merge 1 commit into
mainfrom
feat/L1-consensus-nanogpt-plus-stale-hide
Open

0motionguy wants to merge 1 commit into
mainfrom
feat/L1-consensus-nanogpt-plus-stale-hide

Conversation

@0motionguy

Copy link
Copy Markdown
Owner

Summary

  • Swap consensus-analyst from dead Kimi-For-Coding to NanoGPT (Kimi-K2-Instruct via OpenAI-compatible chat). Keeps Kimi as a fallback when only KIMI_API_KEY is set.
  • Hard-enforce no publicly stale batches with a 48h TTL gate (CONSENSUS_MAX_AGE_HOURS, default 48). New getFreshConsensusVerdictsPayload() returns EMPTY past TTL; getConsensusItemReport() returns null past TTL.
  • Restores 498 stale verdicts that have been frozen since Kimi's quota broke.

Why now

Part of the ULTRA improvement plan derived from the deep-crawl harness shipped to toolbox in PR (pending). Phase 4 §4.1 always-ship row — L1 is independent of the deep-crawl deltas because Kimi is dead regardless of competitor evidence. The 48h stale-hide gate also implements the user-added hard rule: no publicly stale batches across TrendingRepo.

Files

Worker:

  • apps/trendingrepo-worker/src/lib/env.ts — add NANOGPT_API_KEY / NANOGPT_BASE_URL / NANOGPT_MODEL, widen LLM_PROVIDER enum, add CONSENSUS_MAX_AGE_HOURS.
  • apps/trendingrepo-worker/src/fetchers/consensus-analyst/llm.ts — rewrite client (NanoGPT primary, Kimi fallback). activeProvider() reports active.
  • apps/trendingrepo-worker/src/fetchers/consensus-analyst/index.ts — record actual provider + model on emitted payload (was hardcoded to kimi-k2-0711-preview).
  • apps/trendingrepo-worker/src/lib/llm/router.ts — unrelated LLM router; narrowed to 'kimi'|'openrouter' after the enum widen (consensus-analyst doesn't use this router).

Web (selector + consumer):

  • src/lib/consensus-verdicts.tsConsensusGenerator type, isConsensusPayloadFresh(), getFreshConsensusVerdictsPayload().
  • src/app/consensus/page.tsx — public consumer now uses fresh-only accessor.
  • src/components/consensus/DailyVerdictPanel.tsx — widened prop type + new "AI / NANOGPT KIMI-K2" label.

Test plan

  • pnpm --filter trendingrepo-worker tsc --noEmit clean
  • pnpm tsc --noEmit clean (existing .next/types errors unrelated)
  • Set NANOGPT_API_KEY in worker prod env → run consensus-analyst fetcher → verify consensus-verdicts payload has "generator":"nanogpt" and "model":"moonshotai/Kimi-K2-Instruct"
  • Verify /consensus page after fetcher publishes — Daily Verdict panel shows "AI / NANOGPT KIMI-K2"
  • Force stale payload (set CONSENSUS_MAX_AGE_HOURS=0) → confirm homepage renders empty/degraded state, not a stale ribbon

Evidence

Phase 4.1 always-ship row from the ULTRA improvement plan. Deep-crawl harness PR (pending) at c:/dev/toolbox/scripts/competitor-deep-crawl/. The Kimi quota failure has been visible in the production consensus-verdicts payload (last computedAt ~Jun 1) since the LLM router stopped accepting User-Agent claude-cli/1.0 reliably.

🤖 Generated with Claude Code

The Kimi For Coding subscription stopped serving the consensus-analyst
worker reliably for server-side use, leaving 498 verdicts stale. Swap
the LLM provider to NanoGPT (Kimi-K2-Instruct via OpenAI-compatible
chat completions), keep Kimi as a fallback when only KIMI_API_KEY is
set, and tag the generator on the payload accordingly.

Hard rule alongside the swap: no publicly stale batches. Add a
48-hour TTL gate (CONSENSUS_MAX_AGE_HOURS, default 48) on the read
path — `getConsensusItemReport()` returns null past TTL and the new
`getFreshConsensusVerdictsPayload()` returns EMPTY rather than
rendering a stale ribbon. The public /consensus page now uses the
fresh-only accessor.

Worker (env, llm, fetcher):
- env.ts: add NANOGPT_API_KEY / NANOGPT_BASE_URL / NANOGPT_MODEL,
  widen LLM_PROVIDER enum, add CONSENSUS_MAX_AGE_HOURS.
- consensus-analyst/llm.ts: rewrite client to prefer NanoGPT when
  NANOGPT_API_KEY is set, fall back to Kimi (streamed, UA-gated)
  otherwise. activeProvider() reports which path is live.
- consensus-analyst/index.ts: record provider + actual model on the
  emitted payload (was hardcoded to KIMI_MODEL fallback).
- llm/router.ts (unrelated LLM router): widened enum required a
  one-line narrow so 'nanogpt' falls back to 'kimi' in this router
  (consensus-analyst has its own client; this router never serves it).

Web (selector + consumer):
- consensus-verdicts.ts: introduce ConsensusGenerator type, recognize
  "nanogpt" on parse, add isConsensusPayloadFresh() +
  getFreshConsensusVerdictsPayload().
- consensus/page.tsx: switch public consumer to fresh-only accessor.
- DailyVerdictPanel.tsx: widen prop type + label NanoGPT generator
  ("AI / NANOGPT KIMI-K2").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant