From 9078db9fb854f3efd1db129a41c0b27d31c6bb18 Mon Sep 17 00:00:00 2001 From: Deokhaeng Lee Date: Mon, 7 Jul 2025 03:02:06 +0900 Subject: [PATCH 1/4] hotfix --- .../editor-area/floating-button.tsx | 8 +-- .../src/components/editor-area/index.tsx | 62 ++++++++++++------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/apps/desktop/src/components/editor-area/floating-button.tsx b/apps/desktop/src/components/editor-area/floating-button.tsx index 038f7b0c8b..c6cde31416 100644 --- a/apps/desktop/src/components/editor-area/floating-button.tsx +++ b/apps/desktop/src/components/editor-area/floating-button.tsx @@ -46,7 +46,7 @@ interface FloatingButtonProps { handleEnhanceWithTemplate: (templateId: string) => void; templates: Template[]; isError: boolean; - progress: number; + progress?: number; isLocalLlm: boolean; } @@ -56,7 +56,7 @@ export function FloatingButton({ handleEnhanceWithTemplate, templates, isError, - progress, + progress = 0, isLocalLlm, }: FloatingButtonProps) { const { userId } = useHypr(); @@ -180,8 +180,8 @@ export function FloatingButton({ } }; - // Only show progress for local LLMs - const shouldShowProgress = isLocalLlm && progress >= 0 && progress < 1; + // Only show progress for local LLMs AND when progress exists + const shouldShowProgress = isLocalLlm && progress !== undefined && progress >= 0 && progress < 1; if (isError) { const errorRetryButtonClasses = cn( diff --git a/apps/desktop/src/components/editor-area/index.tsx b/apps/desktop/src/components/editor-area/index.tsx index d8d25d337d..cfe6a0edb8 100644 --- a/apps/desktop/src/components/editor-area/index.tsx +++ b/apps/desktop/src/components/editor-area/index.tsx @@ -97,10 +97,16 @@ export default function EditorArea({ const preMeetingNote = useSession(sessionId, (s) => s.session.pre_meeting_memo_html) ?? ""; const hasTranscriptWords = useSession(sessionId, (s) => s.session.words.length > 0); + const llmConnectionQuery = useQuery({ + queryKey: ["llm-connection"], + queryFn: () => connectorCommands.getLlmConnection(), + }); + const { enhance, progress } = useEnhanceMutation({ sessionId, preMeetingNote, rawContent, + isLocalLlm: llmConnectionQuery.data?.type === "HyprLocal", onSuccess: (content) => { generateTitle.mutate({ enhancedContent: content }); @@ -205,11 +211,6 @@ export default function EditorArea({ })); }; - const llmConnectionQuery = useQuery({ - queryKey: ["llm-connection"], - queryFn: () => connectorCommands.getLlmConnection(), - }); - return (
void; }) { const { userId, onboardingSessionId } = useHypr(); @@ -313,7 +316,10 @@ export function useEnhanceMutation({ const enhance = useMutation({ mutationKey: ["enhance", sessionId], mutationFn: async () => { - setProgress(0); // Reset progress when starting + if (isLocalLlm) { + setProgress(0); + } + const fn = sessionId === onboardingSessionId ? dbCommands.getWordsOnboarding : dbCommands.getWords; @@ -406,9 +412,11 @@ Sections:`; const { text, fullStream } = streamText({ abortSignal, model, - tools: { - update_progress: tool({ parameters: z.any() }), - }, + ...(isLocalLlm && { + tools: { + update_progress: tool({ parameters: z.any() }), + }, + }), messages: [ { role: "system", content: systemMessage }, { role: "user", content: userMessage }, @@ -417,18 +425,20 @@ Sections:`; markdownTransform(), smoothStream({ delayInMs: 80, chunking: "line" }), ], - providerOptions: { - [localProviderName]: { - metadata: customGrammar - ? { - grammar: "custom", - customGrammar: customGrammar, - } - : { - grammar: "enhance", - }, + ...(isLocalLlm && { + providerOptions: { + [localProviderName]: { + metadata: customGrammar + ? { + grammar: "custom", + customGrammar: customGrammar, + } + : { + grammar: "enhance", + }, + }, }, - }, + }), }); let acc = ""; @@ -436,7 +446,7 @@ Sections:`; if (chunk.type === "text-delta") { acc += chunk.textDelta; } - if (chunk.type === "tool-call") { + if (chunk.type === "tool-call" && isLocalLlm) { const chunkProgress = chunk.args?.progress ?? 0; setProgress(chunkProgress); } @@ -459,10 +469,14 @@ Sections:`; }); persistSession(); - setProgress(0); + if (isLocalLlm) { + setProgress(0); + } }, onError: (error) => { - setProgress(0); + if (isLocalLlm) { + setProgress(0); + } console.error(error); if (!(error as unknown as string).includes("cancel")) { @@ -471,7 +485,7 @@ Sections:`; }, }); - return { enhance, progress }; + return { enhance, progress: isLocalLlm ? progress : undefined }; } function useGenerateTitleMutation({ sessionId }: { sessionId: string }) { From a774fb792a87df68d09cb852734adf08870a7bf4 Mon Sep 17 00:00:00 2001 From: Deokhaeng Lee Date: Mon, 7 Jul 2025 03:04:15 +0900 Subject: [PATCH 2/4] went through formatting --- apps/desktop/src/components/editor-area/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/src/components/editor-area/index.tsx b/apps/desktop/src/components/editor-area/index.tsx index cfe6a0edb8..2105cb462e 100644 --- a/apps/desktop/src/components/editor-area/index.tsx +++ b/apps/desktop/src/components/editor-area/index.tsx @@ -319,7 +319,7 @@ export function useEnhanceMutation({ if (isLocalLlm) { setProgress(0); } - + const fn = sessionId === onboardingSessionId ? dbCommands.getWordsOnboarding : dbCommands.getWords; From 5abd55db8c9a96d06357c58e0875b99c35914bc1 Mon Sep 17 00:00:00 2001 From: Deokhaeng Lee Date: Mon, 7 Jul 2025 17:41:22 +0900 Subject: [PATCH 3/4] hotfix - re-fetching logic --- .../editor-area/floating-button.tsx | 84 +++++++++++-------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/apps/desktop/src/components/editor-area/floating-button.tsx b/apps/desktop/src/components/editor-area/floating-button.tsx index c6cde31416..b1ce5248fb 100644 --- a/apps/desktop/src/components/editor-area/floating-button.tsx +++ b/apps/desktop/src/components/editor-area/floating-button.tsx @@ -1,5 +1,6 @@ import { PlusIcon, RefreshCwIcon, TypeOutlineIcon, XIcon, ZapIcon } from "lucide-react"; import { useEffect, useRef, useState } from "react"; +import { useQueryClient } from "@tanstack/react-query"; import { useHypr } from "@/contexts"; import { useEnhancePendingState } from "@/hooks/enhance-pending"; @@ -70,6 +71,7 @@ export function FloatingButton({ const [showRefreshIcon, setShowRefreshIcon] = useState(true); const [showTemplatePopover, setShowTemplatePopover] = useState(false); const hideTimeoutRef = useRef(null); + const queryClient = useQueryClient(); // Clear timeout on cleanup useEffect(() => { @@ -111,6 +113,7 @@ export function FloatingButton({ hideTimeoutRef.current = null; } if (!showRaw && !isEnhancePending && showRefreshIcon) { + queryClient.invalidateQueries({ queryKey: ["templates"] }); setShowTemplatePopover(true); } }; @@ -121,11 +124,11 @@ export function FloatingButton({ }, 100); }; - // Simple template selection - just call parent function const handleTemplateSelect = (templateId: string) => { setShowTemplatePopover(false); - // Send analytics event for custom template usage (not for "auto") + queryClient.invalidateQueries({ queryKey: ["llm-connection"] }); + if (templateId !== "auto") { analyticsCommands.event({ event: "custom_template_enhancement_started", @@ -136,45 +139,22 @@ export function FloatingButton({ handleEnhanceWithTemplate(templateId); }; - // Helper function to extract emoji and clean name - const extractEmojiAndName = (title: string) => { - const emojiMatch = title.match(/^(\p{Emoji})\s*/u); - if (emojiMatch) { - return { - emoji: emojiMatch[1], - name: title.replace(/^(\p{Emoji})\s*/u, "").trim(), - }; - } - - // Fallback emoji based on keywords if no emoji in title - const lowercaseTitle = title.toLowerCase(); - let fallbackEmoji = "📄"; - if (lowercaseTitle.includes("meeting")) { - fallbackEmoji = "💼"; - } - if (lowercaseTitle.includes("interview")) { - fallbackEmoji = "👔"; - } - if (lowercaseTitle.includes("standup")) { - fallbackEmoji = "☀️"; - } - if (lowercaseTitle.includes("review")) { - fallbackEmoji = "📝"; - } - - return { - emoji: fallbackEmoji, - name: title, - }; - }; - const handleAddTemplate = async () => { setShowTemplatePopover(false); try { - // Open settings window + queryClient.invalidateQueries({ queryKey: ["templates"] }); + await windowsCommands.windowShow({ type: "settings" }); - // Navigate to templates tab await windowsCommands.windowNavigate({ type: "settings" }, "/app/settings?tab=templates"); + + const handleWindowFocus = () => { + queryClient.invalidateQueries({ queryKey: ["templates"] }); + queryClient.invalidateQueries({ queryKey: ["llm-connection"] }); + window.removeEventListener("focus", handleWindowFocus); + }; + + window.addEventListener("focus", handleWindowFocus); + } catch (error) { console.error("Failed to open settings/templates:", error); } @@ -356,3 +336,35 @@ function RunOrRerun({ showRefresh }: { showRefresh: boolean }) {
); } + +// Helper function to extract emoji and clean name +const extractEmojiAndName = (title: string) => { + const emojiMatch = title.match(/^(\p{Emoji})\s*/u); + if (emojiMatch) { + return { + emoji: emojiMatch[1], + name: title.replace(/^(\p{Emoji})\s*/u, "").trim(), + }; + } + + // Fallback emoji based on keywords if no emoji in title + const lowercaseTitle = title.toLowerCase(); + let fallbackEmoji = "📄"; + if (lowercaseTitle.includes("meeting")) { + fallbackEmoji = "💼"; + } + if (lowercaseTitle.includes("interview")) { + fallbackEmoji = "👔"; + } + if (lowercaseTitle.includes("standup")) { + fallbackEmoji = "☀️"; + } + if (lowercaseTitle.includes("review")) { + fallbackEmoji = "📝"; + } + + return { + emoji: fallbackEmoji, + name: title, + }; +}; From ae6205b13ff1ee6f07013b47ae459a868cbfbdd7 Mon Sep 17 00:00:00 2001 From: Deokhaeng Lee Date: Mon, 7 Jul 2025 17:48:17 +0900 Subject: [PATCH 4/4] formatted --- .../src/components/editor-area/floating-button.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/components/editor-area/floating-button.tsx b/apps/desktop/src/components/editor-area/floating-button.tsx index b1ce5248fb..68e582536a 100644 --- a/apps/desktop/src/components/editor-area/floating-button.tsx +++ b/apps/desktop/src/components/editor-area/floating-button.tsx @@ -1,6 +1,6 @@ +import { useQueryClient } from "@tanstack/react-query"; import { PlusIcon, RefreshCwIcon, TypeOutlineIcon, XIcon, ZapIcon } from "lucide-react"; import { useEffect, useRef, useState } from "react"; -import { useQueryClient } from "@tanstack/react-query"; import { useHypr } from "@/contexts"; import { useEnhancePendingState } from "@/hooks/enhance-pending"; @@ -143,18 +143,17 @@ export function FloatingButton({ setShowTemplatePopover(false); try { queryClient.invalidateQueries({ queryKey: ["templates"] }); - + await windowsCommands.windowShow({ type: "settings" }); await windowsCommands.windowNavigate({ type: "settings" }, "/app/settings?tab=templates"); - + const handleWindowFocus = () => { queryClient.invalidateQueries({ queryKey: ["templates"] }); queryClient.invalidateQueries({ queryKey: ["llm-connection"] }); window.removeEventListener("focus", handleWindowFocus); }; - + window.addEventListener("focus", handleWindowFocus); - } catch (error) { console.error("Failed to open settings/templates:", error); }