Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions apps/desktop/src/components/main/sidebar/banner/registry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,53 @@ export function createBannerRegistry({
}: BannerRegistryParams): BannerRegistryEntry[] {
// order matters
return [
{
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,
},
Comment on lines +31 to +77
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

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.

{
banner: {
id: "missing-stt",
Expand Down
26 changes: 22 additions & 4 deletions apps/desktop/src/components/settings/ai/stt/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { cn } from "@hypr/utils";

import { useBillingAccess } from "../../../../billing";
import { useConfigValues } from "../../../../config/use-config";
import { useSTTConnection } from "../../../../hooks/useSTTConnection";
import * as settings from "../../../../store/tinybase/settings";
import {
getProviderSelectionBlockers,
Expand All @@ -35,6 +36,16 @@ export function SelectProviderAndModel() {
] as const);
const billing = useBillingAccess();
const configuredProviders = useConfiguredMapping();
const { local: sttLocal } = useSTTConnection();
const sttServerStatus = sttLocal.data?.status;

const isLocalSttModel =
current_stt_provider === "hyprnote" &&
!!current_stt_model &&
current_stt_model !== "cloud";

const isUnreachable = isLocalSttModel && sttServerStatus === "unreachable";
const isNotConfigured = !current_stt_provider || !current_stt_model;

const handleSelectProvider = settings.UI.useSetValueCallback(
"current_stt_provider",
Expand Down Expand Up @@ -80,9 +91,7 @@ export function SelectProviderAndModel() {
className={cn([
"flex flex-col gap-4",
"p-4 rounded-xl border border-neutral-200",
!!current_stt_provider && !!current_stt_model
? "bg-neutral-50"
: "bg-red-50",
isNotConfigured || isUnreachable ? "bg-red-50" : "bg-neutral-50",
])}
>
<div className="flex flex-row items-center gap-4">
Expand Down Expand Up @@ -212,14 +221,23 @@ export function SelectProviderAndModel() {
)}
</div>

{(!current_stt_provider || !current_stt_model) && (
{isNotConfigured && (
<div className="flex items-center gap-2 pt-2 border-t border-red-200">
<span className="text-sm text-red-600">
<strong className="font-medium">Transcription model</strong> is
needed to make Hyprnote listen to your conversations.
</span>
</div>
)}

{isUnreachable && (
<div className="flex items-center gap-2 pt-2 border-t border-red-200">
<span className="text-sm text-red-600">
<strong className="font-medium">Transcription model</strong>{" "}
failed to start. Please try again.
</span>
</div>
)}
</div>
</div>
);
Expand Down
Loading