docs: move release notes into CHANGELOG.md#70
Conversation
- New Visible Models settings tab: fetch models from OpenRouter/Ollama/LM Studio, then toggle per-model visibility with sub-provider filter chips - New Model Profiles settings tab: create/edit/delete named model sets grouped by provider; profiles draw only from visible models - Centralized filtering (ModelFiltering.ts) so visibility and active profile apply consistently in the chat model picker and quick chat - Profile selector dropdown in the chat model picker uses the themed Radix Select component Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Model Profiles and Visible Models management
Adds persona/role presets that inject a system prompt into chats. Includes 5 built-in profiles (Data Scientist, Academic Researcher, Study Guide, Code Reviewer, Creative Writer), a per-chat selector pill in the chat input toolbar, and a Prompt Profiles tab in Settings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Model Profiles, Visible Models, and Prompt Profiles
- Created BUILD.md with instructions - Updated README.md - Added .github/workflows/build.yml - Removed unused import in ModelFiltering.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LFS support to checkout step - Add Rust toolchain setup with caching via actions-rust-lang/setup-rust-toolchain@v1 - Use pnpm install --frozen-lockfile for deterministic builds - Remove push-to-main trigger to avoid duplicating cloud-qa.yaml - Upgrade pnpm/action-setup from v3 to v4 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The updater bundle requires TAURI_SIGNING_PRIVATE_KEY which isn't available in CI. Build only app and dmg bundles for verification. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--bundles flag doesn't suppress createUpdaterArtifacts; use --config inline override instead to prevent the signing key error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds workflow_dispatch trigger with optional release_tag input. Builds for both aarch64 and x86_64 targets. When a release tag is provided, creates a GitHub Release with downloadable .app.zip and .dmg files for both architectures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add GitHub Release support to build workflow
- Migration v142: create Ambient Gemini Flash config (gemini-2.5-flash-preview-04-17, vision-capable, free tier on Google AI Studio), migrate users off the deprecated ambient-gemini-2.5-pro config, mark old config as deprecated - Remove ALLOWED_MODEL_IDS_FOR_QUICK_CHAT allowlist so all non-deprecated, enabled models with valid API keys appear in the ambient model selector Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Migration v143: add gemini-2.5-flash-lite (stable, vision-capable, free tier), deprecate gemini-2.0-flash-lite-preview-02-05, update ambient config to point to the new flash-lite model - Allow gemini-2.5-flash-lite in ProviderGoogle model name allowlist Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bump @tauri-apps/plugin-store to ~2.2.0 to match the Rust crate which had already resolved to 2.2.0 via Cargo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ambient (quick chat) mode should not pass MCP tools like web_search to the model — there's no UI to invoke them and they cause confusing responses when the model tries to call an unconfigured tool. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update ambient default to Gemini 2.5 Flash and open model selector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bump version to 0.14.6
Adds a "Select All" button in the profile selector row of the manage models dialog, plus a cmd+shift+A keyboard shortcut to select all currently visible models (respecting active profile and search filter). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Select All button and shortcut to model picker
… shortcut scope - Extract selectableVisibleModels memo shared by button and shortcut, filtering out models without API keys and OpenRouter when collapsed - Add `enabled` option to useShortcut so cmd+shift+A is not swallowed in non-default dialog modes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lowup Fix Select All: filter ungated models, dedup logic, scope shortcut
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bump version to 0.14.7
Users can now select which model is used to auto-generate chat titles. Defaults to the ambient chat model, with the option to pick from any cheap enabled OpenRouter model the user has marked available. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…iders Refactor visible models settings by provider
- Fix migration ordering (142→143→144→145 instead of 142→144→145→143)
- Check global YOLO before per-tool to skip unnecessary DB query
- Fix checkToolYolo SELECT 1 typed as ToolYoloDBRow (now { exists })
- Add htmlFor/id to per-tool Label/Switch for accessibility
- Make useAllToolYolo conditional (skip query when global YOLO is on)
- Use yoloMode === false instead of !yoloMode to handle loading state
- Remove stale useMemo with empty deps for allTools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… matching - Add parseSearchQuery to detect "provider: term" prefix syntax for hard provider filtering (e.g. "openai: gpt-4" shows only OpenAI models) - Replace isSubsequenceMatch with scoreMatch (exact > word-boundary > normalized substring; numeric terms require contiguous digit group match) - Update filterBySearch to accept providerFilter and sort by score - Update modelGroups useMemo to use parseSearchQuery and short-circuit non-matching provider groups Fixes false positives like "5.4" matching "4.6" or "420". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ute scores
- Use ProviderName[] for KNOWN_PROVIDERS to stay in sync with core model layer
(adds "meta"; eliminates drift risk)
- Guard against empty provider prefix (": gpt" no longer accidentally matches
first provider in the list)
- Require exact or unambiguous prefix match for provider (avoids "open:" being
ambiguous between openai/openrouter)
- Precompute scoreMatch per model in filterBySearch to avoid redundant work
inside the sort comparator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ty, and pre-send pricing UI Three features combined in one commit: 1. OpenRouter actual model + cost attribution - Add actual_model_id column to messages table (migration 145) - Persist actual routed model from OpenRouter generation API - Display actual model name with "via auto" badge in ToolsMessageView - Full data path: API -> DB -> ChatState -> MultiChat UI 2. Error-state cost reliability - Recompute and persist chat/project cost totals on error paths - Add cost invalidation in legacy onError and useStopMessageStreaming - Harden sidebar cost display with Number() coercion and Number.isFinite checks 3. Pre-send model pricing UI - Add formatPricePerMillion() utility to CostAPI - New ModelPricingDisplay component showing per-1M token pricing - Supports single-model and range display for multi-model compare - Integrated into ChatInput, respects showCost setting Made-with: Cursor
Apply Prettier formatting fixes for ModelPricingDisplay and ToolsMessageView so lint/style checks pass. Made-with: Cursor
Drop the chat-input model pricing display to keep the compose area uncluttered while preserving existing post-send cost behavior. Made-with: Cursor
The OpenRouter generation endpoint (/api/v1/generation) was returning negative total_cost values, and the actual model wasn't being captured. OpenRouter includes both usage.cost and the model field directly in the streaming response. This commit: - Captures chunk.model from the streaming response in ProviderOpenRouter - Reads usage.cost (OpenRouter extension) from the final chunk - Adds model and cost fields to the UsageData type - Prefers response-level cost/model in MessageAPI, falling back to the generation endpoint only when the response doesn't include them - Guards against negative cost values Made-with: Cursor
…ames Made-with: Cursor
…ibution-and-pricing-ui OpenRouter actual model attribution, error-state cost reliability, and pre-send pricing UI
Fix fuzzy search false positives in model picker
Add per-tool and per-project YOLO mode
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Pull request overview
This PR updates fork documentation/release history (adds CHANGELOG.md, updates README.md) while also introducing substantial new app functionality around model visibility/profiles/defaults, per-chat model selection persistence, and more granular YOLO permissions.
Changes:
- Move fork release history into
CHANGELOG.md, addBUILD.md, and adjust repo metadata/versioning. - Add model visibility controls + model/prompt profiles and consolidate defaults configuration under a new Settings “Defaults” tab.
- Introduce per-tool/per-project YOLO overrides and related DB migrations + APIs.
Reviewed changes
Copilot reviewed 64 out of 65 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ui/lib/models.ts | Removes hardcoded quick-chat allowed model ID list. |
| src/ui/hooks/useShortcut.ts | Adds an enabled option to conditionally disable shortcuts. |
| src/ui/components/VisibleModelsTab.tsx | New Settings tab UI to manage per-model visibility, including provider sections and fetch actions. |
| src/ui/components/VisibleModelsTab.search.test.ts | Adds unit tests for visible-models search/filter helpers. |
| src/ui/components/visibleModelsSearch.ts | Implements provider/sub-provider parsing and model filtering logic for visibility UI. |
| src/ui/components/ui/textarea.tsx | Ensures Textarea has w-full styling. |
| src/ui/components/ui/command.tsx | Adds trailing content support to command input (e.g., shortcut hints). |
| src/ui/components/SortableColumnItem.tsx | Adds reusable draggable+dropspot component for sortable column behavior. |
| src/ui/components/Settings.tsx | Reworks Settings tabs (new tabs/order), adds title-generation model selector, routes legacy quick-chat tab to defaults, and wires in new tabs. |
| src/ui/components/QuickChatModelSelector.tsx | Switches quick-chat model selection to use centralized filtering + visibility map. |
| src/ui/components/PromptProfilesTab.tsx | Adds Settings UI to CRUD prompt profiles. |
| src/ui/components/PromptProfilePill.tsx | Adds chat toolbar pill to select/manage prompt profiles per chat. |
| src/ui/components/ProjectView.tsx | Adds per-project default prompt profile + per-project YOLO override selectors. |
| src/ui/components/PermissionsTab.tsx | Adds per-tool YOLO toggles when global YOLO is off. |
| src/ui/components/Onboarding.tsx | Updates onboarding to optionally collect multiple provider API keys. |
| src/ui/components/ModelProfilesTab.tsx | Adds Settings UI to CRUD model profiles (named model-config sets). |
| src/ui/components/ManageModelsBox.tsx | Adds profile selection/application, improved search (provider filter + scoring), and select-all shortcut wiring. |
| src/ui/components/DefaultsTab.tsx | New consolidated defaults tab for prompt/profile/model defaults + ambient chat settings. |
| src/ui/components/ChatInput.tsx | Adds collapsible input UX, per-chat model compare persistence + defaults application, minimized-model exclusion, and prompt profile pill. |
| src/ui/components/AutoExpandingTextarea.tsx | Adds onHeightChange callback to support collapse threshold logic. |
| src/ui/components/AppSidebar.tsx | Improves route parsing for chat ID and adds minimized-models sidebar panel with retry UX. |
| src/ui/App.tsx | Maps legacy quick-chat settings tab to defaults when opening settings. |
| src/core/utilities/Settings.ts | Adds new model/prompt default fields and seeds defaults via buildFreshInstallModelAndPromptDefaults. |
| src/core/utilities/ProxyUtils.ts | Treats whitespace-only API keys as absent. |
| src/core/utilities/ModelFiltering.ts | Adds centralized filtering utility for visibility + profile filtering. |
| src/core/utilities/ChorusDefaultPreferences.ts | Defines fresh-install defaults (e.g., Gemini 2.5 Flash Lite) for model-related settings. |
| src/core/infra/ToolsDisabledStore.ts | New zustand store for per-chat/per-model tool disable state. |
| src/core/infra/ModelOrderStore.ts | New zustand store for per-chat model order and current visual order. |
| src/core/infra/MinimizedModelsStore.ts | New zustand store tracking minimized model columns per chat. |
| src/core/chorus/ToolsetsManager.ts | Implements per-project and per-tool YOLO resolution precedence while preserving deny behavior. |
| src/core/chorus/ToolsetsManager.test.ts | Adds test ensuring always_deny blocks tool execution even with YOLO enabled. |
| src/core/chorus/Toolsets.ts | Adds MCP start/list tools timeouts and guards against concurrent start attempts. |
| src/core/chorus/simpleLLM.ts | Adds ability to route simpleLLM calls to a specific model config ID (for title gen). |
| src/core/chorus/prompts/prompts.ts | Adds prompt-profile system prompt injection hook. |
| src/core/chorus/Models.ts | Adds types for provider visibility, model profiles, prompt profiles; extends usage fields. |
| src/core/chorus/ModelProviders/simple/SimpleCompletionProviderFactory.ts | Adds createProviderByPrefix helper for targeted provider selection. |
| src/core/chorus/ModelProviders/ProviderOpenRouter.ts | Captures actual model + cost from streaming chunks into usage data. |
| src/core/chorus/ModelProviders/ProviderGoogle.ts | Adds support for gemini-2.5-flash-lite. |
| src/core/chorus/ChatState.ts | Adds actualModelId field on message state. |
| src/core/chorus/chatCreationDefaults.ts | Applies chat creation defaults (prompt profile for regular chats, ambient model for quick chats). |
| src/core/chorus/ChatCompareSelection.ts | Adds logic for computing initial compare selection using new defaults + visibility/profile filtering and syncing global compare metadata. |
| src/core/chorus/api/ToolYoloAPI.ts | Adds DB API + hooks for per-tool YOLO records. |
| src/core/chorus/api/ProviderVisibilityAPI.ts | Adds provider-visible-model persistence + visibility map helper that considers API-key gating. |
| src/core/chorus/api/PromptProfilesAPI.ts | Adds DB APIs + hooks for prompt profiles and per-chat associations. |
| src/core/chorus/api/ProjectAPI.ts | Extends project schema and adds mutations for default prompt profile + YOLO override; adds fetchProjectYoloMode. |
| src/core/chorus/api/ModelProfilesAPI.ts | Adds DB APIs + hooks for model profiles and active model profile. |
| src/core/chorus/api/ModelConfigChatAPI.ts | Adds per-chat saved compare selection resolution with fallback to ambient compare list. |
| src/core/chorus/api/CostAPI.ts | Captures OpenRouter actualModel for cost attribution. |
| src/core/chorus/api/ChatAPI.ts | Initializes per-chat compare selection on creation and applies creation defaults. |
| src-tauri/tauri.qa.conf.json | Bumps app version to 0.14.15 (QA config). |
| src-tauri/tauri.dev.conf.json | Bumps app version to 0.14.15 (dev config). |
| src-tauri/tauri.conf.json | Bumps app version to 0.14.15 (prod config). |
| src-tauri/src/migrations.rs | Adds new migrations (visibility/profiles/projects defaults) and legacy-compat migration 145/146 switch. |
| src-tauri/src/lib.rs | Adds runtime detection of legacy migration 145 and sets env var before running migrations. |
| README.md | Adds “Fork changes” section and links to CHANGELOG.md; links to BUILD.md. |
| package.json | Bumps version to 0.14.15 and updates plugin-store dependency. |
| CHANGELOG.md | New consolidated changelog for fork releases v0.14.5–v0.14.15 plus pre-release. |
| BUILD.md | New build instructions document. |
| .prettierignore | Adds .context to prettier ignore list. |
| .github/workflows/build.yml | Adds GitHub Actions build workflow with optional release creation. |
| .cursor/worktrees.json | Adds Cursor worktree setup command config. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const isAllVisible = visibleProviderModels.every((m) => { | ||
| const v = visibleModels?.find((vm) => vm.modelId === m.modelId); | ||
| return v ? v.isVisible : true; | ||
| }); |
There was a problem hiding this comment.
isAllVisible uses visibleModels?.find(...) inside an .every(...) over visibleProviderModels, making this O(n*m) per render. With large model lists this can become noticeably slow. Consider precomputing a Map/Set of visibility by modelId (e.g., via useMemo) and doing O(1) lookups.
| # Fork changes | ||
|
|
||
| - Added profiles for favorite models in the chat window | ||
| - Dynamically fetch and select models from providers | ||
| - Prompt profiles: Choose your preferred chat persona |
There was a problem hiding this comment.
The PR title/description describe a docs-only change (moving release notes to CHANGELOG), but this diff includes substantial new UI + core functionality (models/profiles/YOLO/migrations/etc.). Please update the PR title/description (and ideally split into smaller PRs) so review scope and risk are clear.
| titleGenerationModelConfigId?: string; | ||
| } | ||
|
|
||
| export default function Settings({ tab = "general" }: SettingsProps) { |
There was a problem hiding this comment.
Because tab defaults to "general" in the function parameter, it’s never undefined. That means tab ?? resolvedTabParam will always prefer the prop and the ?tab= URL param (including the legacy quick-chat redirect) won’t take effect. Consider removing the default from the parameter and resolving defaultTab from the URL param when present.
| <Input | ||
| id={`${field.provider}-api-key`} | ||
| placeholder={field.placeholder} | ||
| value={apiKeyInputs[field.provider]} | ||
| onChange={(event) => |
There was a problem hiding this comment.
The onboarding API key <Input> fields don’t specify type="password", so keys will be shown in plaintext while typing. For API keys, consider masking by default (or providing an explicit show/hide toggle).
| const visibilityMap = new Map( | ||
| (data ?? []).map((v) => [v.modelId, v.isVisible]), | ||
| ); |
There was a problem hiding this comment.
useProviderVisibilityMap creates a new Map(...) each render. Because callers often include this map in dependency arrays, this breaks memoization and can cause avoidable recomputation/rerenders. Consider wrapping the map construction in useMemo keyed on data, apiKeys, and allModels so the returned Map is referentially stable when inputs don’t change.
| const value = isVisible ? 1 : 0; | ||
| for (const modelId of modelIds) { | ||
| await db.execute( | ||
| "INSERT OR REPLACE INTO provider_visible_models (provider_name, model_id, is_visible) VALUES (?, ?, ?)", | ||
| [providerName, modelId, value], |
There was a problem hiding this comment.
useSetAllProviderModelsVisible awaits db.execute(...) inside a for loop, doing one write per model sequentially. For large catalogs (e.g., OpenRouter), this can be very slow. Consider batching in a transaction or using bulk insert semantics if available.
| <Checkbox | ||
| checked={allSelected} | ||
| data-state={ | ||
| someSelected && !allSelected | ||
| ? "indeterminate" | ||
| : undefined | ||
| } |
There was a problem hiding this comment.
The provider-level checkbox sets data-state="indeterminate", but Radix Checkbox determines indeterminate state from the checked prop (it should be "indeterminate", not false). With the current code, the checkbox will likely render unchecked even when someSelected && !allSelected. Consider setting checked to "indeterminate" in that case and dropping the manual data-state.
| const allToolsDependency = ToolsetsManager.instance | ||
| .listToolsets() | ||
| .map( | ||
| (toolset) => | ||
| `${toolset.name}:${toolset |
There was a problem hiding this comment.
allToolsDependency is built by calling ToolsetsManager.instance.listToolsets() (+ listTools()) on every render, and then listToolsets() is called again inside the useMemo. This duplicates potentially expensive work. Consider computing the tool list once (or exposing a stable tool list from ToolsetsManager) and deriving both the dependency and allTools from that single computation.
| build: | ||
| runs-on: macos-latest | ||
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
The workflow grants contents: write on the pull_request trigger. Even if GitHub restricts GITHUB_TOKEN on forked PRs, this is a higher-risk default for PR builds. Consider least-privilege permissions for PR runs and limiting write permissions to the release workflow/job.
Summary
Test Plan