feat: enable copy over instructions (#3266)
This commit is contained in:
parent
3bebdfe67e
commit
2074511067
@ -7,6 +7,8 @@ import { useAtomValue, useSetAtom } from 'jotai'
|
|||||||
import useAssistantQuery from '@/hooks/useAssistantQuery'
|
import useAssistantQuery from '@/hooks/useAssistantQuery'
|
||||||
import useThreads from '@/hooks/useThreads'
|
import useThreads from '@/hooks/useThreads'
|
||||||
|
|
||||||
|
import { copyOverInstructionEnabledAtom } from '@/screens/Settings/Advanced/components/CopyOverInstruction'
|
||||||
|
|
||||||
import { toaster } from '../Toast'
|
import { toaster } from '../Toast'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -17,12 +19,18 @@ import {
|
|||||||
} from '@/helpers/atoms/App.atom'
|
} from '@/helpers/atoms/App.atom'
|
||||||
import { getSelectedModelAtom } from '@/helpers/atoms/Model.atom'
|
import { getSelectedModelAtom } from '@/helpers/atoms/Model.atom'
|
||||||
|
|
||||||
|
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const KeyListener: React.FC = () => {
|
const KeyListener: React.FC = () => {
|
||||||
const setShowLeftPanel = useSetAtom(showLeftPanelAtom)
|
const setShowLeftPanel = useSetAtom(showLeftPanelAtom)
|
||||||
const setShowRightPanel = useSetAtom(showRightPanelAtom)
|
const setShowRightPanel = useSetAtom(showRightPanelAtom)
|
||||||
const setMainViewState = useSetAtom(mainViewStateAtom)
|
const setMainViewState = useSetAtom(mainViewStateAtom)
|
||||||
const { createThread } = useThreads()
|
const { createThread } = useThreads()
|
||||||
|
|
||||||
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
|
const copyOverInstructionEnabled = useAtomValue(
|
||||||
|
copyOverInstructionEnabledAtom
|
||||||
|
)
|
||||||
const { data: assistants } = useAssistantQuery()
|
const { data: assistants } = useAssistantQuery()
|
||||||
|
|
||||||
const selectedModel = useAtomValue(getSelectedModelAtom)
|
const selectedModel = useAtomValue(getSelectedModelAtom)
|
||||||
@ -46,9 +54,21 @@ const KeyListener: React.FC = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
createThread(selectedModel.model, assistants[0])
|
if (!selectedModel) return
|
||||||
|
let instructions: string | undefined = undefined
|
||||||
|
if (copyOverInstructionEnabled) {
|
||||||
|
instructions = activeThread?.assistants[0]?.instructions ?? undefined
|
||||||
|
}
|
||||||
|
createThread(selectedModel.model, assistants[0], instructions)
|
||||||
setMainViewState(MainViewState.Thread)
|
setMainViewState(MainViewState.Thread)
|
||||||
}, [selectedModel, createThread, assistants, setMainViewState])
|
}, [
|
||||||
|
createThread,
|
||||||
|
setMainViewState,
|
||||||
|
selectedModel,
|
||||||
|
assistants,
|
||||||
|
activeThread,
|
||||||
|
copyOverInstructionEnabled,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
|||||||
@ -49,8 +49,11 @@ const useThreads = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const createNewThread = useCallback(
|
const createNewThread = useCallback(
|
||||||
async (modelId: string, assistant: Assistant) => {
|
async (modelId: string, assistant: Assistant, instructions?: string) => {
|
||||||
assistant.model = modelId
|
assistant.model = modelId
|
||||||
|
if (instructions) {
|
||||||
|
assistant.instructions = instructions
|
||||||
|
}
|
||||||
const thread = await createThread(assistant)
|
const thread = await createThread(assistant)
|
||||||
log.info('Create new thread result', thread)
|
log.info('Create new thread result', thread)
|
||||||
setThreads((threads) => [thread, ...threads])
|
setThreads((threads) => [thread, ...threads])
|
||||||
|
|||||||
@ -40,7 +40,6 @@
|
|||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-scroll-to-bottom": "^4.2.0",
|
|
||||||
"sass": "^1.69.4",
|
"sass": "^1.69.4",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"tailwindcss": "3.3.5",
|
"tailwindcss": "3.3.5",
|
||||||
@ -51,7 +50,6 @@
|
|||||||
"@types/node": "20.8.10",
|
"@types/node": "20.8.10",
|
||||||
"@types/react": "18.2.34",
|
"@types/react": "18.2.34",
|
||||||
"@types/react-dom": "18.2.14",
|
"@types/react-dom": "18.2.14",
|
||||||
"@types/react-scroll-to-bottom": "^4.2.4",
|
|
||||||
"@types/uuid": "^9.0.6",
|
"@types/uuid": "^9.0.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
||||||
"@typescript-eslint/parser": "^6.8.0",
|
"@typescript-eslint/parser": "^6.8.0",
|
||||||
|
|||||||
@ -0,0 +1,41 @@
|
|||||||
|
import { ChangeEvent, useCallback } from 'react'
|
||||||
|
|
||||||
|
import { Switch } from '@janhq/joi'
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
import { atomWithStorage } from 'jotai/utils'
|
||||||
|
|
||||||
|
const COPY_OVER_INSTRUCTION_ENABLED = 'copy_over_instruction_enabled'
|
||||||
|
export const copyOverInstructionEnabledAtom = atomWithStorage(
|
||||||
|
COPY_OVER_INSTRUCTION_ENABLED,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
const CopyOverInstructionItem: React.FC = () => {
|
||||||
|
const [copyOverInstructionEnabled, setCopyOverInstructionEnabled] = useAtom(
|
||||||
|
copyOverInstructionEnabledAtom
|
||||||
|
)
|
||||||
|
|
||||||
|
const onSwitchToggled = useCallback(
|
||||||
|
(e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setCopyOverInstructionEnabled(e.target.checked)
|
||||||
|
},
|
||||||
|
[setCopyOverInstructionEnabled]
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
||||||
|
<div className="flex-shrink-0 space-y-1">
|
||||||
|
<div className="flex gap-x-2">
|
||||||
|
<h6 className="font-semibold capitalize">Copy Over Instruction</h6>
|
||||||
|
</div>
|
||||||
|
<p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
|
||||||
|
Enable instruction to be copied to new thread
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/**/}
|
||||||
|
<Switch checked={copyOverInstructionEnabled} onChange={onSwitchToggled} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CopyOverInstructionItem
|
||||||
@ -13,7 +13,9 @@ import { toaster } from '@/containers/Toast'
|
|||||||
import useModelStop from '@/hooks/useModelStop'
|
import useModelStop from '@/hooks/useModelStop'
|
||||||
import { useSettings } from '@/hooks/useSettings'
|
import { useSettings } from '@/hooks/useSettings'
|
||||||
|
|
||||||
import DataMigration from './FactoryReset/components/DataMigration'
|
import CopyOverInstructionItem from './components/CopyOverInstruction'
|
||||||
|
|
||||||
|
import DataMigration from './components/DataMigration'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
experimentalFeatureEnabledAtom,
|
experimentalFeatureEnabledAtom,
|
||||||
@ -26,12 +28,6 @@ import {
|
|||||||
|
|
||||||
import { activeModelsAtom } from '@/helpers/atoms/Model.atom'
|
import { activeModelsAtom } from '@/helpers/atoms/Model.atom'
|
||||||
|
|
||||||
// type GPU = {
|
|
||||||
// id: string
|
|
||||||
// vram: number | null
|
|
||||||
// name: string
|
|
||||||
// }
|
|
||||||
|
|
||||||
const Advanced = () => {
|
const Advanced = () => {
|
||||||
const [experimentalEnabled, setExperimentalEnabled] = useAtom(
|
const [experimentalEnabled, setExperimentalEnabled] = useAtom(
|
||||||
experimentalFeatureEnabledAtom
|
experimentalFeatureEnabledAtom
|
||||||
@ -462,6 +458,7 @@ const Advanced = () => {
|
|||||||
|
|
||||||
{/* Factory Reset */}
|
{/* Factory Reset */}
|
||||||
{/* <FactoryReset /> */}
|
{/* <FactoryReset /> */}
|
||||||
|
{experimentalEnabled && <CopyOverInstructionItem />}
|
||||||
{experimentalEnabled && <DataMigration />}
|
{experimentalEnabled && <DataMigration />}
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import useAssistantQuery from '@/hooks/useAssistantQuery'
|
|||||||
|
|
||||||
import useThreads from '@/hooks/useThreads'
|
import useThreads from '@/hooks/useThreads'
|
||||||
|
|
||||||
|
import { copyOverInstructionEnabledAtom } from '@/screens/Settings/Advanced/components/CopyOverInstruction'
|
||||||
|
|
||||||
import ThreadItem from './ThreadItem'
|
import ThreadItem from './ThreadItem'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -22,7 +24,7 @@ import {
|
|||||||
getSelectedModelAtom,
|
getSelectedModelAtom,
|
||||||
} from '@/helpers/atoms/Model.atom'
|
} from '@/helpers/atoms/Model.atom'
|
||||||
import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom'
|
import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import { getActiveThreadIdAtom, threadsAtom } from '@/helpers/atoms/Thread.atom'
|
import { activeThreadAtom, threadsAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const ThreadLeftPanel: React.FC = () => {
|
const ThreadLeftPanel: React.FC = () => {
|
||||||
const { createThread, setActiveThread } = useThreads()
|
const { createThread, setActiveThread } = useThreads()
|
||||||
@ -30,11 +32,13 @@ const ThreadLeftPanel: React.FC = () => {
|
|||||||
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
||||||
const selectedModel = useAtomValue(getSelectedModelAtom)
|
const selectedModel = useAtomValue(getSelectedModelAtom)
|
||||||
const threads = useAtomValue(threadsAtom)
|
const threads = useAtomValue(threadsAtom)
|
||||||
const activeThreadId = useAtomValue(getActiveThreadIdAtom)
|
|
||||||
|
|
||||||
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
const { data: assistants } = useAssistantQuery()
|
const { data: assistants } = useAssistantQuery()
|
||||||
|
|
||||||
const isCreatingThread = useRef(false)
|
const isCreatingThread = useRef(false)
|
||||||
|
const copyOverInstructionEnabled = useAtomValue(
|
||||||
|
copyOverInstructionEnabledAtom
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if user does not have any threads, we should create one
|
// if user does not have any threads, we should create one
|
||||||
@ -52,13 +56,10 @@ const ThreadLeftPanel: React.FC = () => {
|
|||||||
}, [threads, assistants, downloadedModels, createThread])
|
}, [threads, assistants, downloadedModels, createThread])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const setActiveThreadIfNone = () => {
|
if (activeThread?.id) return
|
||||||
if (activeThreadId) return
|
if (threads.length === 0) return
|
||||||
if (threads.length === 0) return
|
setActiveThread(threads[0].id)
|
||||||
setActiveThread(threads[0].id)
|
}, [activeThread?.id, setActiveThread, threads])
|
||||||
}
|
|
||||||
setActiveThreadIfNone()
|
|
||||||
}, [activeThreadId, setActiveThread, threads])
|
|
||||||
|
|
||||||
const onCreateThreadClicked = useCallback(async () => {
|
const onCreateThreadClicked = useCallback(async () => {
|
||||||
if (!assistants || assistants.length === 0) {
|
if (!assistants || assistants.length === 0) {
|
||||||
@ -70,8 +71,18 @@ const ThreadLeftPanel: React.FC = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!selectedModel) return
|
if (!selectedModel) return
|
||||||
createThread(selectedModel.model, assistants[0])
|
let instructions: string | undefined = undefined
|
||||||
}, [createThread, selectedModel, assistants])
|
if (copyOverInstructionEnabled) {
|
||||||
|
instructions = activeThread?.assistants[0]?.instructions ?? undefined
|
||||||
|
}
|
||||||
|
createThread(selectedModel.model, assistants[0], instructions)
|
||||||
|
}, [
|
||||||
|
createThread,
|
||||||
|
selectedModel,
|
||||||
|
assistants,
|
||||||
|
activeThread,
|
||||||
|
copyOverInstructionEnabled,
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LeftPanelContainer>
|
<LeftPanelContainer>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user