Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@
"rust-analyzer.cargo.targetDir": "target/analyzer",
"rust-analyzer.cargo.extraEnv": {
"MACOSX_DEPLOYMENT_TARGET": "14.2"
},
"[typescriptreact]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}
21 changes: 21 additions & 0 deletions apps/desktop/src/components/editor-area/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,30 @@ import { toast } from "@hypr/ui/components/ui/toast";
import { cn } from "@hypr/ui/lib/utils";
import { generateText, localProviderName, modelProvider, smoothStream, streamText, tool } from "@hypr/utils/ai";
import { useOngoingSession, useSession, useSessions } from "@hypr/utils/contexts";
import { load } from "@tauri-apps/plugin-store";
import { enhanceFailedToast } from "../toast/shared";
import { AnnotationBox } from "./annotation-box";
import { FloatingButton } from "./floating-button";
import { NoteHeader } from "./note-header";
import { TextSelectionPopover } from "./text-selection-popover";

const getUserContext = async (): Promise<{ value: string } | null> => {
try {
const store = await load("store.json", { autoSave: false })
const val = await store.get("user_context")
if (val && typeof val === "object" && "value" in val) {
return val as { value: string }
}
return null
} catch (error) {
console.error("Failed to fetch user context", error)
return null
}
}




async function generateTitleDirect(
enhancedContent: string,
targetSessionId: string,
Expand Down Expand Up @@ -448,11 +466,14 @@ export function useEnhanceMutation({

let customInstruction = selectedTemplate?.description;

let userContext = await getUserContext() || "";
Copy link

Choose a reason for hiding this comment

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

getUserContext returns an object but the code passes the whole object instead of its value string

Prompt for AI agents
Address the following comment on apps/desktop/src/components/editor-area/index.tsx at line 469:

<comment>getUserContext returns an object but the code passes the whole object instead of its `value` string</comment>

<file context>
@@ -448,11 +466,14 @@ export function useEnhanceMutation({
 
       let customInstruction = selectedTemplate?.description;
 
+      let userContext = await getUserContext() || &quot;&quot;;
+
       const systemMessage = await templateCommands.render(
</file context>
Suggested change
let userContext = await getUserContext() || "";
let userContext = (await getUserContext())?.value ?? "";


const systemMessage = await templateCommands.render(
"enhance.system",
{
config,
type,
userContext,
// Pass userHeaders when using H1 headers, templateInfo otherwise
...(shouldUseH1Headers
? { userHeaders: h1Headers }
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/components/settings/components/tab-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
MessageSquareIcon,
SettingsIcon,
SparklesIcon,
UserIcon,
} from "lucide-react";

import { type Tab } from "./types";
Expand Down Expand Up @@ -56,6 +57,8 @@ export function TabIcon({ tab }: { tab: Tab }) {
return <CreditCardIcon className="h-4 w-4" />;
case "mcp":
return <McpIcon className="h-4 w-4" />;
case "user-context":
return <UserIcon className="h-4 w-4" />;
default:
return null;
}
Expand Down
5 changes: 4 additions & 1 deletion apps/desktop/src/components/settings/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
NetworkIcon,
Settings,
Sparkles,
User,
Volume2,
} from "lucide-react";

Expand All @@ -23,7 +24,8 @@ export type Tab =
| "feedback"
| "integrations"
| "mcp"
| "billing";
| "billing"
| "user-context";

export const TABS: { name: Tab; icon: LucideIcon }[] = [
{ name: "general", icon: Settings },
Expand All @@ -37,4 +39,5 @@ export const TABS: { name: Tab; icon: LucideIcon }[] = [
{ name: "mcp", icon: NetworkIcon },
{ name: "billing", icon: CreditCard },
{ name: "feedback", icon: BlocksIcon },
{ name: "user-context", icon: User },
];
90 changes: 90 additions & 0 deletions apps/desktop/src/components/settings/views/user-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Button } from "@hypr/ui/components/ui/button";
import { Textarea } from "@hypr/ui/components/ui/textarea";
import { toast } from "@hypr/ui/components/ui/toast";
import { load } from "@tauri-apps/plugin-store";
import React, { useEffect, useRef, useState } from "react";

export default function UserContext() {
const [isLoading, setIsLoading] = useState(false);
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const [userContext, setUserContext] = useState<{ value: string } | null>(null);

const showUserContextToast = (content: string) => {
toast({
id: "user-context",
title: "User Context",
content: content,
dismissible: true,
});
};

const getStore = async () => {
return await load("store.json", { autoSave: false });
};

const getUserContext = async (): Promise<{ value: string } | null> => {
let store = await getStore();
let userContext = await store.get("user_context");

return userContext as { value: string } | null;
};

const handleSave = async () => {
try {
setIsLoading(true);
let store = await getStore();

if (!store) {
showUserContextToast("Failed to retrieve user store");
setIsLoading(false);
return;
}

if (!textAreaRef?.current?.value) {
showUserContextToast("Failed to save user context");
setIsLoading(false);
return;
}

store.set("user_context", { value: textAreaRef?.current?.value });
await store.save();
showUserContextToast("User context saved successfully");
setIsLoading(false);
} catch (error) {
setIsLoading(false);
console.log("Failed to save user context with error ", error);
}
};

useEffect(() => {
getUserContext().then((val) => {
setUserContext(val);
}).catch((e) => {
console.log(e);
});
}, []);

return (
<div className="flex-1 ">
<div className="mb-2">
<p className="text-black ">User Context</p>
</div>
<Textarea
className="h-full"
ref={textAreaRef}
placeholder={`${userContext?.value || "Enter details about yourself"}`}
>
</Textarea>

<div className="mt-2 flex flex-row w-full justify-center">
<Button
isLoading={isLoading}
className="w-3/4"
onClick={handleSave}
>
<span className="text-white">Save</span>
</Button>
</div>
</div>
);
}
4 changes: 4 additions & 0 deletions apps/desktop/src/routes/app.settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
Sound,
TemplatesView,
} from "@/components/settings/views";
import UserContext from "@/components/settings/views/user-context";
import { cn } from "@hypr/ui/lib/utils";

const schema = z.object({
Expand Down Expand Up @@ -71,6 +72,8 @@ function Component() {
return t`License`;
case "mcp":
return t`MCP`;
case "user-context":
return t`User Context`;
default:
return tab;
}
Expand Down Expand Up @@ -140,6 +143,7 @@ function Component() {
{search.tab === "integrations" && <Integrations />}
{search.tab === "mcp" && <MCP />}
{search.tab === "billing" && <Billing />}
{search.tab === "user-context" && <UserContext />}
</div>
</div>
</div>
Expand Down
7 changes: 7 additions & 0 deletions crates/template/assets/enhance.system.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ You will be given multiple inputs from the user. Below are useful information th
- The beginning of a raw note may include agenda items, discussion topics, and preliminary questions.
- Primarily consist of key phrases or sentences the user wants to remember, though they may also contain random or extraneous words.
- May sometimes be empty.
- User Context (txt)

The User Context contains important background details about the user, such as their role, company, ongoing projects, style/tone preferences, and domain terminology.
You must always take this into account when generating enhanced notes to make them more relevant and personalized.

Here is the User Context:
{{ userContext}}

# Enhanced Note Format

Expand Down