Skip to content

Fix reply to single model silently skipping AI response#69

Closed
sidharthmirch wants to merge 97 commits into
meltylabs:mainfrom
sidharthmirch:sidharthmirch/fix-reply-message
Closed

Fix reply to single model silently skipping AI response#69
sidharthmirch wants to merge 97 commits into
meltylabs:mainfrom
sidharthmirch:sidharthmirch/fix-reply-message

Conversation

@sidharthmirch
Copy link
Copy Markdown

Fixes the bug where replying to a single model in the reply window saves the user message but never generates an AI response.

Root cause

ChatInput.tsx:363 was passing replyToModelConfig?.modelId (e.g. "anthropic::claude-sonnet-4-5") to populateBlock. This flows into fetchModelConfigById which queries WHERE model_configs.id = ? — expecting a UUID primary key. The mismatch caused it to return null, and usePopulateToolsBlock returned { skipped: true } silently.

Fix

One-line change: replyToModelConfig?.modelIdreplyToModelConfig?.id

Test plan

  • Open a multi-model chat and send a message
  • Click Reply on one model's response to open a reply window
  • Type a message and send it
  • Confirm the model generates a response (previously it would silently do nothing)
  • Verify normal (non-reply) chat still works as before

🤖 Generated with Claude Code

sidharthmirch and others added 30 commits March 29, 2026 00:21
- 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>
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>
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>
sidharthmirch and others added 24 commits March 30, 2026 21:48
…r-1-8gq

Persist model selection per chat and default new-chat models
- Settings.tsx: use hasOwnProperty to guard against prototype key exploits in tab validation
- DefaultsTab.tsx: filter fallback profile dropdown to only profiles containing the fallback model; add incompatibility warning; add comment that visibleModels are not filtered by active profile
- ChorusDefaultPreferences.ts: simplify buildFreshInstallModelAndPromptDefaults to remove unused apiKeys param (always called with {} at fresh install)
- Settings.ts: update call sites to match simplified signature
- MessageAPI.ts: tighten applyChatCreationModelDefaults JSDoc to reflect quick-chat-only behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Settings.tsx: remove unnecessary 'as string' type assertion (fixes ESLint no-unnecessary-type-assertion)
- migrations.rs: add migration 144 to add default_prompt_profile_id column to projects
- ProjectAPI.ts: add defaultPromptProfileId to Project type/DB row/read/fetch, add useSetProjectDefaultPromptProfile mutation
- chatCreationDefaults.ts: pass project-level default profile to applyDefaultPromptProfileForChat, which takes priority over the global setting
- ProjectView.tsx: add prompt profile selector in the CHATS panel (hidden when no profiles exist)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses a proper isSettingsTabId type guard function to narrow rawTab to
SettingsTabId without a type assertion, fixing the ESLint
no-unnecessary-type-assertion error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comparing rawTab (which includes SettingsTabId) against "quick-chat"
caused TS2367 since "quick-chat" is not a member of SettingsTabId.
Fix: resolve the searchParams tab param independently (as string | null),
then merge with the typed tab prop via ??.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Default settings and new-chat model preferences
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… guard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Deselect model block when clicking outside or re-clicking selected block
…blur

Fix sidepane blur state being forced on the reply panel
- Add currentVisualOrder store to track resolved visual order of model columns
- Extend cmd+1-8 keybindings to work with tools block (was compare-only)
- Use visual order for tools keybindings so cmd+1 always selects leftmost column
- Add cmd/ctrl+shift+space keybinding to scroll selected column into view
- Add data-tools-message-id attribute for DOM queries
…nearest

- Wrap activeMessages in useMemo so toolsItemOrder is stable and the
  setCurrentVisualOrder effect only fires when the order actually changes
- Update clearChat to also delete from currentVisualOrderByChatId (was
  leaking per-chat visual state on navigation)
- Add block: nearest to scrollIntoView to prevent unintended vertical scrolling
…r-keybindings

Fix cmd+number keybindings for tools and compare blocks
- added cmd+shift+space to focus selected block
- CMD+1-8 now smooth-scrolls the selected model column into view
- CMD+Shift+Space now moves the selected model to the first column position
- Added data-compare-message-id attribute to compare block columns for scroll targeting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bug fixes for cmd+KEY and multi-model selection states
… single model

replyToModelConfig?.modelId is a human-readable model string (e.g. "anthropic::claude-sonnet-4-5"),
but fetchModelConfigById expects a UUID primary key. Passing the wrong field caused it to return
null, silently skipping AI generation on reply.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 01:24
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the “reply to a single model silently skips AI response” bug by ensuring reply flows pass a model config primary key (config id) into block population. In addition, it introduces a broader set of model-management and UX features (visibility, profiles, defaults, minimize/reorder columns), plus supporting persistence/migrations and build/docs updates.

Changes:

  • Fix reply-to-single-model by passing/storing model config IDs (not provider model IDs) through the reply + populate pipeline.
  • Add model visibility filtering, model/prompt profiles, defaults management, and per-project default prompt profiles; update settings + pickers accordingly.
  • Add multi-model UX improvements (minimize/reorder columns, retry handling/tool-disable heuristics), title-generation model selection, and supporting migrations/build docs/workflow updates.

Reviewed changes

Copilot reviewed 47 out of 48 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/ui/lib/models.ts Removes quick-chat allowed-model allowlist constant.
src/ui/hooks/useShortcut.ts Adds enabled option gate to disable shortcuts without unmounting.
src/ui/components/VisibleModelsTab.tsx New Settings tab UI for toggling model visibility + fetching provider catalogs.
src/ui/components/ui/command.tsx Adds trailing adornment support in command input (e.g., shortcut hint).
src/ui/components/SortableColumnItem.tsx New DnD helper combining draggable + droppable for column reorder.
src/ui/components/Settings.tsx Restructures settings tabs; adds Defaults/Profiles/Visible Models tabs and title model selector.
src/ui/components/QuickChatModelSelector.tsx Uses centralized filtering + provider visibility map for ambient model selection.
src/ui/components/PromptProfilesTab.tsx New CRUD UI for prompt/persona profiles.
src/ui/components/PromptProfilePill.tsx New chat toolbar pill to pick/manage prompt profile per chat.
src/ui/components/ProjectView.tsx Adds per-project default prompt profile selection.
src/ui/components/MultiChatDeprecationPath.tsx Adds minimize/reorder behaviors to deprecated compare UI path.
src/ui/components/MultiChat.tsx Adds minimize/reorder UX for tools/compare blocks; integrates defaults/prompt-profile application on new chats.
src/ui/components/ModelProfilesTab.tsx New CRUD UI for model profiles (named model sets).
src/ui/components/ManageModelsBox.tsx Adds profile selector/apply + select-all shortcut; integrates visibility/profile filtering; supports per-chat selection/reorder hooks.
src/ui/components/DefaultsTab.tsx New consolidated Defaults settings (prompt profile, chat models, fallback, ambient, shortcut/accessibility).
src/ui/components/ChatInput.tsx Fixes reply-to-single-model by passing config id; persists per-chat compare selection; passes excluded minimized models and new-chat defaults flags.
src/ui/components/AppSidebar.tsx Adds “Minimized” panel to manage minimized models and retry failures from sidebar.
src/ui/App.tsx Redirects legacy quick-chat settings tab open requests to defaults.
src/core/utilities/Settings.ts Extends settings schema with defaults/title model; uses fresh-install default builder.
src/core/utilities/ModelFiltering.ts New centralized filtering utility combining visibility + active model profile constraints.
src/core/utilities/ChorusDefaultPreferences.ts New fresh-install default model/prompt settings seed values.
src/core/infra/ToolsDisabledStore.ts New per-chat/per-model tools-disabled store for retry behavior.
src/core/infra/ModelOrderStore.ts New per-chat model order + resolved visual order store for keybindings/UX.
src/core/infra/MinimizedModelsStore.ts New per-chat minimized-models store shared with sidebar/UI.
src/core/chorus/simpleLLM.ts Adds ability to run simple LLM calls via a specific model config ID.
src/core/chorus/prompts/prompts.ts Injects optional prompt-profile system prompt into model config prompts.
src/core/chorus/Models.ts Adds types for ProviderVisibility, ModelProfile, PromptProfile.
src/core/chorus/ModelProviders/simple/SimpleCompletionProviderFactory.ts Adds createProviderByPrefix for explicit-provider selection.
src/core/chorus/ModelProviders/ProviderGoogle.ts Adds support for gemini-2.5-flash-lite name mapping.
src/core/chorus/chatCreationDefaults.ts Applies defaults for new chats (prompt profile / ambient model metadata) and visibility/vision checks.
src/core/chorus/ChatCompareSelection.ts Implements initial compare-model selection priority and syncing global compare metadata to per-chat selection.
src/core/chorus/api/ProviderVisibilityAPI.ts New DB-backed provider-visible-models API + hooks and visibility map helper.
src/core/chorus/api/PromptProfilesAPI.ts New DB-backed prompt profiles + per-chat association APIs.
src/core/chorus/api/ProjectAPI.ts Adds defaultPromptProfileId to projects + mutation to set it.
src/core/chorus/api/ModelProfilesAPI.ts New DB-backed model profiles + active profile tracking via app_metadata.
src/core/chorus/api/ModelConfigChatAPI.ts Exposes saved per-chat model-config selection; resolves effective compare selection with visibility filtering.
src/core/chorus/api/MessageAPI.ts Major updates: prompt-profile injection, retry improvements, tools-disable heuristics, populate behavior changes, title generation model selection, per-chat selection handling.
src/core/chorus/api/ChatAPI.ts Initializes per-chat compare selection on chat creation; applies creation defaults post-insert.
src-tauri/tauri.qa.conf.json Version bump.
src-tauri/tauri.dev.conf.json Version bump.
src-tauri/tauri.conf.json Version bump.
src-tauri/src/migrations.rs Adds tables and model updates for visibility/profiles/defaults; adds gemini model changes; adds project default prompt profile column.
README.md Documents fork-specific features and unsigned app note; adds build doc link.
package.json Version bump; updates @tauri-apps/plugin-store version.
BUILD.md New build instructions.
.github/workflows/build.yml New GitHub Actions workflow for building (and optionally releasing) macOS bundles.
.cursor/worktrees.json Adds worktree setup command configuration for Cursor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2642 to +2654
Migration {
version: 144,
description: "add default_prompt_profile_id to projects",
kind: MigrationKind::Up,
sql: r#"
ALTER TABLE projects ADD COLUMN default_prompt_profile_id TEXT DEFAULT NULL;
"#,
},
Migration {
version: 143,
description: "add gemini 2.5 flash lite and update ambient to use it",
kind: MigrationKind::Up,
sql: r#"
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new migrations are not listed in ascending version order (version 144 appears before 143). If the migration runner applies migrations in vector order (rather than sorting by version), this can lead to incorrect application/recording order. Please reorder these entries so migrations are appended in monotonically increasing version order (…142, 143, 144).

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +119
export function useProviderVisibilityMap(): Map<string, boolean> | undefined {
const { data } = useProviderVisibleModels();
if (!data) return undefined;

return new Map(data.map((v) => [v.modelId, v.isVisible]));
}
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useProviderVisibilityMap() creates and returns a new Map instance on every render. Because many callers use this value in useMemo/dependency arrays, this forces unnecessary recomputation even when the underlying data hasn't changed. Consider memoizing the map with useMemo keyed on data (or return the raw array and let callers memoize) so the reference stays stable across renders.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +111

const visibleConfigs = useMemo(
() =>
getFilteredModelConfigs(
modelConfigsQuery.data ?? [],
providerVisibilityMap,
null,
),
[modelConfigsQuery.data, providerVisibilityMap],
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useChatCompareModelConfigs builds visibleConfigs using getFilteredModelConfigs(..., null) (no active model profile). Elsewhere (e.g. ChatCompareSelection.fetchVisibleModelConfigsForSelection and ManageModelsBox) the active model profile is applied, so this can produce an inconsistent state where the current chat selection includes models outside the active profile and the picker UI can't represent them. Consider including the active model profile here as well (or explicitly document that chat compare selection ignores the active profile).

Suggested change
const visibleConfigs = useMemo(
() =>
getFilteredModelConfigs(
modelConfigsQuery.data ?? [],
providerVisibilityMap,
null,
),
[modelConfigsQuery.data, providerVisibilityMap],
const activeModelProfileQuery = ModelsAPI.useActiveModelProfile();
const visibleConfigs = useMemo(
() =>
getFilteredModelConfigs(
modelConfigsQuery.data ?? [],
providerVisibilityMap,
activeModelProfileQuery.data ?? null,
),
[
modelConfigsQuery.data,
providerVisibilityMap,
activeModelProfileQuery.data,
],

Copilot uses AI. Check for mistakes.
Comment on lines 360 to +365
void populateBlock.mutateAsync({
messageSetId: aiMessageSetId,
blockType: BLOCK_TYPE,
replyToModelId: replyToModelConfig?.modelId,
replyToModelId: replyToModelConfig?.id,
excludedModelIds: minimizedModels,
applyChatCreationModelDefaults,
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title/description states this is a one-line fix for single-model reply (replyToModelConfig?.modelIdreplyToModelConfig?.id), but this PR also introduces substantial new functionality (model visibility, model/prompt profiles, minimize/reorder UI, defaults, new migrations, etc.). Please either update the PR description to reflect the full scope or split these unrelated changes into separate PRs to reduce review/rollback risk.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants