Skip to content

Commit a26e55a

Browse files
authored
Redemption settings hotfix (#1270)
* got rid of llm redemption * ran tests * chat slight updgrade * ran tests
1 parent 3fa3eb5 commit a26e55a

File tree

10 files changed

+224
-123
lines changed

10 files changed

+224
-123
lines changed

apps/desktop/src/components/editor-area/floating-button.tsx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
22
import { PlusIcon, RefreshCwIcon, TypeOutlineIcon, XIcon, ZapIcon } from "lucide-react";
33
import { useEffect, useRef, useState } from "react";
44

5-
import { useHypr } from "@/contexts";
65
import { useEnhancePendingState } from "@/hooks/enhance-pending";
7-
import { commands as analyticsCommands } from "@hypr/plugin-analytics";
86
import { commands as connectorCommands } from "@hypr/plugin-connector";
97
import { Session, Template } from "@hypr/plugin-db";
108
import { commands as windowsCommands } from "@hypr/plugin-windows";
@@ -62,7 +60,6 @@ export function FloatingButton({
6260
progress = 0,
6361
showProgress,
6462
}: FloatingButtonProps) {
65-
const { userId } = useHypr();
6663
const [showRaw, setShowRaw] = useSession(session.id, (s) => [
6764
s.showRaw,
6865
s.setShowRaw,
@@ -142,14 +139,6 @@ export function FloatingButton({
142139

143140
const handleTemplateSelect = (templateId: string) => {
144141
setShowTemplatePopover(false);
145-
146-
if (templateId !== "auto") {
147-
analyticsCommands.event({
148-
event: "custom_template_enhancement_started",
149-
distinct_id: userId,
150-
});
151-
}
152-
153142
handleEnhanceWithTemplate(templateId);
154143
};
155144

apps/desktop/src/components/editor-area/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ export function useEnhanceMutation({
353353

354354
const selectedTemplate = await TemplateService.getTemplate(effectiveTemplateId ?? "");
355355

356+
const eventName = selectedTemplate?.tags.includes("builtin")
357+
? "builtin_template_enhancement_started"
358+
: "custom_template_enhancement_started";
359+
analyticsCommands.event({
360+
event: eventName,
361+
distinct_id: userId,
362+
});
363+
356364
const shouldUseH1Headers = !effectiveTemplateId && h1Headers.length > 0;
357365
const grammarSections = selectedTemplate?.sections.map(s => s.title) || null;
358366

apps/desktop/src/components/right-panel/components/chat/message-content.tsx

Lines changed: 115 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { commands as miscCommands } from "@hypr/plugin-misc";
2+
import Renderer from "@hypr/tiptap/renderer";
3+
import { useEffect, useState } from "react";
14
import { MarkdownCard } from "./markdown-card";
25
import { Message } from "./types";
36

@@ -8,26 +11,127 @@ interface MessageContentProps {
811
onApplyMarkdown?: (markdownContent: string) => void;
912
}
1013

14+
function MarkdownText({ content }: { content: string }) {
15+
const [htmlContent, setHtmlContent] = useState<string>("");
16+
17+
useEffect(() => {
18+
const convertMarkdown = async () => {
19+
try {
20+
let html = await miscCommands.opinionatedMdToHtml(content);
21+
22+
// Clean up spacing (same as MarkdownCard)
23+
html = html
24+
.replace(/<p>\s*<\/p>/g, "")
25+
.replace(/<p>\u00A0<\/p>/g, "")
26+
.replace(/<p>&nbsp;<\/p>/g, "")
27+
.replace(/<p>\s+<\/p>/g, "")
28+
.replace(/<p> <\/p>/g, "")
29+
.trim();
30+
31+
setHtmlContent(html);
32+
} catch (error) {
33+
console.error("Failed to convert markdown:", error);
34+
setHtmlContent(content);
35+
}
36+
};
37+
38+
if (content.trim()) {
39+
convertMarkdown();
40+
}
41+
}, [content]);
42+
43+
return (
44+
<>
45+
<style>
46+
{`
47+
/* Styles for inline markdown text rendering */
48+
.markdown-text-container .tiptap-normal {
49+
font-size: 0.875rem !important;
50+
line-height: 1.5 !important;
51+
padding: 0 !important;
52+
color: rgb(38 38 38) !important; /* text-neutral-800 */
53+
user-select: text !important;
54+
-webkit-user-select: text !important;
55+
-moz-user-select: text !important;
56+
-ms-user-select: text !important;
57+
}
58+
59+
.markdown-text-container .tiptap-normal * {
60+
user-select: text !important;
61+
-webkit-user-select: text !important;
62+
-moz-user-select: text !important;
63+
-ms-user-select: text !important;
64+
}
65+
66+
.markdown-text-container .tiptap-normal p {
67+
margin: 0 0 8px 0 !important;
68+
}
69+
70+
.markdown-text-container .tiptap-normal p:last-child {
71+
margin-bottom: 0 !important;
72+
}
73+
74+
.markdown-text-container .tiptap-normal strong {
75+
font-weight: 600 !important;
76+
}
77+
78+
.markdown-text-container .tiptap-normal em {
79+
font-style: italic !important;
80+
}
81+
82+
.markdown-text-container .tiptap-normal a {
83+
color: rgb(59 130 246) !important; /* text-blue-500 */
84+
text-decoration: underline !important;
85+
}
86+
87+
.markdown-text-container .tiptap-normal code {
88+
background-color: rgb(245 245 245) !important; /* bg-neutral-100 */
89+
padding: 2px 4px !important;
90+
border-radius: 4px !important;
91+
font-family: ui-monospace, SFMono-Regular, Consolas, monospace !important;
92+
font-size: 0.8em !important;
93+
}
94+
95+
.markdown-text-container .tiptap-normal ul,
96+
.markdown-text-container .tiptap-normal ol {
97+
margin: 4px 0 !important;
98+
padding-left: 1.2rem !important;
99+
}
100+
101+
.markdown-text-container .tiptap-normal li {
102+
margin-bottom: 2px !important;
103+
}
104+
105+
/* Selection highlight */
106+
.markdown-text-container .tiptap-normal ::selection {
107+
background-color: #3b82f6 !important;
108+
color: white !important;
109+
}
110+
111+
.markdown-text-container .tiptap-normal ::-moz-selection {
112+
background-color: #3b82f6 !important;
113+
color: white !important;
114+
}
115+
`}
116+
</style>
117+
<div className="markdown-text-container select-text">
118+
<Renderer initialContent={htmlContent} />
119+
</div>
120+
</>
121+
);
122+
}
123+
11124
export function MessageContent({ message, sessionTitle, hasEnhancedNote, onApplyMarkdown }: MessageContentProps) {
12-
// If no parts are parsed, show regular content
13125
if (!message.parts || message.parts.length === 0) {
14-
return (
15-
<div className="whitespace-pre-wrap text-sm text-neutral-800 select-text">
16-
{message.content}
17-
</div>
18-
);
126+
return <MarkdownText content={message.content} />;
19127
}
20128

21129
return (
22130
<div className="space-y-1">
23131
{message.parts.map((part, index) => (
24132
<div key={index}>
25133
{part.type === "text"
26-
? (
27-
<div className="whitespace-pre-wrap text-sm text-neutral-800 select-text">
28-
{part.content}
29-
</div>
30-
)
134+
? <MarkdownText content={part.content} />
31135
: (
32136
<MarkdownCard
33137
content={part.content}

apps/desktop/src/components/right-panel/hooks/useChatLogic.ts

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { commands as connectorCommands } from "@hypr/plugin-connector";
77
import { commands as dbCommands } from "@hypr/plugin-db";
88
import { commands as miscCommands } from "@hypr/plugin-misc";
99
import { commands as templateCommands } from "@hypr/plugin-template";
10-
import { modelProvider, streamText } from "@hypr/utils/ai";
10+
import { modelProvider, streamText, tool } from "@hypr/utils/ai";
1111
import { useSessions } from "@hypr/utils/contexts";
12+
import { z } from "zod";
1213

1314
import type { ActiveEntityInfo, Message } from "../types/chat-types";
1415
import { parseMarkdownBlocks } from "../utils/markdown-parser";
@@ -26,6 +27,7 @@ interface UseChatLogicProps {
2627
getChatGroupId: () => Promise<string>;
2728
sessionData: any;
2829
chatInputRef: React.RefObject<HTMLTextAreaElement>;
30+
llmConnectionQuery: any;
2931
}
3032

3133
export function useChatLogic({
@@ -41,6 +43,7 @@ export function useChatLogic({
4143
getChatGroupId,
4244
sessionData,
4345
chatInputRef,
46+
llmConnectionQuery,
4447
}: UseChatLogicProps) {
4548
const [isGenerating, setIsGenerating] = useState(false);
4649
const sessions = useSessions((state) => state.sessions);
@@ -282,11 +285,13 @@ export function useChatLogic({
282285
content: userMessage.content.trim(),
283286
});
284287

288+
// Declare aiMessageId outside try block so it's accessible in catch
289+
const aiMessageId = (Date.now() + 1).toString();
290+
285291
try {
286292
const provider = await modelProvider();
287293
const model = provider.languageModel("defaultModel");
288294

289-
const aiMessageId = (Date.now() + 1).toString();
290295
const aiMessage: Message = {
291296
id: aiMessageId,
292297
content: "Generating...",
@@ -298,6 +303,17 @@ export function useChatLogic({
298303
const { textStream } = streamText({
299304
model,
300305
messages: await prepareMessageHistory(messages, content, mentionedContent),
306+
// Add tools conditionally for local LLM (same as enhance)
307+
...(llmConnectionQuery.data?.type === "HyprLocal" && {
308+
tools: {
309+
update_progress: tool({ inputSchema: z.any() }),
310+
},
311+
}),
312+
onError: (error) => {
313+
console.error("On Error Catch:", error);
314+
setIsGenerating(false);
315+
throw error;
316+
},
301317
});
302318

303319
let aiResponse = "";
@@ -332,23 +348,37 @@ export function useChatLogic({
332348
} catch (error) {
333349
console.error("AI error:", error);
334350

351+
const errorMessage = (error as any)?.error || "Unknown error";
352+
353+
let finalErrorMesage = "";
354+
355+
if (String(errorMessage).includes("too large")) {
356+
finalErrorMesage =
357+
"Sorry, I encountered an error. Please try again. Your transcript or meeting notes might be too large. Please try again with a smaller transcript or meeting notes."
358+
+ "\n\n" + errorMessage;
359+
} else {
360+
finalErrorMesage = "Sorry, I encountered an error. Please try again. " + "\n\n" + errorMessage;
361+
}
362+
335363
setIsGenerating(false);
336364

337-
const errorMessageId = (Date.now() + 1).toString();
338-
const aiMessage: Message = {
339-
id: errorMessageId,
340-
content: "Sorry, I encountered an error. Please try again.",
341-
isUser: false,
342-
timestamp: new Date(),
343-
};
344-
setMessages((prev) => [...prev, aiMessage]);
365+
setMessages((prev) =>
366+
prev.map(msg =>
367+
msg.id === aiMessageId
368+
? {
369+
...msg,
370+
content: finalErrorMesage,
371+
}
372+
: msg
373+
)
374+
);
345375

346376
await dbCommands.upsertChatMessage({
347-
id: errorMessageId,
377+
id: aiMessageId,
348378
group_id: groupId,
349379
created_at: new Date().toISOString(),
350380
role: "Assistant",
351-
content: "Sorry, I encountered an error. Please try again.",
381+
content: finalErrorMesage,
352382
});
353383
}
354384
};

apps/desktop/src/components/right-panel/views/chat-view.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { useQuery } from "@tanstack/react-query";
12
import { useNavigate } from "@tanstack/react-router";
23
import { useEffect, useRef, useState } from "react";
34

45
import { useHypr, useRightPanel } from "@/contexts";
6+
import { commands as connectorCommands } from "@hypr/plugin-connector";
57
import {
68
ChatHistoryView,
79
ChatInput,
@@ -39,6 +41,12 @@ export function ChatView() {
3941
setHasChatStarted,
4042
});
4143

44+
const llmConnectionQuery = useQuery({
45+
queryKey: ["llm-connection"],
46+
queryFn: () => connectorCommands.getLlmConnection(),
47+
refetchOnWindowFocus: true,
48+
});
49+
4250
const { chatGroupsQuery, sessionData, getChatGroupId } = useChatQueries({
4351
sessionId,
4452
userId,
@@ -68,6 +76,7 @@ export function ChatView() {
6876
getChatGroupId,
6977
sessionData,
7078
chatInputRef,
79+
llmConnectionQuery,
7180
});
7281

7382
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {

apps/desktop/src/components/settings/components/ai/stt-view.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ export function STTView({
410410
Lower value will cause model to output text more often, but may cause performance issues.
411411
</FormDescription>
412412
<FormControl>
413-
<div className="flex items-center gap-4">
413+
<div className="flex items-center justify-center gap-4">
414414
<Slider
415415
min={300}
416416
max={1200}
@@ -421,7 +421,7 @@ export function STTView({
421421
field.onChange(newValue);
422422
aiConfigMutation.mutate({ redemptionTimeMs: newValue });
423423
}}
424-
className="w-[60%]"
424+
className="w-[100%]"
425425
/>
426426
</div>
427427
</FormControl>

0 commit comments

Comments
 (0)