hiro 28e4405498
feat: support RAG
chore: Update new model.json with multiple binaries

feat: Add updates for handling multiple model binaries

chore: jan can see

Update Model.json (#1005)

* add(mixtral): add model.json for mixtral

* archived some models + update the model.json

* add(model): add pandora 10.7b

* fix(model): update description

* fix(model): pump vers and change the featured model to trinity

* fix(model): archive neuralchat

* fix(model): decapriated all old models

* fix(trinity): add cover image and change description

* fix(trinity): update cover png

* add(pandora): cover image

* fix(pandora): cover image

* add(mixtral): add model.json for mixtral

* archived some models + update the model.json

* add(model): add pandora 10.7b

* fix(model): update description

* fix(model): pump vers and change the featured model to trinity

* fix(model): archive neuralchat

* fix(model): decapriated all old models

* fix(trinity): add cover image and change description

* fix(trinity): update cover png

* add(pandora): cover image

* fix(pandora): cover image

* chore: model desc nits

* fix(models): adjust the size for solars and pandoras

* add(mixtral): description

---------

Co-authored-by: 0xSage <n@pragmatic.vc>

chore: reformat model.json and use new template

fix(Model): download/abort model (#1163)

* fix(Model): download/abort model
* fix: image preview

Signed-off-by: James <james@jan.ai>

---------

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
Co-authored-by: Louis <louis@jan.ai>

add preview and reduce time re-render all chat screen

Signed-off-by: James <james@jan.ai>

store files under thread_id/files

Signed-off-by: James <james@jan.ai>

fix: Update llava 1.5 size

fix: Nitro extension path resolver

feat: Add upload preview clearance

chore: Update FileType to multiple targets

fix: delete file preview once new thread created

chore: Add langchain import

support storing pdf file

Signed-off-by: James <james@jan.ai>

feat: add retrieval tool in node runtime

fix: import module done

Co-authored-by: Louis <louis-jan@users.noreply.github.com>

feat: Add type assistant tool

chore: Add tool_retrieval_enabled to InferenceEngine

chore: Add AssistantTool to thread entity

chore: refactor tool retrieval base class

feat: Add handler for assistant with rag enabled

chore: Update inferenceEngine type properly

chore: Update inferenceEngine type properly

fix: Update retrieval tool

chore: main entry correction

refactor: tsconfig files

chore: Update ModelRuntimeParams type

refactor: Remove unused files

fix: wip

chore: remove unused console.log for FileUploadPreview

fix: Update mapping correctly for engine and proxyEngine

feat: Add proxyEngine to type ModelInfo

fix: WIP with test route

fix: Add bundleDependencies to package.json

chore: remove conversational history memory

fix: refactor data passing

reafactor: remove unused code

fix: Update module

chore: export import correction

fix conflict

Signed-off-by: James <james@jan.ai>

fix: resolve after rebased

fix: Update llava 1.5 model json

feat: Add bakllava 1 model json

refactor: node module export, ES syntax and langchain import

fix: WIP

fix: WIP

fix: WIP

fix: external module import

fix: WIP

Add UI attachment fot file upload

Prepare Thumbnail UI image

chore: rebase model folder to dev branch

chore: remove multiple binaries related commits

fix: remove multiple binaries related commits part 2

fix: Remove transformer.js related deps

Fix truncate file name attachment

remove unused code image preview attachment

fix: remove multi binaries error

chore: remove commented code for ModelArtifacts type

Dropzone for drag and drop attachment

Avoid conditional showing 0 using length

fix symbol windows

avoid undefined tools

fix: add tool retrieval to true by default and disable the change

chore: remove unused code

fix: Enable nitro embedding by default

fix: Update code WIP with nitro embedding

chore: remove unused running function

fix: assistant extension missing module

feat: Retrieval ingest, query and reforward

fix: Update hnswlib version conflict

fix: Add tool settings

fix: Update path to thread_id/memory

fix: Add support for nitro embedding usage

fix: RAG does not work with plain content message

fix(Model): #1662 imported model does not use gpu (#1723)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>

feat: allow users to update retrieval settings

chore: pass thread assistant settings to assistant extensions

chore: eslint fix

fix bug border right panel showing in thread while not have active thread

Update setting layout retrieval assistant

Renaming file settingcomponent

change default value in core extention

add fake loader generate response

fix conditional fake loader

remove unused import

Proper error message on file typr

fix: loading indicator

fix: chunk size and overlap constraint

conditional drag and drop when retrieval off

fix: enable retrieval middleware as soon as its tool is enabled

fix: configure embedding engine according to request

fix: Retrieval false by default

fix: engine json

chore: migrate assistant

disabled collapse panel when retrieval or children null

chore: remove unused log

chore: Bump nitro version to 0.2.14 for batch embedding

chore: remove unused console.log
2024-01-26 23:12:28 +07:00

390 lines
14 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import React, { useEffect, useState } from 'react'
import ScrollToBottom from 'react-scroll-to-bottom'
import {
Button,
Switch,
Tooltip,
TooltipArrow,
TooltipContent,
TooltipPortal,
TooltipTrigger,
Select,
SelectContent,
SelectItem,
Input,
SelectTrigger,
SelectValue,
} from '@janhq/uikit'
import { atom, useAtom, useAtomValue } from 'jotai'
import { Paintbrush, CodeIcon } from 'lucide-react'
import { ExternalLinkIcon, InfoIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import CardSidebar from '@/containers/CardSidebar'
import DropdownListSidebar, {
selectedModelAtom,
} from '@/containers/DropdownListSidebar'
import { useActiveModel } from '@/hooks/useActiveModel'
import { useServerLog } from '@/hooks/useServerLog'
import { getConfigurationsData } from '@/utils/componentSettings'
import { toSettingParams } from '@/utils/modelParam'
import EngineSetting from '../Chat/EngineSetting'
import SettingComponentBuilder from '../Chat/ModelSetting/SettingComponent'
import { showRightSideBarAtom } from '../Chat/Sidebar'
import Logs from './Logs'
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
import { getActiveThreadModelParamsAtom } from '@/helpers/atoms/Thread.atom'
const corsEnabledAtom = atom(true)
const verboseEnabledAtom = atom(true)
const hostAtom = atom('127.0.0.1')
const portAtom = atom('1337')
const LocalServerScreen = () => {
const [errorRangePort, setErrorRangePort] = useState(false)
const [serverEnabled, setServerEnabled] = useAtom(serverEnabledAtom)
const showing = useAtomValue(showRightSideBarAtom)
const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom)
const modelEngineParams = toSettingParams(activeModelParams)
const componentDataEngineSetting = getConfigurationsData(modelEngineParams)
const { openServerLog, clearServerLog } = useServerLog()
const { startModel, stateModel } = useActiveModel()
const [selectedModel] = useAtom(selectedModelAtom)
const [isCorsEnabled, setIsCorsEnabled] = useAtom(corsEnabledAtom)
const [isVerboseEnabled, setIsVerboseEnabled] = useAtom(verboseEnabledAtom)
const [host, setHost] = useAtom(hostAtom)
const [port, setPort] = useAtom(portAtom)
const FIRST_TIME_VISIT_API_SERVER = 'firstTimeVisitAPIServer'
const [firstTimeVisitAPIServer, setFirstTimeVisitAPIServer] =
useState<boolean>(false)
const handleChangePort = (value: any) => {
if (Number(value) <= 0 || Number(value) >= 65536) {
setErrorRangePort(true)
} else {
setErrorRangePort(false)
}
setPort(value)
}
useEffect(() => {
if (
localStorage.getItem(FIRST_TIME_VISIT_API_SERVER) === null ||
localStorage.getItem(FIRST_TIME_VISIT_API_SERVER) === 'true'
) {
localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'true')
setFirstTimeVisitAPIServer(true)
}
}, [firstTimeVisitAPIServer])
useEffect(() => {
handleChangePort(port)
}, [])
return (
<div className="flex h-full w-full">
{/* Left SideBar */}
<div className="flex h-full w-60 flex-shrink-0 flex-col overflow-y-auto border-r border-border">
<div className="p-4">
<h2 className="font-bold">Server Options</h2>
<p className="mt-2 leading-relaxed">
Start an OpenAI-compatible local HTTP server.
</p>
</div>
<div className="border-b border-border pb-8">
<div className="space-y-3 px-4">
<Button
block
themes={serverEnabled ? 'danger' : 'primary'}
disabled={stateModel.loading || errorRangePort}
onClick={() => {
if (serverEnabled) {
window.core?.api?.stopServer()
setServerEnabled(false)
} else {
startModel(String(selectedModel?.id))
window.core?.api?.startServer({
host,
port,
isCorsEnabled,
isVerboseEnabled,
})
setServerEnabled(true)
if (firstTimeVisitAPIServer) {
localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'false')
setFirstTimeVisitAPIServer(false)
}
}
}}
>
{serverEnabled ? 'Stop' : 'Start'} Server
</Button>
{serverEnabled && (
<Button block themes="secondaryBlue" asChild>
<a href={`http://localhost:${port}`} target="_blank">
API Reference <ExternalLinkIcon size={20} className="ml-2" />
</a>
</Button>
)}
</div>
</div>
<Tooltip>
<TooltipTrigger asChild>
<div className="space-y-4 p-4">
<div>
<p className="mb-2 block text-sm font-semibold text-zinc-500 dark:text-gray-300">
Server Options
</p>
<div className="flex w-full flex-shrink-0 items-center gap-x-2">
<Select
value={host}
onValueChange={(e) => setHost(e)}
disabled={serverEnabled}
>
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="127.0.0.1">127.0.0.1</SelectItem>
<SelectItem value="0.0.0.0">0.0.0.0</SelectItem>
</SelectContent>
</Select>
<Input
className={twMerge(
'w-[70px] flex-shrink-0',
errorRangePort && 'border-danger'
)}
value={port}
onChange={(e) => {
handleChangePort(e.target.value)
}}
maxLength={5}
disabled={serverEnabled}
/>
</div>
{errorRangePort && (
<p className="mt-2 text-xs text-danger">{`The port range should be from 0 to 65536`}</p>
)}
</div>
<div>
<label
id="cors"
className="mb-2 inline-flex items-start gap-x-2 font-bold text-zinc-500 dark:text-gray-300"
>
Cross-Origin-Resource-Sharing (CORS)
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon
size={16}
className="mt-0.5 flex-shrink-0 dark:text-gray-500"
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="max-w-[240px]">
<span>
CORS (Cross-Origin Resource Sharing) manages resource
access on this server from external domains. Enable
for secure inter-website communication, regulating
data sharing to bolster overall security.
</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</label>
<div className="flex items-center justify-between">
<Switch
checked={isCorsEnabled}
onCheckedChange={(e) => setIsCorsEnabled(e)}
name="cors"
disabled={serverEnabled}
/>
</div>
</div>
<div>
<label
id="verbose"
className="mb-2 inline-flex items-start gap-x-2 font-bold text-zinc-500 dark:text-gray-300"
>
Verbose Server Logs
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon
size={16}
className="mt-0.5 flex-shrink-0 dark:text-gray-500"
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="max-w-[240px]">
<span>
Verbose Server Logs provide extensive details about
server activities. Enable to capture thorough records,
aiding in troubleshooting and monitoring server
performance effectively.
</span>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</label>
<div className="flex items-center justify-between">
<Switch
checked={isVerboseEnabled}
onCheckedChange={(e) => setIsVerboseEnabled(e)}
name="verbose"
disabled={serverEnabled}
/>
</div>
</div>
</div>
</TooltipTrigger>
<TooltipPortal>
{serverEnabled && (
<TooltipContent side="bottom" className="max-w-[200px]">
<span>
Settings cannot be modified while the server is running
</span>
<TooltipArrow />
</TooltipContent>
)}
</TooltipPortal>
</Tooltip>
</div>
{/* Middle Bar */}
<ScrollToBottom className="relative flex h-full w-full flex-col overflow-auto bg-background">
<div className="sticky top-0 flex items-center justify-between bg-zinc-100 px-4 py-2 dark:bg-secondary/30">
<h2 className="font-bold">Server Logs</h2>
<div className="space-x-2">
<Button
size="sm"
themes="outline"
className="bg-white dark:bg-secondary"
onClick={() => openServerLog()}
>
<CodeIcon size={16} className="mr-2" />
Open Logs
</Button>
<Button
size="sm"
themes="outline"
className="bg-white dark:bg-secondary"
onClick={() => clearServerLog()}
>
<Paintbrush size={16} className="mr-2" />
Clear
</Button>
</div>
</div>
{firstTimeVisitAPIServer ? (
<div className="flex h-full items-center justify-center">
<div className="w-[335px] rounded-lg border border-blue-600 bg-blue-100 p-6">
<div className="item-start flex gap-x-4">
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
className="mt-1 flex-shrink-0"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10 20C15.5228 20 20 15.5228 20 10C20 4.47715 15.5228 0 10 0C4.47715 0 2.11188e-08 4.47715 2.11188e-08 10C2.11188e-08 12.397 0.843343 14.597 2.2495 16.3195L0.292453 18.2929C-0.332289 18.9229 0.110179 20 0.993697 20H10ZM5.5 8C5.5 7.44772 5.94772 7 6.5 7H13.5C14.0523 7 14.5 7.44772 14.5 8C14.5 8.55229 14.0523 9 13.5 9H6.5C5.94772 9 5.5 8.55229 5.5 8ZM6.5 11C5.94772 11 5.5 11.4477 5.5 12C5.5 12.5523 5.94772 13 6.5 13H9.5C10.0523 13 10.5 12.5523 10.5 12C10.5 11.4477 10.0523 11 9.5 11H6.5Z"
fill="#2563EB"
/>
</svg>
<div>
<h6 className="font-medium text-black">
Once you start the server, you cannot chat with your
assistant.
</h6>
<Button
className="mt-4"
onClick={() => {
localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'false')
setFirstTimeVisitAPIServer(false)
}}
>
Got it
</Button>
</div>
</div>
</div>
</div>
) : (
<Logs />
)}
</ScrollToBottom>
{/* Right bar */}
<div
className={twMerge(
'h-full flex-shrink-0 overflow-x-hidden border-l border-border bg-background transition-all duration-100 dark:bg-background/20',
showing
? 'w-80 translate-x-0 opacity-100'
: 'w-0 translate-x-full opacity-0'
)}
>
<div className="px-4">
<div className="mt-4">
<DropdownListSidebar />
</div>
{componentDataEngineSetting.filter(
(x) => x.name === 'prompt_template'
).length !== 0 && (
<div className="mt-4">
<CardSidebar title="Model Parameters" asChild>
<div className="px-2 py-4">
<SettingComponentBuilder
enabled={!serverEnabled}
componentData={componentDataEngineSetting}
selector={(x) => x.name === 'prompt_template'}
/>
</div>
</CardSidebar>
</div>
)}
{componentDataEngineSetting.length !== 0 && (
<div className="my-4">
<CardSidebar title="Engine Parameters" asChild>
<div className="px-2 py-4">
<EngineSetting enabled={!serverEnabled} />
</div>
</CardSidebar>
</div>
)}
</div>
</div>
</div>
)
}
export default LocalServerScreen