/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useContext } from 'react' import { FieldValues, useForm } from 'react-hook-form' import { getUserSpace, openFileExplorer, joinPath } from '@janhq/core' import { Input, Textarea, Form, Button, FormField, FormItem, FormControl, } from '@janhq/uikit' import { atom, useAtomValue } from 'jotai' import { twMerge } from 'tailwind-merge' import LogoMark from '@/containers/Brand/Logo/Mark' import CardSidebar from '@/containers/CardSidebar' import DropdownListSidebar, { selectedModelAtom, } from '@/containers/DropdownListSidebar' import { useCreateNewThread } from '@/hooks/useCreateNewThread' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import { getConfigurationsData } from '@/utils/componentSettings' import { toSettingParams } from '@/utils/model_param' import EngineSetting from '../EngineSetting' import ModelSetting from '../ModelSetting' import settingComponentBuilder from '../ModelSetting/settingComponentBuilder' import { activeThreadAtom, getActiveThreadIdAtom, getActiveThreadModelParamsAtom, threadStatesAtom, } from '@/helpers/atoms/Thread.atom' export const showRightSideBarAtom = atom(true) const Sidebar: React.FC = () => { const showing = useAtomValue(showRightSideBarAtom) const activeThread = useAtomValue(activeThreadAtom) const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) const selectedModel = useAtomValue(selectedModelAtom) const { updateThreadMetadata } = useCreateNewThread() const { updateModelParameter } = useUpdateModelParameters() const threadStates = useAtomValue(threadStatesAtom) const threadId = useAtomValue(getActiveThreadIdAtom) const modelEngineParams = toSettingParams(activeModelParams) const componentDataEngineSetting = getConfigurationsData(modelEngineParams) const onReviewInFinderClick = async (type: string) => { if (!activeThread) return const activeThreadState = threadStates[activeThread.id] if (!activeThreadState.isFinishInit) { alert('Thread is not started yet') return } const userSpace = await getUserSpace() let filePath = undefined const assistantId = activeThread.assistants[0]?.assistant_id switch (type) { case 'Engine': case 'Thread': filePath = await joinPath(['threads', activeThread.id]) break case 'Model': if (!selectedModel) return filePath = await joinPath(['models', selectedModel.id]) break case 'Assistant': if (!assistantId) return filePath = await joinPath(['assistants', assistantId]) break default: break } if (!filePath) return const fullPath = await joinPath([userSpace, filePath]) openFileExplorer(fullPath) } const onViewJsonClick = async (type: string) => { if (!activeThread) return const activeThreadState = threadStates[activeThread.id] if (!activeThreadState.isFinishInit) { alert('Thread is not started yet') return } const userSpace = await getUserSpace() let filePath = undefined const assistantId = activeThread.assistants[0]?.assistant_id switch (type) { case 'Engine': case 'Thread': filePath = await joinPath(['threads', activeThread.id, 'thread.json']) break case 'Model': if (!selectedModel) return filePath = await joinPath(['models', selectedModel.id, 'model.json']) break case 'Assistant': if (!assistantId) return filePath = await joinPath(['assistants', assistantId, 'assistant.json']) break default: break } if (!filePath) return const fullPath = await joinPath([userSpace, filePath]) openFileExplorer(fullPath) } const form = useForm() const filterChangedFormFields = ( allFields: T, dirtyFields: Partial> ): Partial => { const changedFieldValues = Object.keys(dirtyFields).reduce( (acc, currentField) => { const isDirty = Array.isArray(dirtyFields[currentField]) ? (dirtyFields[currentField] as boolean[]).some((value) => { value === true }) : dirtyFields[currentField] === true if (isDirty) { return { ...acc, [currentField]: allFields[currentField], } } return acc }, {} as Partial ) return changedFieldValues } const onSubmit = async (values: any) => { if (!threadId) return if (!activeThread) return if (Object.keys(form.formState.dirtyFields).length) { if ( Object.keys(form.formState.dirtyFields).includes('title') || Object.keys(form.formState.dirtyFields).includes('instructions') ) { updateThreadMetadata({ ...activeThread, title: values.title || activeThread.title, assistants: [ { ...activeThread.assistants[0], instructions: values.instructions || activeThread?.assistants[0].instructions, }, ], }) } updateModelParameter( threadId, filterChangedFormFields(values, form.formState.dirtyFields) ) form.reset() } } return (
( <> field.onChange(e)} value={field.value} /> )} />
{activeThread?.id || '-'}
{activeThread?.assistants[0].assistant_name ?? '-'}
( <>