bring back tooltip each params setting

This commit is contained in:
Faisal Amir 2024-01-04 01:10:01 +07:00
parent e8934d0771
commit 49d5703ac3
8 changed files with 146 additions and 18 deletions

View File

@ -1,8 +1,16 @@
import React from 'react' import React from 'react'
import { Switch } from '@janhq/uikit' import {
Switch,
Tooltip,
TooltipArrow,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from '@janhq/uikit'
import { useAtomValue } from 'jotai' import { useAtomValue } from 'jotai'
import { InfoIcon } from 'lucide-react'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
@ -11,10 +19,11 @@ import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom'
type Props = { type Props = {
name: string name: string
title: string title: string
description: string
checked: boolean checked: boolean
} }
const Checkbox: React.FC<Props> = ({ name, title, checked }) => { const Checkbox: React.FC<Props> = ({ name, title, checked, description }) => {
const { updateModelParameter } = useUpdateModelParameters() const { updateModelParameter } = useUpdateModelParameters()
const threadId = useAtomValue(getActiveThreadIdAtom) const threadId = useAtomValue(getActiveThreadIdAtom)
@ -25,7 +34,22 @@ const Checkbox: React.FC<Props> = ({ name, title, checked }) => {
return ( return (
<div className="flex justify-between"> <div className="flex justify-between">
<p className="mb-2 text-sm font-semibold text-gray-600">{title}</p> <div className="mb-1 flex items-center gap-x-2">
<p className="text-sm font-semibold text-zinc-500 dark:text-gray-300">
{title}
</p>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon size={16} className="flex-shrink-0 dark:text-gray-500" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="max-w-[240px]">
<span>{description}</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
<Switch checked={checked} onCheckedChange={onCheckedChange} /> <Switch checked={checked} onCheckedChange={onCheckedChange} />
</div> </div>
) )

View File

@ -1,7 +1,16 @@
import { Textarea } from '@janhq/uikit' import {
Textarea,
Tooltip,
TooltipArrow,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from '@janhq/uikit'
import { useAtomValue } from 'jotai' import { useAtomValue } from 'jotai'
import { InfoIcon } from 'lucide-react'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom' import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom'
@ -9,6 +18,7 @@ import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom'
type Props = { type Props = {
title: string title: string
name: string name: string
description: string
placeholder: string placeholder: string
value: string value: string
} }
@ -17,6 +27,7 @@ const ModelConfigInput: React.FC<Props> = ({
title, title,
name, name,
value, value,
description,
placeholder, placeholder,
}) => { }) => {
const { updateModelParameter } = useUpdateModelParameters() const { updateModelParameter } = useUpdateModelParameters()
@ -30,7 +41,22 @@ const ModelConfigInput: React.FC<Props> = ({
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
<p className="mb-2 text-sm font-semibold text-gray-600">{title}</p> <div className="mb-2 flex items-center gap-x-2">
<p className="text-sm font-semibold text-zinc-500 dark:text-gray-300">
{title}
</p>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon size={16} className="flex-shrink-0 dark:text-gray-500" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="max-w-[240px]">
<span>{description}</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
<Textarea <Textarea
placeholder={placeholder} placeholder={placeholder}
onChange={onValueChanged} onChange={onValueChanged}

View File

@ -1,15 +1,33 @@
import React from 'react' import React from 'react'
import { Slider, Input } from '@janhq/uikit' import {
import { useAtomValue } from 'jotai' Slider,
Input,
Tooltip,
TooltipArrow,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from '@janhq/uikit'
import { useAtomValue, useSetAtom } from 'jotai'
import { InfoIcon } from 'lucide-react'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param'
import {
engineParamsUpdateAtom,
getActiveThreadIdAtom,
getActiveThreadModelParamsAtom,
} from '@/helpers/atoms/Thread.atom'
type Props = { type Props = {
name: string name: string
title: string title: string
description: string
min: number min: number
max: number max: number
step: number step: number
@ -22,19 +40,48 @@ const SliderRightPanel: React.FC<Props> = ({
min, min,
max, max,
step, step,
description,
value, value,
}) => { }) => {
const { updateModelParameter } = useUpdateModelParameters() const { updateModelParameter } = useUpdateModelParameters()
const threadId = useAtomValue(getActiveThreadIdAtom) const threadId = useAtomValue(getActiveThreadIdAtom)
const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom)
const modelSettingParams = toSettingParams(activeModelParams)
const engineParams = getConfigurationsData(modelSettingParams)
const setEngineParamsUpdate = useSetAtom(engineParamsUpdateAtom)
const onValueChanged = (e: number[]) => { const onValueChanged = (e: number[]) => {
if (!threadId) return if (!threadId) return
if (engineParams.some((x) => x.name.includes(name))) {
setEngineParamsUpdate(true)
} else {
setEngineParamsUpdate(false)
}
updateModelParameter(threadId, name, e[0]) updateModelParameter(threadId, name, e[0])
} }
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
<p className="mb-2 text-sm font-semibold text-gray-600">{title}</p> <div className="mb-3 flex items-center gap-x-2">
<p className="text-sm font-semibold text-zinc-500 dark:text-gray-300">
{title}
</p>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon size={16} className="flex-shrink-0 dark:text-gray-500" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="max-w-[240px]">
<span>{description}</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
<div className="flex items-center gap-x-4"> <div className="flex items-center gap-x-4">
<div className="relative w-full"> <div className="relative w-full">
<Slider <Slider

View File

@ -7,6 +7,8 @@ import {
} from '@janhq/core' } from '@janhq/core'
import { atom } from 'jotai' import { atom } from 'jotai'
export const engineParamsUpdateAtom = atom<boolean>(false)
/** /**
* Stores the current active thread id. * Stores the current active thread id.
*/ */

View File

@ -34,6 +34,7 @@ import {
} from '@/helpers/atoms/ChatMessage.atom' } from '@/helpers/atoms/ChatMessage.atom'
import { import {
activeThreadAtom, activeThreadAtom,
engineParamsUpdateAtom,
getActiveThreadModelParamsAtom, getActiveThreadModelParamsAtom,
threadStatesAtom, threadStatesAtom,
updateThreadAtom, updateThreadAtom,
@ -59,6 +60,8 @@ export default function useSendChatMessage() {
const updateThreadInitSuccess = useSetAtom(updateThreadInitSuccessAtom) const updateThreadInitSuccess = useSetAtom(updateThreadInitSuccessAtom)
const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom)
const engineParamsUpdate = useAtomValue(engineParamsUpdateAtom)
useEffect(() => { useEffect(() => {
modelRef.current = activeModel modelRef.current = activeModel
}, [activeModel]) }, [activeModel])
@ -135,8 +138,10 @@ export default function useSendChatMessage() {
console.error('No active thread') console.error('No active thread')
return return
} }
const activeThreadState = threadStates[activeThread.id]
console.log(engineParamsUpdate)
const activeThreadState = threadStates[activeThread.id]
const runtimeParams = toRuntimeParams(activeModelParams) const runtimeParams = toRuntimeParams(activeModelParams)
const settingParams = toSettingParams(activeModelParams) const settingParams = toSettingParams(activeModelParams)
@ -256,6 +261,7 @@ export default function useSendChatMessage() {
await WaitForModelStarting(modelId) await WaitForModelStarting(modelId)
setQueuedMessage(false) setQueuedMessage(false)
} }
events.emit(EventName.OnMessageSent, messageRequest) events.emit(EventName.OnMessageSent, messageRequest)
} }

View File

@ -21,6 +21,7 @@ export type InputData = {
export type SliderData = { export type SliderData = {
min: number min: number
max: number max: number
step: number step: number
value: number value: number
} }
@ -45,6 +46,7 @@ const settingComponentBuilder = (
<Slider <Slider
key={data.name} key={data.name}
title={data.title} title={data.title}
description={data.description}
min={min} min={min}
max={max} max={max}
step={step} step={step}
@ -60,6 +62,7 @@ const settingComponentBuilder = (
title={data.title} title={data.title}
key={data.name} key={data.name}
name={data.name} name={data.name}
description={data.description}
placeholder={placeholder} placeholder={placeholder}
value={textValue} value={textValue}
/> />
@ -70,6 +73,7 @@ const settingComponentBuilder = (
<Checkbox <Checkbox
key={data.name} key={data.name}
name={data.name} name={data.name}
description={data.description}
title={data.title} title={data.title}
checked={checked} checked={checked}
/> />

View File

@ -226,7 +226,7 @@ const Sidebar: React.FC = () => {
<div className="mt-6"> <div className="mt-6">
<CardSidebar title="Inference Parameters" asChild> <CardSidebar title="Inference Parameters" asChild>
<div className="p-2"> <div className="px-2 py-4">
<ModelSetting /> <ModelSetting />
</div> </div>
</CardSidebar> </CardSidebar>
@ -234,7 +234,7 @@ const Sidebar: React.FC = () => {
<div className="mt-4"> <div className="mt-4">
<CardSidebar title="Model Parameters" asChild> <CardSidebar title="Model Parameters" asChild>
<div className="p-2"> <div className="px-2 py-4">
{settingComponentBuilder(componentDataEngineSetting, true)} {settingComponentBuilder(componentDataEngineSetting, true)}
</div> </div>
</CardSidebar> </CardSidebar>
@ -247,7 +247,7 @@ const Sidebar: React.FC = () => {
onViewJsonClick={onViewJsonClick} onViewJsonClick={onViewJsonClick}
asChild asChild
> >
<div className="p-2"> <div className="px-2 py-4">
<EngineSetting /> <EngineSetting />
</div> </div>
</CardSidebar> </CardSidebar>

View File

@ -1,4 +1,11 @@
import { ChangeEvent, Fragment, KeyboardEvent, useEffect, useRef } from 'react' import {
ChangeEvent,
Fragment,
KeyboardEvent,
useEffect,
useRef,
useState,
} from 'react'
import { EventName, MessageStatus, events } from '@janhq/core' import { EventName, MessageStatus, events } from '@janhq/core'
import { Button, Textarea } from '@janhq/uikit' import { Button, Textarea } from '@janhq/uikit'
@ -51,7 +58,8 @@ const ChatScreen = () => {
const activeThreadState = useAtomValue(activeThreadStateAtom) const activeThreadState = useAtomValue(activeThreadStateAtom)
const { sendChatMessage, queuedMessage } = useSendChatMessage() const { sendChatMessage, queuedMessage } = useSendChatMessage()
const isWaitingForResponse = activeThreadState?.waitingForResponse ?? false const isWaitingForResponse = activeThreadState?.waitingForResponse ?? false
const disabled = currentPrompt.trim().length === 0 || isWaitingForResponse const isDisabledChatbox =
currentPrompt.trim().length === 0 || isWaitingForResponse
const activeThreadId = useAtomValue(getActiveThreadIdAtom) const activeThreadId = useAtomValue(getActiveThreadIdAtom)
const [isWaitingToSend, setIsWaitingToSend] = useAtom(waitingToSendMessage) const [isWaitingToSend, setIsWaitingToSend] = useAtom(waitingToSendMessage)
@ -147,13 +155,22 @@ const ChatScreen = () => {
<ModelStart /> <ModelStart />
{/* {reloadModel && (
<div className="mb-2 text-center">
<span className="text-muted-foreground">
Model is reloading to apply new changes.
</span>
</div>
)} */}
{queuedMessage && ( {queuedMessage && (
<div className="my-2 py-2 text-center"> <div className="mb-2 text-center">
<span className="rounded-lg border border-border px-4 py-2 shadow-lg"> <span className="text-muted-foreground">
Message queued. It can be sent once the model has started Message queued. It can be sent once the model has started
</span> </span>
</div> </div>
)} )}
<div className="mx-auto flex w-full flex-shrink-0 items-end justify-center space-x-4 px-8 py-4"> <div className="mx-auto flex w-full flex-shrink-0 items-end justify-center space-x-4 px-8 py-4">
<Textarea <Textarea
className="max-h-[400px] resize-none overflow-y-auto pr-20" className="max-h-[400px] resize-none overflow-y-auto pr-20"
@ -172,7 +189,9 @@ const ChatScreen = () => {
{messages[messages.length - 1]?.status !== MessageStatus.Pending ? ( {messages[messages.length - 1]?.status !== MessageStatus.Pending ? (
<Button <Button
size="lg" size="lg"
disabled={disabled || stateModel.loading || !activeThread} disabled={
isDisabledChatbox || stateModel.loading || !activeThread
}
themes="primary" themes="primary"
className="min-w-[100px]" className="min-w-[100px]"
onClick={sendChatMessage} onClick={sendChatMessage}