SPB Git

spb/polyllm

Public
3.0 KB

# PolyLLM — repository guide

PolyLLM (www.polyllm.io) is a BYOK multi-provider AI workspace: OpenAI, Anthropic, Gemini, xAI behind one normalized adapter layer, real streaming, capability-driven configuration, Arena comparisons, usage/cost tracking. The original product brief lives in docs/SPEC-original.md; the UI conventions in docs/UI-BRIEF.md.

# Non-negotiables

  • Research before provider changes. Read docs/provider-research/<provider>.md, re-fetch the official docs, probe the real API (pnpm providers:matrix), then update src/lib/ai/providers/<provider>/catalog*.ts. Never assume model ids, parameters, event names or limits from memory. Bump Last documentation audit.
  • Provider quirks stay inside src/lib/ai/providers/*. UI and services only see PolyModel, UnifiedChatRequest, UnifiedStreamEvent, PolyProviderError.
  • Capabilities drive the UI. Never branch on a model id in components; use model.capabilities / model.parameters. Never send a parameter the model does not accept (filterSettings() + adapter translation).
  • Keys. User keys are encrypted (src/lib/crypto/keys.ts) and decrypted only in getDecryptedKey() right before a request. Never log, return or serialize them; PublicConnection exposes keyHint only. Owner keys in .env are for the registry sync, admin diagnostics and tests — never for user requests.
  • No fake integrations. A capability is ✅ only after a real request passed (docs/provider-test-matrix.md).
  • Secrets only in .env (gitignored) and the mld manifest on M1M32; .env.example documents the variables.

# Commands

pnpm dev · pnpm typecheck · pnpm lint · pnpm test (vitest) · pnpm test:e2e (Playwright; dev server with EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1) · pnpm db:generate / pnpm db:migrate · pnpm models:sync [provider] · pnpm providers:matrix [provider].

# Deploy

mld from the laptop (see docs/deployment-cluster.md): mld stage . polyllm && mld deploy polyllm --node M3U96a. Manifest with secrets: M1M32:~/dispatch/apps/polyllm.json (local gitignored copy deploy/polyllm.mld.json).

# Gotchas

  • React Compiler lint: no Date.now()/impure calls in render, no setState synchronously in effects without an explicit eslint-disable, memoize derived lists.
  • import "server-only" modules are used by CLI scripts through scripts/hooks.mjs (tsx --import) and by vitest via an alias.
  • Anthropic: adaptive thinking may legitimately produce zero thinking tokens on easy prompts; Haiku 4.5 needs budget_tokens.
  • Gemini: free-tier keys have tiny per-model daily quotas (429 limit: 20) and some models are paid-tier only (429 limit: 0); thought signatures must be replayed on function-call parts.
  • xAI: bad keys return HTTP 400 (Incorrect API key), frequency/presence_penalty always 400, web search only via /v1/responses.
  • OpenAI: Responses API has no seed/stop; sampling params only when reasoning.effort === "none" on reasoning models.
Files · d6f683a5f3ce2650916bcde9467e60c640c62fa9
Menu

Theme