Files
moeka-project/apps/server/.env
T
RainbowBird 4da4a72703 feat(server): finalize in-process LLM/TTS router cutover
End-state of the multi-step KTD-5 / KTD-6 / U8 work. The knoway sidecar
is no longer reachable from server code; the router is required at boot
and now owns chat completions, TTS synthesis, and voice catalog listing.

Highlights:
- LLM_ROUTER_MASTER_KEY becomes required; app.ts drops the graceful-
  skip branch and the chat fallback fetch path is gone.
- /audio/speech and /audio/voices route through new routeTts /
  listTtsVoices entries that reuse the chat key-rotator + per-attempt
  timeout + abort propagation.
- DEFAULT_CHAT_MODEL / DEFAULT_TTS_MODEL move from env to configKV so
  default-model swaps are hot-reloadable via Pub/Sub.
- GATEWAY_BASE_URL removed from env schema, .env, .env.local, smoke,
  verification harness. Redis upstream-voices cache deleted — catalogs
  come from in-process adapter JSON.
- routeTts splits adapter error contract by ApiError statusCode:
  4xx propagates without fallback; 5xx folds into the network-failure
  fallback path. handleTTS wraps billing + span attribute in try/finally
  to plug a span leak when ttsMeter.accumulate() throws.
- seed-router-config.ts rewritten with --merge (default) / --reset /
  --dry-run modes and env-var key handoff (OPENROUTER_KEY / AZURE_KEY /
  DASHSCOPE_KEY) so prod seed flows never put plaintext on the CLI.
  Adds DashScope CosyVoice seeding.

Docs (CLAUDE.md, architecture-overview.md, transport-and-routes.md)
reflect the new boundary. verifications/llm-router.md replaces the
overstated "U1-U9 shipped" line with an evidence-vs-pending table.

Tests: full 40-file / 343-case server suite green. New regressions pin
ApiError 4xx → no-fallback, ApiError 5xx → fallback, TTS billing
failure → span closed and error propagated.
2026-05-18 23:32:33 +08:00

39 lines
1.3 KiB
Bash

DATABASE_URL="postgresql://postgres:example-PAssw0rd-xHjDYR.b7N@db:5432/postgres"
REDIS_URL="redis://localhost:6379"
BETTER_AUTH_SECRET=""
AUTH_GOOGLE_CLIENT_ID=""
AUTH_GOOGLE_CLIENT_SECRET=""
AUTH_GITHUB_CLIENT_ID=""
AUTH_GITHUB_CLIENT_SECRET=""
STRIPE_SECRET_KEY=""
STRIPE_WEBHOOK_SECRET=""
CLIENT_URL=""
API_SERVER_URL=""
# Comma-separated browser origins for CORS (/api/*) and Stripe return URLs.
# Required when the Capacitor dev server uses a LAN IP (see ios/App/App/capacitor.config.json),
# e.g. ADDITIONAL_TRUSTED_ORIGINS="https://10.0.0.129:5273,https://198.18.0.1:5273"
# OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
# Master key for the in-process LLM/TTS router envelope crypto.
# Base64 of 32 random bytes. Required at boot: missing or wrong-length value
# fails env parsing and the server refuses to start (no graceful skip).
# Do NOT commit a real key here — put the value in `.env.local` (gitignored).
#
# Generate:
# openssl rand -base64 32
#
# Rotation: when replacing the key, copy the old value to
# LLM_ROUTER_MASTER_KEY_PREVIOUS first, set LLM_ROUTER_MASTER_KEY to the new
# one, redeploy, then run a re-wrap of every stored ciphertext before
# dropping PREVIOUS. See `apps/server/src/utils/envelope-crypto.ts`.
LLM_ROUTER_MASTER_KEY=""
# LLM_ROUTER_MASTER_KEY_PREVIOUS=""