Merge branch 'main' into feat-1346

This commit is contained in:
Hieu 2024-01-11 16:34:49 +07:00 committed by GitHub
commit 54084f3c3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 120 additions and 47 deletions

View File

@ -1,3 +1,5 @@
GTM_ID=xxxx GTM_ID=xxxx
POSTHOG_PROJECT_API_KEY=xxxx POSTHOG_PROJECT_API_KEY=xxxx
POSTHOG_APP_URL=xxxx POSTHOG_APP_URL=xxxx
ALGOLIA_API_KEY=xxxx
ALGOLIA_APP_ID=xxxx

View File

@ -151,13 +151,13 @@ const config = {
autoCollapseCategories: false, autoCollapseCategories: false,
}, },
}, },
// Agolia DocSearch // Algolia Search Configuration
algolia: { algolia: {
appId: process.env.ALGOLIA_APP_ID || "XXX", appId: process.env.ALGOLIA_APP_ID || "XXX",
apiKey: process.env.ALGOLIA_API_KEY || "XXX", apiKey: process.env.ALGOLIA_API_KEY || "XXX",
indexName: "jan", indexName: "jan",
contextualSearch: false,
insights: true, insights: true,
debug: false,
}, },
// SEO Docusarus // SEO Docusarus
metadata: [ metadata: [

View File

@ -1,3 +1,8 @@
.DocCardList--no-description .card p { .DocCardList--no-description .card p {
display: none; display: none;
} }
/* For dark theme */
[data-theme="dark"] .DocSearch {
--docsearch-hit-active-color: #090a11; /* Keep the color unchanged */
}

View File

@ -6,6 +6,7 @@ const badgeVariants = cva('badge', {
variants: { variants: {
themes: { themes: {
primary: 'badge-primary', primary: 'badge-primary',
warning: 'badge-warning',
success: 'badge-success', success: 'badge-success',
secondary: 'badge-secondary', secondary: 'badge-secondary',
danger: 'badge-danger', danger: 'badge-danger',

View File

@ -21,6 +21,10 @@
@apply border-transparent bg-red-100 text-red-700; @apply border-transparent bg-red-100 text-red-700;
} }
&-warning {
@apply border-transparent bg-yellow-100 text-yellow-700;
}
&-outline { &-outline {
@apply text-foreground border-border border; @apply text-foreground border-border border;
} }

View File

@ -8,7 +8,7 @@
} }
&-secondary-blue { &-secondary-blue {
@apply bg-blue-200 text-blue-900 hover:bg-blue-500/80; @apply bg-blue-200 text-blue-600 hover:bg-blue-500/80;
} }
&-danger { &-danger {

View File

@ -16,7 +16,7 @@ import { useActiveModel } from '@/hooks/useActiveModel'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param' import { toSettingParams } from '@/utils/modelParam'
import { import {
engineParamsUpdateAtom, engineParamsUpdateAtom,

View File

@ -16,7 +16,7 @@ import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param' import { toSettingParams } from '@/utils/modelParam'
import { import {
engineParamsUpdateAtom, engineParamsUpdateAtom,

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { useState } from 'react'
import { import {
Slider, Slider,
@ -14,10 +14,12 @@ import { useAtomValue, useSetAtom } from 'jotai'
import { InfoIcon } from 'lucide-react' import { InfoIcon } from 'lucide-react'
import { useActiveModel } from '@/hooks/useActiveModel' import { useActiveModel } from '@/hooks/useActiveModel'
import { useClickOutside } from '@/hooks/useClickOutside'
import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param' import { toSettingParams } from '@/utils/modelParam'
import { import {
engineParamsUpdateAtom, engineParamsUpdateAtom,
@ -57,6 +59,10 @@ const SliderRightPanel: React.FC<Props> = ({
const { stopModel } = useActiveModel() const { stopModel } = useActiveModel()
const [showTooltip, setShowTooltip] = useState({ max: false, min: false })
useClickOutside(() => setShowTooltip({ max: false, min: false }), null, [])
const onValueChanged = (e: number[]) => { const onValueChanged = (e: number[]) => {
if (!threadId) return if (!threadId) return
if (engineParams.some((x) => x.name.includes(name))) { if (engineParams.some((x) => x.name.includes(name))) {
@ -97,25 +103,43 @@ const SliderRightPanel: React.FC<Props> = ({
/> />
<div className="relative mt-2 flex items-center justify-between text-gray-400"> <div className="relative mt-2 flex items-center justify-between text-gray-400">
<p className="text-sm">{min}</p> <p className="text-sm">{min}</p>
<p className="absolute left-1/2 -translate-x-1/2 text-sm">
{max / 2}
</p>
<p className="text-sm">{max}</p> <p className="text-sm">{max}</p>
</div> </div>
</div> </div>
<Tooltip open={showTooltip.max || showTooltip.min}>
<TooltipTrigger asChild>
<Input <Input
className="-mt-4 h-8 w-16" type="number"
className="-mt-4 h-8 w-20"
min={min} min={min}
max={max} max={max}
value={String(value)} value={String(value)}
onChange={(e) => { onChange={(e) => {
if (Number(e.target.value) >= max) { if (Number(e.target.value) > Number(max)) {
onValueChanged([Number(max)]) onValueChanged([Number(max)])
setShowTooltip({ max: true, min: false })
} else if (Number(e.target.value) < Number(min)) {
onValueChanged([Number(min)])
setShowTooltip({ max: false, min: true })
} else { } else {
onValueChanged([Number(e.target.value)]) onValueChanged([Number(e.target.value)])
setShowTooltip({ max: false, min: false })
} }
}} }}
/> />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent className="max-w-[240px]" side="top">
{showTooltip.max && (
<span>Automatically set to the maximum allowed tokens</span>
)}
{showTooltip.min && (
<span>Automatically set to the minimum allowed tokens</span>
)}
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div> </div>
</div> </div>
) )

View File

@ -23,7 +23,7 @@ import { currentPromptAtom } from '@/containers/Providers/Jotai'
import { toaster } from '@/containers/Toast' import { toaster } from '@/containers/Toast'
import { toRuntimeParams, toSettingParams } from '@/utils/model_param' import { toRuntimeParams, toSettingParams } from '@/utils/modelParam'
import { useActiveModel } from './useActiveModel' import { useActiveModel } from './useActiveModel'

View File

@ -8,7 +8,7 @@ import {
import { useAtomValue, useSetAtom } from 'jotai' import { useAtomValue, useSetAtom } from 'jotai'
import { toRuntimeParams, toSettingParams } from '@/utils/model_param' import { toRuntimeParams, toSettingParams } from '@/utils/modelParam'
import { extensionManager } from '@/extension' import { extensionManager } from '@/extension'
import { import {

View File

@ -4,7 +4,7 @@ import { useAtomValue } from 'jotai'
import { selectedModelAtom } from '@/containers/DropdownListSidebar' import { selectedModelAtom } from '@/containers/DropdownListSidebar'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/model_param' import { toSettingParams } from '@/utils/modelParam'
import settingComponentBuilder from '../ModelSetting/settingComponentBuilder' import settingComponentBuilder from '../ModelSetting/settingComponentBuilder'
@ -18,7 +18,7 @@ const EngineSetting = () => {
const modelSettingParams = toSettingParams(activeModelParams) const modelSettingParams = toSettingParams(activeModelParams)
const componentData = getConfigurationsData(modelSettingParams) const componentData = getConfigurationsData(modelSettingParams, selectedModel)
componentData.sort((a, b) => a.title.localeCompare(b.title)) componentData.sort((a, b) => a.title.localeCompare(b.title))

View File

@ -6,7 +6,7 @@ import { useAtomValue } from 'jotai'
import { selectedModelAtom } from '@/containers/DropdownListSidebar' import { selectedModelAtom } from '@/containers/DropdownListSidebar'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toRuntimeParams } from '@/utils/model_param' import { toRuntimeParams } from '@/utils/modelParam'
import settingComponentBuilder from './settingComponentBuilder' import settingComponentBuilder from './settingComponentBuilder'
@ -20,9 +20,10 @@ const ModelSetting = () => {
const modelRuntimeParams = toRuntimeParams(activeModelParams) const modelRuntimeParams = toRuntimeParams(activeModelParams)
const componentData = getConfigurationsData(modelRuntimeParams) const componentData = getConfigurationsData(
modelRuntimeParams,
componentData.sort((a, b) => a.title.localeCompare(b.title)) selectedModel
).toSorted((a, b) => a.title.localeCompare(b.title))
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">

View File

@ -32,7 +32,7 @@ export const presetConfiguration: Record<string, SettingComponentData> = {
min: 0, min: 0,
max: 4096, max: 4096,
step: 128, step: 128,
value: 1024, value: 4096,
}, },
}, },
max_tokens: { max_tokens: {
@ -42,10 +42,10 @@ export const presetConfiguration: Record<string, SettingComponentData> = {
'The maximum number of tokens the model will generate in a single response.', 'The maximum number of tokens the model will generate in a single response.',
controllerType: 'slider', controllerType: 'slider',
controllerData: { controllerData: {
min: 128, min: 100,
max: 4096, max: 4096,
step: 128, step: 10,
value: 2048, value: 4096,
}, },
}, },
ngl: { ngl: {

View File

@ -1,7 +1,7 @@
/* eslint-disable no-case-declarations */ /* eslint-disable no-case-declarations */
import Checkbox from '@/containers/Checkbox' import Checkbox from '@/containers/Checkbox'
import ModelConfigInput from '@/containers/ModelConfigInput' import ModelConfigInput from '@/containers/ModelConfigInput'
import Slider from '@/containers/Slider' import SliderRightPanel from '@/containers/SliderRightPanel'
export type ControllerType = 'slider' | 'checkbox' | 'input' export type ControllerType = 'slider' | 'checkbox' | 'input'
@ -43,7 +43,7 @@ const settingComponentBuilder = (
case 'slider': case 'slider':
const { min, max, step, value } = data.controllerData as SliderData const { min, max, step, value } = data.controllerData as SliderData
return ( return (
<Slider <SliderRightPanel
key={data.name} key={data.name}
title={data.title} title={data.title}
description={data.description} description={data.description}

View File

@ -19,7 +19,7 @@ import DropdownListSidebar, {
import { useCreateNewThread } from '@/hooks/useCreateNewThread' import { useCreateNewThread } from '@/hooks/useCreateNewThread'
import { getConfigurationsData } from '@/utils/componentSettings' import { getConfigurationsData } from '@/utils/componentSettings'
import { toRuntimeParams, toSettingParams } from '@/utils/model_param' import { toRuntimeParams, toSettingParams } from '@/utils/modelParam'
import EngineSetting from '../EngineSetting' import EngineSetting from '../EngineSetting'
import ModelSetting from '../ModelSetting' import ModelSetting from '../ModelSetting'

View File

@ -71,7 +71,7 @@ const ExploreModelItemHeader: React.FC<Props> = ({ model, onClick, open }) => {
if (isDownloaded) { if (isDownloaded) {
downloadButton = ( downloadButton = (
<Button <Button
themes="success" themes="secondaryBlue"
className="min-w-[98px]" className="min-w-[98px]"
onClick={onUseModelClick} onClick={onUseModelClick}
> >
@ -92,21 +92,21 @@ const ExploreModelItemHeader: React.FC<Props> = ({ model, onClick, open }) => {
if (minimumRamModel > totalRam) { if (minimumRamModel > totalRam) {
return ( return (
<Badge className="rounded-md bg-red-500 text-white"> <Badge className="rounded-md" themes="danger">
Not enough RAM Not enough RAM
</Badge> </Badge>
) )
} }
if (minimumRamModel < availableRam) { if (minimumRamModel < availableRam) {
return ( return (
<Badge className="rounded-md bg-green-500 text-white"> <Badge className="rounded-md" themes="success">
Recommended Recommended
</Badge> </Badge>
) )
} }
if (minimumRamModel < totalRam && minimumRamModel > availableRam) { if (minimumRamModel < totalRam && minimumRamModel > availableRam) {
return ( return (
<Badge className="rounded-md bg-yellow-500 text-white"> <Badge className="rounded-md" themes="warning">
Slow on your device Slow on your device
</Badge> </Badge>
) )

View File

@ -31,4 +31,14 @@
[type='submit'] { [type='submit'] {
background-color: inherit; background-color: inherit;
} }
input[type='number'] {
-moz-appearance: textfield;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
} }

View File

@ -1,4 +1,4 @@
import { ModelRuntimeParams, ModelSettingParams } from '@janhq/core' import { Model, ModelRuntimeParams, ModelSettingParams } from '@janhq/core'
import { presetConfiguration } from '@/screens/Chat/ModelSetting/predefinedComponent' import { presetConfiguration } from '@/screens/Chat/ModelSetting/predefinedComponent'
@ -7,9 +7,16 @@ import { SettingComponentData } from '@/screens/Chat/ModelSetting/settingCompone
import { ModelParams } from '@/helpers/atoms/Thread.atom' import { ModelParams } from '@/helpers/atoms/Thread.atom'
export const getConfigurationsData = ( export const getConfigurationsData = (
settings: ModelSettingParams | ModelRuntimeParams settings: ModelSettingParams | ModelRuntimeParams,
selectedModel?: Model
) => { ) => {
const componentData: SettingComponentData[] = [] const componentData: SettingComponentData[] = []
const defaultValue = (value?: number) => {
if (value && value < 4096) return value
return 4096
}
Object.keys(settings).forEach((key: string) => { Object.keys(settings).forEach((key: string) => {
const componentSetting = presetConfiguration[key] const componentSetting = presetConfiguration[key]
@ -18,8 +25,27 @@ export const getConfigurationsData = (
} }
if ('slider' === componentSetting.controllerType) { if ('slider' === componentSetting.controllerType) {
const value = Number(settings[key as keyof ModelParams]) const value = Number(settings[key as keyof ModelParams])
if ('value' in componentSetting.controllerData) if ('value' in componentSetting.controllerData) {
componentSetting.controllerData.value = value componentSetting.controllerData.value = value
if ('max' in componentSetting.controllerData) {
switch (key) {
case 'max_tokens':
componentSetting.controllerData.max =
selectedModel?.parameters.max_tokens || 4096
componentSetting.controllerData.value = defaultValue(
selectedModel?.parameters.max_tokens
)
break
case 'ctx_len':
componentSetting.controllerData.max =
selectedModel?.settings.ctx_len || 4096
componentSetting.controllerData.value = defaultValue(
selectedModel?.settings.ctx_len
)
break
}
}
}
} else if ('input' === componentSetting.controllerType) { } else if ('input' === componentSetting.controllerType) {
const value = settings[key as keyof ModelParams] as string const value = settings[key as keyof ModelParams] as string
const placeholder = settings[key as keyof ModelParams] as string const placeholder = settings[key as keyof ModelParams] as string