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
2 changes: 0 additions & 2 deletions apps/desktop/src/components/editor-area/floating-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ export function FloatingButton({
const handleTemplateSelect = (templateId: string) => {
setShowTemplatePopover(false);

queryClient.invalidateQueries({ queryKey: ["llm-connection"] });

if (templateId !== "auto") {
analyticsCommands.event({
event: "custom_template_enhancement_started",
Expand Down
33 changes: 21 additions & 12 deletions apps/desktop/src/components/editor-area/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ export function useEnhanceMutation({
}) {
const { userId, onboardingSessionId } = useHypr();
const [progress, setProgress] = useState(0);
const [actualIsLocalLlm, setActualIsLocalLlm] = useState(isLocalLlm);
const queryClient = useQueryClient();

const preMeetingText = extractTextFromHtml(preMeetingNote);
const rawText = extractTextFromHtml(rawContent);
Expand All @@ -316,7 +318,15 @@ export function useEnhanceMutation({
const enhance = useMutation({
mutationKey: ["enhance", sessionId],
mutationFn: async () => {
if (isLocalLlm) {
await queryClient.invalidateQueries({ queryKey: ["llm-connection"] });
await new Promise(resolve => setTimeout(resolve, 100));

const { type } = await connectorCommands.getLlmConnection();
const freshIsLocalLlm = type === "HyprLocal";

setActualIsLocalLlm(freshIsLocalLlm);

if (freshIsLocalLlm) {
Comment on lines +321 to +329
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Address hardcoded timeout and consider architectural improvements.

The hardcoded 100ms timeout is arbitrary and may not be sufficient for query invalidation to complete. Additionally, invalidating queries inside mutation functions is generally an anti-pattern that can lead to race conditions.

Consider refactoring to:

  1. Use a more deterministic approach than hardcoded timeouts
  2. Move query invalidation to onSuccess/onError callbacks
  3. Add error handling for the fresh LLM connection fetch
- await queryClient.invalidateQueries({ queryKey: ["llm-connection"] });
- await new Promise(resolve => setTimeout(resolve, 100));
- 
- const { type } = await connectorCommands.getLlmConnection();
- const freshIsLocalLlm = type === "HyprLocal";
- 
- setActualIsLocalLlm(freshIsLocalLlm);
+ try {
+   const { type } = await connectorCommands.getLlmConnection();
+   const freshIsLocalLlm = type === "HyprLocal";
+   setActualIsLocalLlm(freshIsLocalLlm);
+ } catch (error) {
+   console.error("Failed to fetch LLM connection:", error);
+   // Fallback to existing state
+ }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/desktop/src/components/editor-area/index.tsx around lines 321 to 329,
replace the hardcoded 100ms timeout after queryClient.invalidateQueries with a
more deterministic approach such as awaiting the query invalidation promise if
available or restructuring the logic to avoid relying on delays. Move the query
invalidation call out of the mutation function into appropriate onSuccess or
onError callbacks to prevent race conditions. Additionally, add error handling
around the call to connectorCommands.getLlmConnection to gracefully handle
failures and avoid unhandled exceptions.

setProgress(0);
}

Expand All @@ -334,12 +344,9 @@ export function useEnhanceMutation({
dismissible: true,
duration: 5000,
});

return;
}

const { type } = await connectorCommands.getLlmConnection();

const config = await dbCommands.getConfig();

let templateInfo = "";
Expand Down Expand Up @@ -399,8 +406,6 @@ Sections:`;
: provider.languageModel("defaultModel");

if (sessionId !== onboardingSessionId) {
const { type } = await connectorCommands.getLlmConnection();

analyticsCommands.event({
event: "normal_enhance_start",
distinct_id: userId,
Expand All @@ -412,7 +417,8 @@ Sections:`;
const { text, fullStream } = streamText({
abortSignal,
model,
...(isLocalLlm && {
// Use fresh value for tools
...(freshIsLocalLlm && {
tools: {
update_progress: tool({ parameters: z.any() }),
},
Expand All @@ -425,7 +431,8 @@ Sections:`;
markdownTransform(),
smoothStream({ delayInMs: 80, chunking: "line" }),
],
...(isLocalLlm && {
// Use fresh value for provider options
...(freshIsLocalLlm && {
providerOptions: {
[localProviderName]: {
metadata: customGrammar
Expand All @@ -446,7 +453,8 @@ Sections:`;
if (chunk.type === "text-delta") {
acc += chunk.textDelta;
}
if (chunk.type === "tool-call" && isLocalLlm) {
// Use fresh value for progress updates
if (chunk.type === "tool-call" && freshIsLocalLlm) {
const chunkProgress = chunk.args?.progress ?? 0;
setProgress(chunkProgress);
}
Expand All @@ -469,12 +477,13 @@ Sections:`;
});

persistSession();
if (isLocalLlm) {

if (actualIsLocalLlm) {
setProgress(0);
}
},
onError: (error) => {
if (isLocalLlm) {
if (actualIsLocalLlm) {
setProgress(0);
}
console.error(error);
Expand All @@ -485,7 +494,7 @@ Sections:`;
},
});

return { enhance, progress: isLocalLlm ? progress : undefined };
return { enhance, progress: actualIsLocalLlm ? progress : undefined };
}

function useGenerateTitleMutation({ sessionId }: { sessionId: string }) {
Expand Down