Skip to content

Commit 4632732

Browse files
Multi model backend support for Ollama, OpenAI, Gemini & Claude with human-like friendly chat abilities (#43) (#44)
* added multi-model switching logic for ollama * readme changes * fix: moved api key setting logic to python backend * feat: model selector in onboarding * feat: structured output support for cloud models * fix: added self.messages property * fix: updated selected model logic * fix: runnable model mapping logic updates (WIP) * fix: added default state to self.messages * fix: added self.system_prompt_template * fix: structured outputs in agents with cloud providers (WIP) * fix: working on agents fix * fix: elaborator response structure * fix: updated runnables with working logic (WIP) * feat: widget teaser - added reminder widget to show what widgets on home screen will look like chat page - added current model selected feature sidebar - revamped sidebar. started as an experiment, went in for a full revamp settings page - added API key management features - delete or add keys manually for your models fix: multiple bugfixes * fix: chat message icons * fix: resolved elaborator issue --------- Co-authored-by: Kabeer2004 <merchantkabeer68@gmail.com>
1 parent 83443c3 commit 4632732

27 files changed

Lines changed: 6009 additions & 2286 deletions

File tree

README.md

Lines changed: 146 additions & 113 deletions
Large diffs are not rendered by default.

src/interface/app/chat/page.js

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import IconGoogleCalendar from "@components/icons/IconGoogleCalendar" // Icon fo
2323
import IconGoogleSlides from "@components/icons/IconGoogleSlides" // Icon for Google Slides command
2424
import IconGoogleMail from "@components/icons/IconGoogleMail" // Icon for Google Mail command
2525
import IconGoogleDrive from "@components/icons/IconGoogleDrive" // Icon for Google Drive command
26+
import ReminderWidget from "@components/agents/Reminder"
2627

2728
/**
2829
* Chat component for the main chat interface.
@@ -59,6 +60,7 @@ const Chat = () => {
5960
const [showCommands, setShowCommands] = useState(false) // showCommands: boolean
6061
// State to hold the filtered slash commands based on user input.
6162
const [filteredCommands, setFilteredCommands] = useState([]) // filteredCommands: { text: string, value: string, icon: React.ReactNode }[]
63+
const [currentModel, setCurrentModel] = useState("")
6264

6365
/**
6466
* Array of available slash commands.
@@ -265,6 +267,21 @@ const Chat = () => {
265267
}
266268
}
267269

270+
const fetchCurrentModel = async () => {
271+
try {
272+
const response = await window.electron?.invoke("get-db-data")
273+
if (response.status === 200 && response.data) {
274+
const selectedModel = response.data.selectedModel
275+
setCurrentModel(selectedModel || "llama3.2:3b")
276+
} else {
277+
setCurrentModel("llama3.2:3b") // Fallback if no data
278+
}
279+
} catch (error) {
280+
toast.error("Error fetching user data.")
281+
setCurrentModel("llama3.2:3b") // Fallback on error
282+
}
283+
}
284+
268285
/**
269286
* Initializes the chat session with the backend for the given chatId.
270287
*/
@@ -310,6 +327,7 @@ const Chat = () => {
310327
*/
311328
useEffect(() => {
312329
fetchUserDetails()
330+
fetchCurrentModel()
313331
}, [])
314332

315333
/**
@@ -638,14 +656,18 @@ const Chat = () => {
638656
"absolute flex flex-col justify-center items-center w-full h-full"
639657
}
640658
/>
641-
<div className="w-3/5 flex flex-col font-Poppins justify-center items-center h-full bg-matteblack">
642-
<h1
643-
className="text-8xl text-white font-bold mb-8"
644-
style={{ zIndex: 10 }}
645-
>
646-
what&apos;s on your mind?
647-
</h1>
648-
<AiButton onClick={() => setShowCreateChatOverlay(true)} />
659+
<div className="w-3/5 flex flex-col font-Poppins items-center h-full relative">
660+
<div className="flex flex-col items-center justify-center flex-grow">
661+
<h1
662+
className="text-8xl text-white font-bold mb-8"
663+
style={{ zIndex: 10 }}
664+
>
665+
what's on your mind?
666+
</h1>
667+
<AiButton
668+
onClick={() => setShowCreateChatOverlay(true)}
669+
/>
670+
</div>
649671
{showCreateChatOverlay && (
650672
<ModalDialog
651673
title="Create a New Chat"
@@ -661,6 +683,15 @@ const Chat = () => {
661683
showInput={true}
662684
/>
663685
)}
686+
<div className="absolute bottom-16 left-0 right-0 flex flex-col items-center justify-center">
687+
<p className="text-white text-sm mb-5">
688+
Widgets are coming here soon! 👇
689+
</p>
690+
<div className="flex flex-row gap-8">
691+
<ReminderWidget />
692+
{/* Add more widgets here in the future, e.g., <AnotherWidget /> */}
693+
</div>
694+
</div>
664695
</div>
665696
</div>
666697
)
@@ -796,6 +827,14 @@ const Chat = () => {
796827

797828
<div ref={chatEndRef} />
798829
</div>
830+
<p className="text-gray-400 font-Poppins text-sm">
831+
You can change now your model from the{" "}
832+
<a href="/settings" className="underline">
833+
Settings
834+
</a>{" "}
835+
page! Current Model:{" "}
836+
<span className="text-lightblue">{currentModel}</span>
837+
</p>
799838
<div className="relative mb-5 flex flex-row gap-4 w-full px-4 py-1 bg-matteblack border-[1px] border-white rounded-lg z-30">
800839
<textarea
801840
ref={textareaRef}

src/interface/app/integrations/page.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ const AppIntegration = () => {
269269
<AppCard
270270
logo="/images/linkedin-logo.png" // LinkedIn logo image path
271271
name="LinkedIn" // App name - LinkedIn
272-
description="Connect your LinkedIn account to pull in your professional profile and enhance your experience." // Description for LinkedIn card
272+
description="Connect your LinkedIn account to add your professional information to Sentient's context." // Description for LinkedIn card
273273
onClick={() => {
274274
// OnClick handler for LinkedIn card
275275
if (!isConnecting && !connectedApps.LinkedIn) {
@@ -287,7 +287,7 @@ const AppIntegration = () => {
287287
<AppCard
288288
logo="/images/reddit-logo.png" // Reddit logo image path
289289
name="Reddit" // App name - Reddit
290-
description="Connect your Reddit account to analyze your subreddit activity and identify topics of interest." // Description for Reddit card
290+
description="Connect your Reddit account to let Sentient analyze your subreddit activity and identify topics of interest." // Description for Reddit card
291291
onClick={() => {
292292
// OnClick handler for Reddit card
293293
if (
@@ -319,7 +319,7 @@ const AppIntegration = () => {
319319
<AppCard
320320
logo="/images/twitter-logo.png" // Twitter logo image path
321321
name="Twitter" // App name - Twitter
322-
description="Connect your Twitter account to analyze your tweets and identify topics of interest." // Description for Twitter card
322+
description="Connect your Twitter account to let Sentient analyze your tweets and identify topics of interest." // Description for Twitter card
323323
onClick={() => {
324324
// OnClick handler for Twitter card
325325
if (
@@ -358,7 +358,7 @@ const AppIntegration = () => {
358358
</ShiningButton>
359359
<div
360360
data-tooltip-id="integrations" // Tooltip ID for integrations info
361-
data-tooltip-content="You can always connect or disconnect the apps from the settings page later" // Tooltip content
361+
data-tooltip-content="You can always connect or disconnect the apps from the Settings page later. All data stays local." // Tooltip content
362362
className="absolute top-4 right-4" // Positioning classes
363363
>
364364
<button className="text-gray-300 hover-button p-2 rounded-[50%] text-sm cursor-default">

src/interface/app/personality-test/page.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import AnimatedLogo from "@components/AnimatedLogo" // Component for displaying
99
import ShiningButton from "@components/ShiningButton" // Custom button component with a shining effect
1010
import AnimatedBeam from "@components/AnimatedBeam" // Component for animated beam effect
1111
import ShinyCard from "@components/ShinyCard" // Custom card component with a shiny effect
12+
import ModelSelection from "@components/ModelSelection"
1213
import toast from "react-hot-toast" // Library for displaying toast notifications
1314

1415
/**
@@ -169,6 +170,7 @@ const PersonalityTest = () => {
169170
const [isReferred, setIsReferred] = useState(null) // isReferred: boolean | null
170171
// State to store the referral code entered by the user.
171172
const [referralCode, setReferralCode] = useState("") // referralCode: string
173+
const [showModelSelection, setShowModelSelection] = useState(false)
172174

173175
/**
174176
* useEffect hook to fetch existing personality data on component mount.
@@ -415,17 +417,17 @@ const PersonalityTest = () => {
415417
const handleBasicInfoSubmit = async (basicInfo) => {
416418
try {
417419
const response = await window.electron?.invoke("set-db-data", {
418-
// Invoke electron to set data in database
419-
data: { personalInfo: basicInfo } // Data to set is the basicInfo object
420+
data: { personalInfo: basicInfo }
420421
})
421422

422423
if (response.status === 200) {
423-
setShowBasicInfoForm(false) // Hide BasicInfoForm on successful submission
424+
setShowBasicInfoForm(false)
425+
setShowModelSelection(true) // Show model selection after basic info
424426
} else {
425-
throw new Error("Error saving basic information") // Throw error if response status is not 200
427+
throw new Error("Error saving basic information")
426428
}
427429
} catch (error) {
428-
toast.error(`Error saving basic information: ${error}`) // Show error toast if any error occurs
430+
toast.error(`Error saving basic information: ${error}`)
429431
}
430432
}
431433

@@ -728,6 +730,19 @@ const PersonalityTest = () => {
728730
*
729731
* @returns {React.ReactNode} - The main UI for the PersonalityTest component.
730732
*/
733+
734+
if (showModelSelection) {
735+
return (
736+
<AnimatedBeam className={"w-screen h-screen"}>
737+
<div className="min-h-screen flex justify-center items-center">
738+
<ModelSelection
739+
onProceed={() => setShowModelSelection(false)}
740+
/>
741+
</div>
742+
</AnimatedBeam>
743+
)
744+
}
745+
731746
return (
732747
<AnimatedBeam className={"w-screen h-screen"}>
733748
<div className="relative overflow-hidden">

0 commit comments

Comments
 (0)