# Changelog All notable changes to Chat Switchboard. ## [0.9.2] — 2026-02-23 ### Added - **Collapsible code blocks**: Code blocks over 15 lines auto-collapse into `
` with language and line count summary. Language label shown in top-left corner of all code blocks. - **HTML preview**: "Preview" button on HTML code blocks opens a sandboxed iframe (`allow-scripts`, no `allow-same-origin`). Auto-detected for untagged blocks via heuristic. - **Token count estimate**: Live token counter below input area showing approximate tokens and context usage percentage when model has `max_context`. - **Context length warning**: Dismissable banner above input at 75% (yellow) and 90% (red) context usage with guidance to start a new chat. - **Proxy interception detection**: `_parseJSON()` checks Content-Type before `.json()` on all API paths including streaming. Typed `proxyBlocked` errors with proxy page title extraction and actionable splash messages. - **Environment injection**: `window.__ENV__` wired through entrypoint, k8s, and index.html for dev/test/production gating. - **Enhanced diagnostics**: `NET:PROXY` log type, Content-Type capture in fetch interceptor, environment info in export header and state snapshot. - **Team admin audit scoping**: New `GET /api/v1/teams/:teamId/audit` and `/audit/actions` endpoints scoped to team members. Activity Log section in team manage panel with filter dropdown and pagination. - **New favicon**: Switchboard panel design with provider-colored jacks. Animated SVG (rotating plugs), 32px PNG, 256px PNG, and ICO. - **Seed users** (dev/test only): `SEED_USERS=user:pass:role,...` env var pre-creates active users on startup. Ignored in production. K8s secret `switchboard-seed-users` wired in backend manifest. ## [0.9.1] — 2026-02-23 ### Removed - **Static known model table**: Deleted `knownModels` map from backend and `KNOWN_MODELS` from frontend. The same model ID can have different capabilities depending on the provider (e.g. DeepSeek has tool_calling on OpenRouter but not on Venice). A hardcoded table can't represent this. - **Frontend `lookupKnownCaps()`**: Removed client-side capability guessing. Backend is the sole source of truth via catalog → heuristic chain. ### Changed - **Resolution chain simplified**: catalog (provider API sync) → heuristic inference. No intermediate known table. Providers that report capabilities via API are authoritative; heuristics are best-effort for unsynced models. - **All providers updated**: OpenAI, OpenRouter, Anthropic, Venice now call `InferCapabilities()` directly instead of the dead known table lookup. - **Frontend `resolveCapabilities()`**: Now passes through backend caps as-is. No client-side merging with a static table. - [x] EXTENSIONS.md recovered into repo, updated with Appendix A (Custom Renderers) and Appendix B (Model Roles with utility/embedding/generation slots) - [x] ROADMAP.md restructured: extension foundation pulled to v0.11.0, model roles to v0.10.0, dependency graph, TBD replaces post-1.0, removed v0.8→v0.9 migration (OBE — no public release, no test path) ### Added - **Heuristic patterns**: Updated to detect qwen3, gpt-5, grok, kimi, minimax, glm-5, gemma-3 model families. Vision expanded to claude-opus/sonnet (not just claude-3). Reasoning expanded for thinking, grok, glm patterns. ### Fixed - **Preset capability pills**: Presets with auto-resolve (no `provider_config_id`) now inherit base model capabilities via `GetByModelIDAny` catalog fallback. - **Venice `optimizedForCode`**: Added mapping to `CodeOptimized` capability. - **CI test stability**: BYOK journey tests use unreachable endpoints so auto-fetch doesn't race with simulated data injection. ## [0.9.0] — 2026-02-22 ### Added - **Schema consolidation**: 21 migrations collapsed to single `001_initial.sql` - **Store layer**: All database access through typed interfaces (no raw SQL in handlers) - **Persona model**: Trust-boundary model replacing old presets; scoped global/team/personal - **Capabilities resolver**: Three-tier chain — catalog → known table → heuristic inference - **Three-state model visibility**: enabled / disabled / team-only - **BYOK auto-fetch**: Creating a personal provider triggers model discovery from provider API - **User model refresh**: `POST /api-configs/:id/models/fetch` endpoint + UI button - **Composite model IDs**: `configId:modelId` format prevents cross-provider collisions - **Audit log foundation**: All admin operations logged with actor, action, resource - **Journey integration tests**: API-driven test suite replacing fake-data tests - **Frontend test suite**: 107 tests, 27 suites validating model processing pipeline - **Live Venice API test**: Proves real BYOK → auto-fetch → models visible flow ### Fixed - **API key storage**: `json:"-"` tag on `ProviderConfig.APIKeyEnc` silently dropped keys during admin create/update. Fixed with wrapper structs that bypass the tag. - **NULL model_default scan**: `scanProviders()` crashed on NULL `model_default` column, silently hiding all team and BYOK models. Fixed with `sql.NullString`. - **Nil slice serialization**: Go nil slices serialized as JSON `null` instead of `[]`, breaking frontend fallback chains. Fixed with `make([]T, 0)`. - **Frontend error swallowing**: API responses with `errors` field were silently ignored. ### Changed - Backward-compatible API routes with v0.8 field name aliases - User model preferences table (`user_model_settings`)