Skip to content
Merged
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
5 changes: 2 additions & 3 deletions .github/workflows/desktop_cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,13 @@
AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
- if: ${{ matrix.target == 'aarch64-apple-darwin' }}
run: |
chmod +x apps/desktop/src-tauri/binaries/stt-${{ matrix.target }}
./scripts/sidecar.sh "apps/desktop/${{ env.TAURI_CONF_PATH }}" "binaries/stt"
run: chmod +x ./apps/desktop/src-tauri/binaries/stt-${{ matrix.target }} && ./scripts/sidecar.sh "./apps/desktop/${{ env.TAURI_CONF_PATH }}" "binaries/stt"

Check warning

Code scanning / zizmor

code injection via template expansion Warning

code injection via template expansion
- run: pnpm -F desktop tauri build --target ${{ matrix.target }} --config ${{ env.TAURI_CONF_PATH }} --verbose
env:
# https://github.com/tauri-apps/tauri-action/issues/740
CI: false
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AM_API_KEY: ${{ secrets.AM_API_KEY }}
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
KEYGEN_ACCOUNT_ID: ${{ secrets.KEYGEN_ACCOUNT_ID }}
Expand Down
34 changes: 28 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rust-version = "1.88.0"
[workspace.dependencies]
hypr-aec = { path = "crates/aec", package = "aec" }
hypr-agc = { path = "crates/agc", package = "agc" }
hypr-am = { path = "crates/am", package = "am" }
hypr-analytics = { path = "crates/analytics", package = "analytics" }
hypr-audio = { path = "crates/audio", package = "audio" }
hypr-audio-utils = { path = "crates/audio-utils", package = "audio-utils" }
Expand All @@ -47,6 +48,7 @@ hypr-kyutai = { path = "crates/kyutai", package = "kyutai" }
hypr-language = { path = "crates/language", package = "language" }
hypr-llama = { path = "crates/llama", package = "llama" }
hypr-loops = { path = "crates/loops", package = "loops" }
hypr-moonshine = { path = "crates/moonshine", package = "moonshine" }
hypr-nango = { path = "crates/nango", package = "nango" }
hypr-network = { path = "crates/network", package = "network" }
hypr-notification = { path = "crates/notification", package = "notification" }
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> AppExt<R> for T {
.unwrap_or(hypr_whisper_local_model::WhisperModel::QuantizedBaseEn);

if let Ok(true) = self.is_model_downloaded(&current_model).await {
if let Err(e) = self.start_server().await {
if let Err(e) = self.start_server(None).await {
tracing::error!("start_local_stt_server: {}", e);
}
}
Expand Down
13 changes: 5 additions & 8 deletions apps/desktop/src/components/settings/components/ai/stt-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

// Add these imports for file operations
// import { message } from "@tauri-apps/plugin-dialog";
// import { writeFile } from "@tauri-apps/plugin-fs";

import { commands as dbCommands } from "@hypr/plugin-db";
import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands, type WhisperModel } from "@hypr/plugin-local-stt";
import { Button } from "@hypr/ui/components/ui/button";
import {
Form,
Expand All @@ -28,7 +24,7 @@ import { cn } from "@hypr/ui/lib/utils";
import { WERPerformanceModal } from "../wer-modal";
import { SharedSTTProps } from "./shared";

export const sttModelMetadata: Record<SupportedModel, {
export const sttModelMetadata: Record<WhisperModel, {
name: string;
description: string;
intelligence: number;
Expand Down Expand Up @@ -353,8 +349,9 @@ export function STTView({
onClick={() => {
if (model.downloaded) {
setSelectedSTTModel(model.key);
localSttCommands.setCurrentModel(model.key as SupportedModel);
localSttCommands.restartServer();
localSttCommands.setCurrentModel(model.key as WhisperModel);
localSttCommands.stopServer(null);
localSttCommands.startServer(null);
}
}}
>
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/components/toast/model-select.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { LinkProps } from "@tanstack/react-router";

import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands, type WhisperModel } from "@hypr/plugin-local-stt";
import { commands as windowsCommands } from "@hypr/plugin-windows";
import { Button } from "@hypr/ui/components/ui/button";
import { sonnerToast, toast } from "@hypr/ui/components/ui/toast";

export async function showModelSelectToast(language: string) {
const currentModel = await localSttCommands.getCurrentModel();
const englishModels: SupportedModel[] = ["QuantizedTinyEn", "QuantizedBaseEn", "QuantizedSmallEn"];
const englishModels: WhisperModel[] = ["QuantizedTinyEn", "QuantizedBaseEn", "QuantizedSmallEn"];

if (language === "en" || !englishModels.includes(currentModel)) {
return;
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/components/toast/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Channel } from "@tauri-apps/api/core";
import { useEffect, useState } from "react";

import { commands as localLlmCommands, SupportedModel as SupportedModelLLM } from "@hypr/plugin-local-llm";
import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands, type WhisperModel } from "@hypr/plugin-local-stt";
import { commands as windowsCommands } from "@hypr/plugin-windows";
import { Button } from "@hypr/ui/components/ui/button";
import { Progress } from "@hypr/ui/components/ui/progress";
Expand Down Expand Up @@ -52,7 +52,7 @@ export const DownloadProgress = ({
);
};

export function showSttModelDownloadToast(model: SupportedModel, onComplete?: () => void, queryClient?: QueryClient) {
export function showSttModelDownloadToast(model: WhisperModel, onComplete?: () => void, queryClient?: QueryClient) {
const sttChannel = new Channel();

localSttCommands.downloadModel(model, sttChannel);
Expand All @@ -77,7 +77,7 @@ export function showSttModelDownloadToast(model: SupportedModel, onComplete?: ()
onComplete={() => {
sonnerToast.dismiss(id);
localSttCommands.setCurrentModel(model);
localSttCommands.startServer();
localSttCommands.startServer(null);
if (onComplete) {
onComplete();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BrainIcon, CheckCircle2Icon, MicIcon } from "lucide-react";
import { useEffect, useState } from "react";

import { commands as localLlmCommands } from "@hypr/plugin-local-llm";
import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands, type WhisperModel } from "@hypr/plugin-local-stt";
import { Progress } from "@hypr/ui/components/ui/progress";
import PushableButton from "@hypr/ui/components/ui/pushable-button";
import { cn } from "@hypr/ui/lib/utils";
Expand All @@ -18,7 +18,7 @@ interface ModelDownloadProgress {
}

interface DownloadProgressViewProps {
selectedSttModel: SupportedModel;
selectedSttModel: WhisperModel;
llmSelection: "hyprllm" | "byom" | null;
onContinue: () => void;
}
Expand Down Expand Up @@ -174,7 +174,7 @@ export const DownloadProgressView = ({
if (sttDownload.completed) {
try {
await localSttCommands.setCurrentModel(selectedSttModel);
await localSttCommands.startServer();
await localSttCommands.startServer(null);
} catch (error) {
console.error("Error setting up STT:", error);
}
Expand Down
21 changes: 10 additions & 11 deletions apps/desktop/src/components/welcome-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { message } from "@tauri-apps/plugin-dialog";
import { ArrowLeft } from "lucide-react"; // Add this import
import { ArrowLeft } from "lucide-react";
import { useEffect, useState } from "react";

import { showLlmModelDownloadToast, showSttModelDownloadToast } from "@/components/toast/shared";
import { commands } from "@/types";
import { commands as authCommands, events } from "@hypr/plugin-auth";
import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands, type WhisperModel } from "@hypr/plugin-local-stt";
import { commands as sfxCommands } from "@hypr/plugin-sfx";
import { Modal, ModalBody } from "@hypr/ui/components/ui/modal";
import { Particles } from "@hypr/ui/components/ui/particles";
import { ConfigureEndpointConfig } from "../settings/components/ai/shared";

import { useHypr } from "@/contexts";
import { zodResolver } from "@hookform/resolvers/zod";
import { commands as analyticsCommands } from "@hypr/plugin-analytics";
import { commands as connectorCommands } from "@hypr/plugin-connector";
import { commands as dbCommands } from "@hypr/plugin-db";
import { commands as localLlmCommands } from "@hypr/plugin-local-llm";
import { Trans } from "@lingui/react/macro";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AudioPermissionsView } from "./audio-permissions-view";
// import { CalendarPermissionsView } from "./calendar-permissions-view";
import { useHypr } from "@/contexts";
import { commands as analyticsCommands } from "@hypr/plugin-analytics";
import { Trans } from "@lingui/react/macro";
import { CustomEndpointView } from "./custom-endpoint-view";
import { DownloadProgressView } from "./download-progress-view";
import { LanguageSelectionView } from "./language-selection-view";
Expand Down Expand Up @@ -72,13 +71,13 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
| "custom-endpoint"
| "language-selection"
>("welcome");
const [selectedSttModel, setSelectedSttModel] = useState<SupportedModel>("QuantizedSmall");
const [selectedSttModel, setSelectedSttModel] = useState<WhisperModel>("QuantizedSmall");
const [wentThroughDownloads, setWentThroughDownloads] = useState(false);
const [llmSelection, setLlmSelection] = useState<"hyprllm" | "byom" | null>(null);
const [cameFromLlmSelection, setCameFromLlmSelection] = useState(false);

const selectSTTModel = useMutation({
mutationFn: (model: SupportedModel) => localSttCommands.setCurrentModel(model),
mutationFn: (model: WhisperModel) => localSttCommands.setCurrentModel(model),
});

const openaiForm = useForm<{ api_key: string; model: string }>({
Expand Down Expand Up @@ -253,7 +252,7 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
setCurrentStep("audio-permissions");
};

const handleModelSelected = (model: SupportedModel) => {
const handleModelSelected = (model: WhisperModel) => {
selectSTTModel.mutate(model);
setSelectedSttModel(model);
sessionStorage.setItem("model-download-toast-dismissed", "true");
Expand Down Expand Up @@ -305,13 +304,13 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {

useEffect(() => {
if (!isOpen && wentThroughDownloads) {
localSttCommands.startServer();
localSttCommands.startServer(null);

localLlmCommands.startServer();

const checkAndShowToasts = async () => {
try {
const sttModelExists = await localSttCommands.isModelDownloaded(selectedSttModel as SupportedModel);
const sttModelExists = await localSttCommands.isModelDownloaded(selectedSttModel as WhisperModel);

if (!sttModelExists) {
showSttModelDownloadToast(selectedSttModel, undefined, queryClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React, { useState } from "react";

import { Card, CardContent } from "@hypr/ui/components/ui/card";

import { SupportedModel } from "@hypr/plugin-local-stt";
import { type WhisperModel } from "@hypr/plugin-local-stt";
import { commands as localSttCommands } from "@hypr/plugin-local-stt";
import PushableButton from "@hypr/ui/components/ui/pushable-button";
import { cn } from "@hypr/ui/lib/utils";
Expand Down Expand Up @@ -45,9 +45,9 @@ const RatingDisplay = (
export const ModelSelectionView = ({
onContinue,
}: {
onContinue: (model: SupportedModel) => void;
onContinue: (model: WhisperModel) => void;
}) => {
const [selectedModel, setSelectedModel] = useState<SupportedModel>("QuantizedSmall");
const [selectedModel, setSelectedModel] = useState<WhisperModel>("QuantizedSmall");

const supportedSTTModels = useQuery<ModelInfo[]>({
queryKey: ["local-stt", "supported-models"],
Expand Down Expand Up @@ -82,7 +82,7 @@ export const ModelSelectionView = ({
})
?.map(modelInfo => {
const model = modelInfo.model;
const metadata = sttModelMetadata[model as SupportedModel];
const metadata = sttModelMetadata[model as WhisperModel];
if (!metadata) {
Comment on lines +85 to 86
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove casts by typing ModelInfo.model as WhisperModel

Typing ModelInfo.model eliminates the need for casts at usage sites.

-interface ModelInfo {
-  model: string;
-  is_downloaded: boolean;
-}
+interface ModelInfo {
+  model: WhisperModel;
+  is_downloaded: boolean;
+}
@@
-              const metadata = sttModelMetadata[model as WhisperModel];
+              const metadata = sttModelMetadata[model];
@@
-                      onClick={() => setSelectedModel(model as WhisperModel)}
+                      onClick={() => setSelectedModel(model)}

Also applies to: 102-103

🤖 Prompt for AI Agents
In apps/desktop/src/components/welcome-modal/model-selection-view.tsx around
lines 85-86 and 102-103, remove the explicit type casts of model to WhisperModel
by updating the type definition of ModelInfo.model to be WhisperModel. This
change will ensure that the model property is already correctly typed,
eliminating the need for casting at usage sites and improving type safety and
code clarity.

return null;
}
Expand All @@ -99,7 +99,7 @@ export const ModelSelectionView = ({
? "ring-2 ring-blue-500 border-blue-500 bg-blue-50"
: "hover:border-gray-400",
)}
onClick={() => setSelectedModel(model as SupportedModel)}
onClick={() => setSelectedModel(model as WhisperModel)}
>
<CardContent className="flex flex-col gap-2 sm:gap-4 justify-between p-3 sm:p-5 h-48 sm:h-56">
<div className="flex-1 text-center">
Expand Down
8 changes: 4 additions & 4 deletions apps/desktop/src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ msgstr "Audio Permissions"
msgid "Autonomy Selector"
msgstr "Autonomy Selector"

#: src/components/welcome-modal/index.tsx:351
#: src/components/welcome-modal/index.tsx:362
#: src/components/welcome-modal/index.tsx:350
#: src/components/welcome-modal/index.tsx:361
msgid "Back"
msgstr "Back"

Expand Down Expand Up @@ -1189,7 +1189,7 @@ msgstr "Pause"
msgid "people"
msgstr "people"

#: src/components/settings/components/ai/stt-view.tsx:332
#: src/components/settings/components/ai/stt-view.tsx:328
msgid "Performance difference between languages"
msgstr "Performance difference between languages"

Expand Down Expand Up @@ -1510,7 +1510,7 @@ msgstr "Toggle left sidebar"
msgid "Toggle widget panel"
msgstr "Toggle widget panel"

#: src/components/settings/components/ai/stt-view.tsx:323
#: src/components/settings/components/ai/stt-view.tsx:319
msgid "Transcribing"
msgstr "Transcribing"

Expand Down
Loading
Loading