Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: RAG enhancements #1965

Merged
merged 7 commits into from
Feb 8, 2024
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: 1 addition & 1 deletion uikit/src/input/styles.scss
Original file line number Diff line number Diff line change
@@ -1,6 1,6 @@
.input {
@apply border-border placeholder:text-muted-foreground flex h-9 w-full rounded-lg border bg-transparent px-3 py-1 transition-colors;
@apply disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600;
@apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600;
@apply focus-within:outline-none focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1;
@apply file:border-0 file:bg-transparent file:font-medium;
}
2 changes: 1 addition & 1 deletion uikit/src/select/styles.scss
Original file line number Diff line number Diff line change
@@ -1,6 1,6 @@
.select {
@apply placeholder:text-muted-foreground border-border flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm disabled:cursor-not-allowed [&>span]:line-clamp-1;
@apply disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600;
@apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600;
@apply focus-within:outline-none focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1;

&-caret {
Expand Down
5 changes: 4 additions & 1 deletion web/containers/CardSidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 156,10 @@ export default function CardSidebar({
</>
) : (
<>
Opens <span className="lowercase">{title}.json.</span>
Opens{' '}
<span className="lowercase">
{title === 'Tools' ? 'assistant' : title}.json.
</span>
&nbsp;Changes affect all new threads.
</>
)}
Expand Down
16 changes: 14 additions & 2 deletions web/hooks/useCreateNewThread.ts
Original file line number Diff line number Diff line change
@@ -1,3 1,5 @@
import { useContext } from 'react'

import {
Assistant,
ConversationalExtension,
Expand All @@ -6,13 8,15 @@ import {
ThreadAssistantInfo,
ThreadState,
Model,
MessageStatus,
AssistantTool,
} from '@janhq/core'
import { atom, useAtomValue, useSetAtom } from 'jotai'

import { selectedModelAtom } from '@/containers/DropdownListSidebar'
import { fileUploadAtom } from '@/containers/Providers/Jotai'

import { FeatureToggleContext } from '@/context/FeatureToggle'

import { generateThreadId } from '@/utils/thread'

import useRecommendedModel from './useRecommendedModel'
Expand Down Expand Up @@ -54,6 58,7 @@ export const useCreateNewThread = () => {
const setSelectedModel = useSetAtom(selectedModelAtom)
const setThreadModelParams = useSetAtom(setThreadModelParamsAtom)
const messages = useAtomValue(getCurrentChatMessagesAtom)
const { experimentalFeature } = useContext(FeatureToggleContext)

const { recommendedModel, downloadedModels } = useRecommendedModel()

Expand All @@ -72,11 77,18 @@ export const useCreateNewThread = () => {
return null
}

// modify assistant tools when experimental on, retieval toggle enabled in default
const assistantTools: AssistantTool = {
type: 'retrieval',
enabled: true,
settings: assistant.tools && assistant.tools[0].settings,
}

const createdAt = Date.now()
const assistantInfo: ThreadAssistantInfo = {
assistant_id: assistant.id,
assistant_name: assistant.name,
tools: assistant.tools,
tools: experimentalFeature ? [assistantTools] : assistant.tools,
model: {
id: defaultModel?.id ?? '*',
settings: defaultModel?.settings ?? {},
Expand Down
2 changes: 2 additions & 0 deletions web/hooks/usePath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 25,7 @@ export const usePath = () => {
if (!selectedModel) return
filePath = await joinPath(['models', selectedModel.id])
break
case 'Tools':
case 'Assistant':
if (!assistantId) return
filePath = await joinPath(['assistants', assistantId])
Expand Down Expand Up @@ -59,6 60,7 @@ export const usePath = () => {
filePath = await joinPath(['models', selectedModel.id, 'model.json'])
break
case 'Assistant':
case 'Tools':
if (!assistantId) return
filePath = await joinPath(['assistants', assistantId, 'assistant.json'])
break
Expand Down
2 changes: 0 additions & 2 deletions web/screens/Chat/ChatInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 112,12 @@ const ChatInput: React.FC = () => {
const file = event.target.files?.[0]
if (!file) return
setFileUpload([{ file: file, type: 'pdf' }])
setCurrentPrompt('Summarize this for me')
}

const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]
if (!file) return
setFileUpload([{ file: file, type: 'image' }])
setCurrentPrompt('What do you see in this image?')
}

const renderPreview = (fileUpload: any) => {
Expand Down
237 changes: 172 additions & 65 deletions web/screens/Chat/Sidebar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 1,20 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useContext } from 'react'

import { InferenceEngine } from '@janhq/core'
import { Input, Textarea, Switch } from '@janhq/uikit'
import {
Input,
Textarea,
Switch,
Tooltip,
TooltipArrow,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from '@janhq/uikit'

import { atom, useAtomValue } from 'jotai'

import { InfoIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge'

import LogoMark from '@/containers/Brand/Logo/Mark'
Expand Down Expand Up @@ -134,76 143,174 @@ const Sidebar: React.FC = () => {
}}
/>
</div>
{experimentalFeature && (
<div>
{activeThread?.assistants[0]?.tools &&
componentDataAssistantSetting.length > 0 && (
<div className="mt-2">
<CardSidebar
title="Retrieval"
asChild
rightAction={
<Switch
name="retrieval"
className="mr-2"
checked={
activeThread?.assistants[0].tools[0].enabled
}
onCheckedChange={(e) => {
if (activeThread)
updateThreadMetadata({
...activeThread,
assistants: [
{
...activeThread.assistants[0],
tools: [
{
type: 'retrieval',
enabled: e,
settings:
(activeThread.assistants[0].tools &&
activeThread.assistants[0]
.tools[0]?.settings) ??
{},
},
],
},
],
})
}}
/>
}
>
{activeThread?.assistants[0]?.tools[0].enabled && (
<div className="px-2 py-4">
<div className="mb-4">
</div>
</CardSidebar>

{experimentalFeature && (
<div>
{activeThread?.assistants[0]?.tools &&
componentDataAssistantSetting.length > 0 && (
<div className="mt-2">
<CardSidebar title="Tools">
<div className="px-2 pt-4">
<div className="mb-2">
<div className="flex items-center justify-between">
<label
id="retrieval"
className="inline-flex items-center font-bold text-zinc-500 dark:text-gray-300"
>
Retrieval
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon
size={16}
className="ml-2 flex-shrink-0 text-black dark:text-gray-500"
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
side="top"
className="max-w-[240px]"
>
<span>
Retrieval helps the assistant use
information from files you send to it. Once
you share a file, the assistant
automatically fetches the relevant content
based on your request.
</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</label>

<div className="flex items-center justify-between">
<Switch
name="retrieval"
className="mr-2"
checked={
activeThread?.assistants[0].tools[0].enabled
}
onCheckedChange={(e) => {
if (activeThread)
updateThreadMetadata({
...activeThread,
assistants: [
{
...activeThread.assistants[0],
tools: [
{
type: 'retrieval',
enabled: e,
settings:
(activeThread.assistants[0]
.tools &&
activeThread.assistants[0]
.tools[0]?.settings) ??
{},
},
],
},
],
})
}}
/>
</div>
</div>
</div>
{activeThread?.assistants[0]?.tools[0].enabled && (
<div className="pb-4 pt-2">
<div className="mb-4">
<div className="item-center mb-2 flex">
<label
id="tool-title"
className="mb-2 inline-block font-bold text-zinc-500 dark:text-gray-300"
id="embedding-model"
className="inline-flex font-bold text-zinc-500 dark:text-gray-300"
>
Embedding Engine
Embedding Model
</label>
<div className="flex items-center justify-between">
<label className="font-medium text-zinc-500 dark:text-gray-300">
{selectedModel?.engine ===
InferenceEngine.openai
? 'OpenAI'
: 'Nitro'}
</label>
</div>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon
size={16}
className="ml-2 flex-shrink-0 dark:text-gray-500"
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
side="top"
className="max-w-[240px]"
>
<span>
Embedding model is crucial for
understanding and processing the input
text effectively by converting text to
numerical representations. Align the model
choice with your task, evaluate its
performance, and consider factors like
resource availability. Experiment to find
the best fit for your specific use case.
</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>

<div className="flex items-center justify-between">
<Input value={selectedModel?.name} disabled />
</div>
<AssistantSetting
componentData={componentDataAssistantSetting}
/>
</div>
)}
</CardSidebar>
<div className="mb-4">
<div className="mb-2 flex items-center">
<label
id="vector-database"
className="inline-block font-bold text-zinc-500 dark:text-gray-300"
>
Vector Database
</label>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon
size={16}
className="ml-2 flex-shrink-0 dark:text-gray-500"
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
side="top"
className="max-w-[240px]"
>
<span>
Vector Database is crucial for efficient
storage and retrieval of embeddings.
Consider your specific task, available
resources, and language requirements.
Experiment to find the best fit for your
specific use case.
</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>

<div className="flex items-center justify-between">
<Input value="HNSWLib" disabled />
</div>
</div>
<AssistantSetting
componentData={componentDataAssistantSetting}
/>
</div>
)}
</div>
)}
</div>
)}
</CardSidebar>
</div>
)}
</div>
</CardSidebar>
)}

<CardSidebar title="Model">
<div className="px-2 pt-4">
<DropdownListSidebar />
Expand Down
5 changes: 0 additions & 5 deletions web/screens/Chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 54,7 @@
}

const ChatScreen: React.FC = () => {
const setCurrentPrompt = useSetAtom(currentPromptAtom)

Check warning on line 57 in web/screens/Chat/index.tsx

View workflow job for this annotation

GitHub Actions / test-on-ubuntu

'setCurrentPrompt' is assigned a value but never used

Check warning on line 57 in web/screens/Chat/index.tsx

View workflow job for this annotation

GitHub Actions / test-on-macos

'setCurrentPrompt' is assigned a value but never used

Check warning on line 57 in web/screens/Chat/index.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows (mcafee)

'setCurrentPrompt' is assigned a value but never used

Check warning on line 57 in web/screens/Chat/index.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows (default-windows-security)

'setCurrentPrompt' is assigned a value but never used

Check warning on line 57 in web/screens/Chat/index.tsx

View workflow job for this annotation

GitHub Actions / test-on-windows (bit-defender)

'setCurrentPrompt' is assigned a value but never used
const activeThread = useAtomValue(activeThreadAtom)
const showLeftSideBar = useAtomValue(showLeftSideBarAtom)
const engineParamsUpdate = useAtomValue(engineParamsUpdateAtom)
Expand Down Expand Up @@ -110,11 110,6 @@
const imageType = files[0]?.type.includes('image')
setFileUpload([{ file: files[0], type: imageType ? 'image' : 'pdf' }])
setDragOver(false)
if (imageType) {
setCurrentPrompt('What do you see in this image?')
} else {
setCurrentPrompt('Summarize this for me')
}
},
onDropRejected: (e) => {
if (
Expand Down
Loading