feat(stt): add local STT model status handling#2331
feat(stt): add local STT model status handling#2331ComputelessComputer wants to merge 1 commit intomainfrom
Conversation
📝 WalkthroughWalkthroughThese changes enhance STT (speech-to-text) status awareness in the desktop UI. Two new banners—"stt-loading" and "stt-unreachable"—are added to the banner registry to display transcription model status conditionally. The settings component is updated to import connection awareness and reflect model configuration and server reachability states with conditional styling and error messaging. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyprnote-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/desktop/src/components/main/sidebar/banner/registry.tsx (1)
34-41: Consider movinganimate-pingto an indicator element.The
animate-pinganimation on the text "loading" might reduce readability. Typically, this animation is applied to visual indicators (like dots or icons) while keeping text static.Consider this alternative approach:
description: ( <> Transcription model is - <strong className="font-mono animate-ping text-amber-500"> - loading - </strong> + <strong className="font-mono text-amber-500"> + <span className="inline-block size-1.5 rounded-full bg-amber-500 animate-ping mr-1" /> + loading + </strong> . This may take a moment. </> ),
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/desktop/src/components/main/sidebar/banner/registry.tsx(1 hunks)apps/desktop/src/components/settings/ai/stt/select.tsx(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, usecn(import from@hypr/utils). It is similar toclsx. Always pass an array and split by logical grouping.
Usemotion/reactinstead offramer-motion.
Files:
apps/desktop/src/components/settings/ai/stt/select.tsxapps/desktop/src/components/main/sidebar/banner/registry.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Redirect rules - hyprnote-storybook
- GitHub Check: Header rules - hyprnote-storybook
- GitHub Check: Pages changed - hyprnote-storybook
- GitHub Check: Redirect rules - hyprnote
- GitHub Check: Header rules - hyprnote
- GitHub Check: Pages changed - hyprnote
🔇 Additional comments (4)
apps/desktop/src/components/settings/ai/stt/select.tsx (4)
18-18: LGTM!The STT connection hook integration is clean and uses appropriate optional chaining for safe property access.
Also applies to: 39-40
42-48: LGTM!The computed flags correctly identify local STT model usage, unreachable status, and missing configuration. The logic is clear and appropriately defensive.
90-95: LGTM!The conditional styling correctly uses the
cnutility with array syntax and appropriately applies error styling (red background) when configuration is missing or the service is unreachable.
224-240: LGTM!The error message blocks provide clear, actionable feedback to users. The conditions are mutually exclusive by design (not configured requires missing config, while unreachable requires a configured local model), preventing conflicting messages.
| { | ||
| banner: { | ||
| id: "stt-loading", | ||
| description: ( | ||
| <> | ||
| Transcription model is | ||
| <strong className="font-mono animate-ping text-amber-500"> | ||
| loading | ||
| </strong> | ||
| . This may take a moment. | ||
| </> | ||
| ), | ||
| primaryAction: { | ||
| label: "View status", | ||
| onClick: onOpenSTTSettings, | ||
| }, | ||
| dismissible: false, | ||
| }, | ||
| condition: () => | ||
| isLocalSttModel && | ||
| sttServerStatus === "loading" && | ||
| !hasSttConfigured && | ||
| !isAiTranscriptionTabActive, | ||
| }, | ||
| { | ||
| banner: { | ||
| id: "stt-unreachable", | ||
| variant: "error", | ||
| description: ( | ||
| <> | ||
| Transcription model{" "} | ||
| <strong className="font-mono text-red-500">failed to start</strong>. | ||
| Please try again. | ||
| </> | ||
| ), | ||
| primaryAction: { | ||
| label: "Configure transcription", | ||
| onClick: onOpenSTTSettings, | ||
| }, | ||
| dismissible: false, | ||
| }, | ||
| condition: () => | ||
| isLocalSttModel && | ||
| sttServerStatus === "unreachable" && | ||
| !hasSttConfigured && | ||
| !isAiTranscriptionTabActive, | ||
| }, |
There was a problem hiding this comment.
Critical: Undefined variables in banner conditions.
The condition functions reference isLocalSttModel and sttServerStatus, but these variables are not defined in this file, not passed as parameters, and not imported. This will cause a ReferenceError at runtime when the conditions are evaluated.
Apply this diff to add the missing parameters:
type BannerRegistryParams = {
isAuthenticated: boolean;
hasLLMConfigured: boolean;
hasSttConfigured: boolean;
+ isLocalSttModel: boolean;
+ sttServerStatus?: "loading" | "unreachable" | "running";
isAiTranscriptionTabActive: boolean;
isAiIntelligenceTabActive: boolean;
onSignIn: () => void | Promise<void>;
onOpenLLMSettings: () => void;
onOpenSTTSettings: () => void;
};
export function createBannerRegistry({
isAuthenticated,
hasLLMConfigured,
hasSttConfigured,
+ isLocalSttModel,
+ sttServerStatus,
isAiTranscriptionTabActive,
isAiIntelligenceTabActive,
onSignIn,
onOpenLLMSettings,
onOpenSTTSettings,
}: BannerRegistryParams): BannerRegistryEntry[] {Then update the calling code to compute and pass these values (similar to how they're computed in select.tsx lines 42-47).
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/desktop/src/components/main/sidebar/banner/registry.tsx around lines
31-77 the condition functions reference undefined variables (isLocalSttModel,
sttServerStatus, hasSttConfigured, isAiTranscriptionTabActive) causing runtime
ReferenceErrors; update the banner entries so each condition accepts those
values as parameters (e.g., condition: ({ isLocalSttModel, sttServerStatus,
hasSttConfigured, isAiTranscriptionTabActive }) => ...) and then update the
caller that evaluates these registry conditions to compute those four values
(following the logic in select.tsx lines 42-47) and pass them into condition
when checking whether to show each banner. Ensure signatures match across
registry and call sites so the variables are provided instead of referenced
globally.
• Added local Speech-to-Text (STT) model status handling functionality
• Implemented status tracking for local STT models