SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
12.5 KB · 247 lines typescript
Raw Blame History
1import type { ProviderId } from "@/lib/ai/core/types";23/**4 * Illustrative content used by the marketing mocks. These are product mocks: provider and5 * model names are real, the numbers are representative, and nothing here talks to a provider.6 * Everything streams locally in the visitor's browser.7 */8export interface MockModel {9  key: string;10  provider: ProviderId;11  name: string;12  context: string;13  input: string; // $/M tokens14  output: string;15  tags?: ("new" | "fast" | "cheap" | "reasoning" | "vision" | "coding" | "long")[];16  caps: {17    temperature: boolean;18    topK: boolean;19    reasoningEffort: boolean;20    thinkingBudget: boolean;21    verbosity: boolean;22    jsonSchema: boolean;23    tools: boolean;24    webSearch: boolean;25    vision: boolean;26  };27}2829export const MOCK_MODELS: MockModel[] = [30  {31    key: "anthropic/claude-opus-5",32    provider: "anthropic",33    name: "Claude Opus 5",34    context: "1M",35    input: "$5.00",36    output: "$25.00",37    tags: ["reasoning", "vision", "coding", "long"],38    caps: { temperature: true, topK: false, reasoningEffort: false, thinkingBudget: true, verbosity: false, jsonSchema: true, tools: true, webSearch: true, vision: true },39  },40  {41    key: "openai/gpt-5.5",42    provider: "openai",43    name: "GPT-5.5",44    context: "400K",45    input: "$1.25",46    output: "$10.00",47    tags: ["reasoning", "vision", "coding"],48    caps: { temperature: false, topK: false, reasoningEffort: true, thinkingBudget: false, verbosity: true, jsonSchema: true, tools: true, webSearch: true, vision: true },49  },50  {51    key: "gemini/gemini-3.8-flash",52    provider: "gemini",53    name: "Gemini 3.8 Flash",54    context: "1M",55    input: "$0.30",56    output: "$2.50",57    tags: ["fast", "cheap", "vision", "long"],58    caps: { temperature: true, topK: true, reasoningEffort: false, thinkingBudget: true, verbosity: false, jsonSchema: true, tools: true, webSearch: true, vision: true },59  },60  {61    key: "xai/grok-4.6",62    provider: "xai",63    name: "Grok 4.6",64    context: "256K",65    input: "$3.00",66    output: "$15.00",67    tags: ["reasoning", "vision"],68    caps: { temperature: true, topK: false, reasoningEffort: true, thinkingBudget: false, verbosity: false, jsonSchema: true, tools: true, webSearch: true, vision: true },69  },70  {71    key: "mistral/mistral-large-3",72    provider: "mistral",73    name: "Mistral Large 3",74    context: "256K",75    input: "$2.00",76    output: "$6.00",77    tags: ["coding", "vision"],78    caps: { temperature: true, topK: false, reasoningEffort: false, thinkingBudget: false, verbosity: false, jsonSchema: true, tools: true, webSearch: false, vision: true },79  },80  {81    key: "deepseek/deepseek-v4-pro",82    provider: "deepseek",83    name: "DeepSeek V4 Pro",84    context: "128K",85    input: "$0.55",86    output: "$2.19",87    tags: ["cheap", "reasoning", "new"],88    caps: { temperature: true, topK: false, reasoningEffort: true, thinkingBudget: false, verbosity: false, jsonSchema: false, tools: true, webSearch: false, vision: false },89  },90  {91    key: "kimi/kimi-k3",92    provider: "kimi",93    name: "Kimi K3",94    context: "256K",95    input: "$0.60",96    output: "$2.50",97    tags: ["long", "reasoning", "new"],98    caps: { temperature: false, topK: false, reasoningEffort: false, thinkingBudget: false, verbosity: false, jsonSchema: false, tools: true, webSearch: true, vision: true },99  },100  {101    key: "cerebras/gpt-oss-120b",102    provider: "cerebras",103    name: "GPT-OSS 120B",104    context: "128K",105    input: "$0.35",106    output: "$0.75",107    tags: ["fast", "cheap"],108    caps: { temperature: true, topK: false, reasoningEffort: true, thinkingBudget: false, verbosity: false, jsonSchema: true, tools: true, webSearch: false, vision: false },109  },110  {111    key: "openrouter/qwen3.6-235b",112    provider: "openrouter",113    name: "Qwen 3.6 235B",114    context: "262K",115    input: "$0.20",116    output: "$0.80",117    tags: ["cheap", "coding"],118    caps: { temperature: true, topK: true, reasoningEffort: false, thinkingBudget: false, verbosity: false, jsonSchema: true, tools: true, webSearch: false, vision: false },119  },120];121122export const PROVIDER_LABEL: Record<ProviderId, string> = {123  openai: "OpenAI",124  anthropic: "Anthropic",125  gemini: "Google Gemini",126  xai: "xAI",127  mistral: "Mistral AI",128  deepseek: "DeepSeek",129  kimi: "Kimi",130  openrouter: "OpenRouter",131  cerebras: "Cerebras",132  custom: "Custom endpoint", // exhaustive: PROVIDER_IDS includes user-defined OpenAI-compatible endpoints133};134135/* ------------------------------------------------------------------------------------------------136 * Scripted conversations137 * ---------------------------------------------------------------------------------------------- */138export const HERO_PROMPT = "Compare the three cheapest models that support JSON schema, then draft a pricing table.";139export const HERO_REPLY = `Three qualify on price and structured output. Ranked by blended cost at a 3:1 input/output ratio:1401411. **Qwen 3.6 235B** (OpenRouter) — $0.20 / $0.80 per million. JSON schema is enforced by the router; 262K context.1422. **Gemini 3.8 Flash** — $0.30 / $2.50. Native \`responseSchema\`, 1M context, fastest first token in your last 30 runs.1433. **DeepSeek V4 Pro** — $0.55 / $2.19. Only \`json_object\`, so I would schema-check the output yourself.144145| Model | Input | Output | Schema |146|---|---|---|---|147| Qwen 3.6 235B | $0.20 | $0.80 | strict |148| Gemini 3.8 Flash | $0.30 | $2.50 | native |149| DeepSeek V4 Pro | $0.55 | $2.19 | json_object |150151Want me to run the same prompt through all three in the Arena?`;152153export const CHAT_PROMPT = "Our Postgres queries got 3× slower after adding a JSONB column. Where should I look first?";154export const CHAT_REPLY = `Start with the write path, not the reads.1551561. **TOAST and row size.** A JSONB column that regularly exceeds ~2 KB gets TOASTed. Every UPDATE now rewrites the out-of-line chunk, and autovacuum has more dead tuples to chase. Check \`pg_stat_user_tables\` for a jump in \`n_dead_tup\` and \`autovacuum_count\`.1571582. **Index bloat on hot tables.** If you added a GIN index on the JSONB, each write touches many index entries. Try \`fastupdate = on\` with a sensible \`gin_pending_list_limit\`, or index only the keys you query with a \`jsonb_path_ops\` expression index.1591603. **Plan changes.** Run \`EXPLAIN (ANALYZE, BUFFERS)\` on the two or three slowest statements from \`pg_stat_statements\`. A wider row means fewer tuples per page, so sequential scans that used to fit in shared buffers may now spill.161162If the regression is in reads only, the third point is almost certainly it.`;163164export const ARENA_PROMPT = "Rewrite this commit message so it explains the why, not the what: “fix bug in scheduler”.";165export const ARENA_REPLIES: Record<string, string> = {166  "openai/gpt-5.5": `**scheduler: prevent duplicate runs after a clock skew**167168Jobs could be enqueued twice when the host clock stepped backwards during a tick, because the next-run timestamp was compared with wall-clock time. Compare against the monotonic clock instead.`,169  "gemini/gemini-3.8-flash": `**Fix scheduler double-firing on clock adjustments**170171When NTP corrected the system time mid-tick, the scheduler saw the same deadline twice and ran the job again. Use a monotonic source for deadline math so time corrections can't replay work.`,172  "xai/grok-4.6": `**scheduler: use monotonic time for deadlines**173174Wall-clock steps (NTP, DST, VM migration) made the scheduler believe a deadline had come around again and re-ran jobs. Deadlines now derive from a monotonic clock, which cannot go backwards.`,175};176177export const RECENT_CONVERSATIONS = ["JSONB slowdown", "Retry budgets, explained", "Pricing table draft", "Migrate to Responses API", "Onboarding copy v3"];178export const MOCK_PROJECTS = ["Infra notes", "Research"];179180/* ------------------------------------------------------------------------------------------------181 * Usage mock — 14 days, four providers182 * ---------------------------------------------------------------------------------------------- */183export const USAGE_SERIES = [18, 24, 21, 33, 29, 12, 9, 31, 42, 38, 47, 36, 51, 44]; // requests / day184export const USAGE_COST_SERIES = [1.9, 2.6, 2.2, 3.8, 3.1, 1.2, 0.8, 3.4, 4.9, 4.1, 5.2, 3.9, 5.8, 4.7]; // $ / day185export const USAGE_DAY_LABELS = USAGE_SERIES.map((_, i) => new Date(2026, 7, 26 + i).toLocaleDateString("en-US", { month: "short", day: "numeric" }));186export const USAGE_BY_PROVIDER: { provider: ProviderId; cost: number }[] = [187  { provider: "anthropic", cost: 18.4 },188  { provider: "openai", cost: 12.9 },189  { provider: "gemini", cost: 5.2 },190  { provider: "xai", cost: 4.7 },191];192export const USAGE_KPIS = [193  { label: "Requests", value: "435", hint: "+12% vs prior 14 d" },194  { label: "Tokens", value: "3.2M", hint: "2.6M in · 0.6M out" },195  { label: "Cost", value: "$41.20", hint: "≈ $88 / month" },196  { label: "Avg TTFT", value: "0.7 s", hint: "92 tok/s" },197];198export const USAGE_SAVINGS = { title: "Route short prompts to Gemini 3.8 Flash", body: "38% of your Opus requests were under 400 tokens with no reasoning. Estimated saving: $9.10 / month." };199200/* ------------------------------------------------------------------------------------------------201 * Arena scoreboard mock202 * ---------------------------------------------------------------------------------------------- */203export const SCOREBOARD = [204  { model: MOCK_MODELS[0], wins: 14, total: 19 },205  { model: MOCK_MODELS[1], wins: 11, total: 19 },206  { model: MOCK_MODELS[2], wins: 9, total: 16 },207  { model: MOCK_MODELS[3], wins: 6, total: 15 },208];209210/* ------------------------------------------------------------------------------------------------211 * FAQ212 * ---------------------------------------------------------------------------------------------- */213export const FAQ_ITEMS: { q: string; a: string }[] = [214  {215    q: "Do you see my API keys?",216    a: "No. Keys are encrypted with AES-256-GCM before they touch the database and are decrypted server-side only for the duration of a request to the provider you selected. They are never sent to the browser, never logged, and the UI only ever shows a hint like sk-••••••••9A2K. You can revoke a key from PolyLLM or from the provider console at any time. The security page explains every step.",217  },218  {219    q: "Which providers and models can I use?",220    a: "Every model your keys unlock: OpenAI, Anthropic, Google Gemini, xAI, Mistral, DeepSeek, Kimi (Moonshot AI), Cerebras and the hundreds of models behind OpenRouter. You can also add your own OpenAI-compatible endpoint for local models (Ollama, LM Studio, vLLM, llama.cpp, MLX). PolyLLM syncs each provider's model list and capability sheet so new releases appear as soon as your key can reach them.",221  },222  {223    q: "Is PolyLLM free?",224    a: "PolyLLM itself is free. You bring your own API keys and pay the providers directly for the tokens you use, at their list prices, with no markup. PolyLLM shows you a cost estimate before you send and the real cost after, so nothing is a surprise.",225  },226  {227    q: "What is Smart Router (AUTO)?",228    a: "Pick AUTO instead of a model and PolyLLM analyzes your prompt — length, code, reasoning, attachments, language — and recommends a model from the ones you have connected, with a one-line explanation and the estimated cost. You can accept, choose another, or let it always route for you. It runs entirely in your browser; nothing about your prompt is sent anywhere before you press Send.",229  },230  {231    q: "What is the Arena?",232    a: "Send one prompt to up to four models at once and watch the answers stream side by side, with tokens, time to first token, throughput and cost for each. Vote on the best answer (or run Blind Arena, where models are hidden until you vote) to build a personal scoreboard of which model is worth its price for your actual work.",233  },234  {235    q: "Do you store my conversations?",236    a: "Yes, so you can come back to them. Conversations, messages and usage metadata live in PolyLLM's own Postgres database and are only readable by you. Temporary chats are never stored. You can export everything as Markdown, JSON or PDF, and delete a conversation, a project or your whole account whenever you want. Deletion is immediate.",237  },238  {239    q: "Where do my prompts go?",240    a: "Only to the provider behind the model you picked, straight from PolyLLM's server. Nothing is proxied through third-party inference services, and nothing is used for training by PolyLLM.",241  },242  {243    q: "Can I use it on my phone?",244    a: "Yes. PolyLLM is designed for small screens first: bottom navigation, swipeable Arena panels, bottom sheets instead of dialogs, and a composer that stays above the keyboard. Install it to your home screen and it opens like a native app.",245  },246];247