This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/CHANGELOG.md
2026-02-23 23:55:22 +00:00

10 KiB

Changelog

All notable changes to Chat Switchboard.

[0.9.3] — 2026-02-23

Changed

  • Code blocks: button-driven collapse — Replaced <details> wrapper with inline collapse/expand toggle button in the code toolbar. Auto-collapses at

    15 lines with a fade mask; toggle available on all blocks >5 lines. User can always expand/collapse regardless of threshold. Smooth CSS transition instead of native <details> jump.

  • Thinking blocks: always visible — Thinking blocks are always rendered in the DOM regardless of the showThinking setting. The setting now controls whether blocks start expanded (<details open>) or collapsed. User can always click to toggle. Setting label updated to "Auto-expand thinking blocks".

Added

  • Admin default model — New default_model policy in Admin → Settings. Dropdown populated from enabled models. When a user has no saved selection (fresh login, cleared browser) or their saved model is no longer available, the admin default is used before falling back to first visible. Resolution chain: localStorage → admin default → first visible.
  • Reasoning/thinking support for OpenAI-compatible providers — Models that send reasoning_content in stream deltas (Grok, DeepSeek, etc.) now have thinking blocks streamed live and persisted as <think> tags. Renders as collapsible thinking blocks in both streaming and history views.
  • Favicon animation during generation — Browser tab favicon pulses with cascading dot opacity animation while a completion is in progress, restoring to the static favicon when done.
  • Tool calls in message history — Tool call metadata (name, arguments, result, error status) is now persisted alongside assistant messages in the database. History view renders tool calls as collapsed <details> blocks showing "🔧 tool_name → done" with expandable input/output JSON.
  • Notes tool: "View note" link — When a notes tool (note_create, note_update, etc.) completes, a "📝 View note" button appears in both the live streaming tool indicator and the history tool call block. Clicking opens the Notes panel and navigates directly to the note.
  • Notes panel: Copy button — "Copy" button added to note read mode, copies title + content as markdown to clipboard.
  • Brand hover: jitter-free crossfade — Sidebar brand logo→collapse icon swap uses opacity crossfade instead of display: none toggle, eliminating layout reflow jitter on hover.

Fixed

  • Model selector shows unavailable model — Selector restoration searched all models including user-hidden ones. Saved selection (localStorage) for a hidden model like Claude Opus would re-select it on every page load even when only Grok was visible. Resolution now filters to visible models only.
  • Refresh toast shows wrong count — "Loaded 33 models" counted all models including hidden; now shows only visible count ("Loaded 1 model").
  • Tool calls vanish after completion — Live streaming tool indicators disappeared when reloadActivePath() rebuilt messages from DB. Fixed: the getActivePath query now includes tool_calls column, and PathMessage carries the data through to the frontend renderer.
  • Tool result "undefined results" text — Operator precedence bug in tool result summary parser caused undefined results to display for note_create. Fixed summary logic to properly branch on title vs count.
  • Regenerate streams at wrong position — Regen'd response appeared below the full conversation (appended at bottom) then snapped to correct position after completion. Fixed: display is now truncated to the parent message before streaming starts, so the new response streams in-place as a clean branch. Backend context was already correct (excludes old response).
  • Regenerate loses tools, reasoning, and tool execution — Regen handler was a stripped-down copy of the completion handler missing tool definitions, tool execution loop, reasoning_content forwarding, and tool_calls persistence. Model lost access to note tools on regen and fell back to generic capabilities. Refactored: extracted streamWithToolLoop() into stream_loop.go as the single canonical streaming implementation. Both streamCompletion (normal chat) and Regenerate now call the shared function — only persistence differs. Future streaming features (new event types, tool capabilities) automatically apply to all code paths.
  • OpenRouter free models crash — Free models with nil pricing caused pq: invalid input syntax for type json on catalog sync. Nil pricing now routes through ToJSON() producing "{}" instead of nil []byte.
  • API key appears unsavedListGlobalConfigs returned raw ProviderConfig structs where APIKeyEnc is json:"-" (never serialized), so has_key was always undefined. Now returns computed has_key field.
  • Case-insensitive usernames — Login, registration, and all user lookups use LOWER() in SQL. All user creation paths normalize to lowercase. New migration 002_ci_username.sql adds LOWER() unique indexes and normalizes existing rows.

[0.9.2] — 2026-02-23

Added

  • Collapsible code blocks: Code blocks over 15 lines auto-collapse into <details> 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.
  • EXTENSIONS.md recovered into repo, updated with Appendix A (Custom Renderers) and Appendix B (Model Roles with utility/embedding/generation slots)
  • 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)