Skip to content

Commit

Permalink
fix: reduce the number of api call (janhq#1896)
Browse files Browse the repository at this point in the history
Signed-off-by: James <[email protected]>
Co-authored-by: James <[email protected]>
  • Loading branch information
namchuai and James authored Feb 5, 2024
1 parent ccbe18e commit 01fec49
Show file tree
Hide file tree
Showing 32 changed files with 467 additions and 419 deletions.
11 changes: 10 additions & 1 deletion core/src/node/api/routes/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
import { JanApiRouteConfiguration } from '../common/configuration'
import { startModel, stopModel } from '../common/startStopModel'
import { ModelSettingParams } from '../../../types'
import { getJanDataFolderPath } from '../../utils'
import { normalizeFilePath } from '../../path'

export const commonRouter = async (app: HttpServer) => {
// Common Routes
Expand Down Expand Up @@ -52,7 +54,14 @@ export const commonRouter = async (app: HttpServer) => {
// App Routes
app.post(`/app/${AppRoute.joinPath}`, async (request: any, reply: any) => {
const args = JSON.parse(request.body) as any[]
reply.send(JSON.stringify(join(...args[0])))

const paths = args[0].map((arg: string) =>
typeof arg === 'string' && (arg.startsWith(`file:/`) || arg.startsWith(`file:\\`))
? join(getJanDataFolderPath(), normalizeFilePath(arg))
: arg
)

reply.send(JSON.stringify(join(...paths)))
})

app.post(`/app/${AppRoute.baseName}`, async (request: any, reply: any) => {
Expand Down
68 changes: 34 additions & 34 deletions core/src/node/api/routes/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,55 @@ import { DownloadManager } from '../../download'
import { HttpServer } from '../HttpServer'
import { createWriteStream } from 'fs'
import { getJanDataFolderPath } from '../../utils'
import { normalizeFilePath } from "../../path";
import { normalizeFilePath } from '../../path'

export const downloadRouter = async (app: HttpServer) => {
app.post(`/${DownloadRoute.downloadFile}`, async (req, res) => {
const strictSSL = !(req.query.ignoreSSL === "true");
const proxy = req.query.proxy?.startsWith("http") ? req.query.proxy : undefined;
const body = JSON.parse(req.body as any);
const strictSSL = !(req.query.ignoreSSL === 'true')
const proxy = req.query.proxy?.startsWith('http') ? req.query.proxy : undefined
const body = JSON.parse(req.body as any)
const normalizedArgs = body.map((arg: any) => {
if (typeof arg === "string") {
return join(getJanDataFolderPath(), normalizeFilePath(arg));
if (typeof arg === 'string' && arg.startsWith('file:')) {
return join(getJanDataFolderPath(), normalizeFilePath(arg))
}
return arg;
});
return arg
})

const localPath = normalizedArgs[1];
const fileName = localPath.split("/").pop() ?? "";
const localPath = normalizedArgs[1]
const fileName = localPath.split('/').pop() ?? ''

const request = require("request");
const progress = require("request-progress");
const request = require('request')
const progress = require('request-progress')

const rq = request({ url: normalizedArgs[0], strictSSL, proxy });
const rq = request({ url: normalizedArgs[0], strictSSL, proxy })
progress(rq, {})
.on("progress", function (state: any) {
console.log("download onProgress", state);
.on('progress', function (state: any) {
console.log('download onProgress', state)
})
.on("error", function (err: Error) {
console.log("download onError", err);
.on('error', function (err: Error) {
console.log('download onError', err)
})
.on("end", function () {
console.log("download onEnd");
.on('end', function () {
console.log('download onEnd')
})
.pipe(createWriteStream(normalizedArgs[1]));
.pipe(createWriteStream(normalizedArgs[1]))

DownloadManager.instance.setRequest(fileName, rq);
});
DownloadManager.instance.setRequest(fileName, rq)
})

app.post(`/${DownloadRoute.abortDownload}`, async (req, res) => {
const body = JSON.parse(req.body as any);
const body = JSON.parse(req.body as any)
const normalizedArgs = body.map((arg: any) => {
if (typeof arg === "string") {
return join(getJanDataFolderPath(), normalizeFilePath(arg));
if (typeof arg === 'string' && arg.startsWith('file:')) {
return join(getJanDataFolderPath(), normalizeFilePath(arg))
}
return arg;
});
return arg
})

const localPath = normalizedArgs[0];
const fileName = localPath.split("/").pop() ?? "";
const rq = DownloadManager.instance.networkRequests[fileName];
DownloadManager.instance.networkRequests[fileName] = undefined;
rq?.abort();
});
};
const localPath = normalizedArgs[0]
const fileName = localPath.split('/').pop() ?? ''
const rq = DownloadManager.instance.networkRequests[fileName]
DownloadManager.instance.networkRequests[fileName] = undefined
rq?.abort()
})
}
43 changes: 19 additions & 24 deletions extensions/conversational-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import {
* functionality for managing threads.
*/
export default class JSONConversationalExtension extends ConversationalExtension {
private static readonly _homeDir = 'file://threads'
private static readonly _threadFolder = 'file://threads'
private static readonly _threadInfoFileName = 'thread.json'
private static readonly _threadMessagesFileName = 'messages.jsonl'

/**
* Called when the extension is loaded.
*/
async onLoad() {
if (!(await fs.existsSync(JSONConversationalExtension._homeDir)))
await fs.mkdirSync(JSONConversationalExtension._homeDir)
if (!(await fs.existsSync(JSONConversationalExtension._threadFolder)))
await fs.mkdirSync(JSONConversationalExtension._threadFolder)
console.debug('JSONConversationalExtension loaded')
}

Expand Down Expand Up @@ -68,7 +68,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
async saveThread(thread: Thread): Promise<void> {
try {
const threadDirPath = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
thread.id,
])
const threadJsonPath = await joinPath([
Expand All @@ -92,7 +92,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
*/
async deleteThread(threadId: string): Promise<void> {
const path = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
`${threadId}`,
])
try {
Expand All @@ -109,7 +109,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
async addNewMessage(message: ThreadMessage): Promise<void> {
try {
const threadDirPath = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
message.thread_id,
])
const threadMessagePath = await joinPath([
Expand Down Expand Up @@ -177,7 +177,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
): Promise<void> {
try {
const threadDirPath = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
threadId,
])
const threadMessagePath = await joinPath([
Expand Down Expand Up @@ -205,7 +205,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
private async readThread(threadDirName: string): Promise<any> {
return fs.readFileSync(
await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
threadDirName,
JSONConversationalExtension._threadInfoFileName,
]),
Expand All @@ -219,14 +219,14 @@ export default class JSONConversationalExtension extends ConversationalExtension
*/
private async getValidThreadDirs(): Promise<string[]> {
const fileInsideThread: string[] = await fs.readdirSync(
JSONConversationalExtension._homeDir
JSONConversationalExtension._threadFolder
)

const threadDirs: string[] = []
for (let i = 0; i < fileInsideThread.length; i++) {
if (fileInsideThread[i].includes('.DS_Store')) continue
const path = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
fileInsideThread[i],
])

Expand All @@ -246,7 +246,7 @@ export default class JSONConversationalExtension extends ConversationalExtension
async getAllMessages(threadId: string): Promise<ThreadMessage[]> {
try {
const threadDirPath = await joinPath([
JSONConversationalExtension._homeDir,
JSONConversationalExtension._threadFolder,
threadId,
])

Expand All @@ -263,22 +263,17 @@ export default class JSONConversationalExtension extends ConversationalExtension
JSONConversationalExtension._threadMessagesFileName,
])

const result = await fs
.readFileSync(messageFilePath, 'utf-8')
.then((content) =>
content
.toString()
.split('\n')
.filter((line) => line !== '')
)
let readResult = await fs.readFileSync(messageFilePath, 'utf-8')

if (typeof readResult === 'object') {
readResult = JSON.stringify(readResult)
}

const result = readResult.split('\n').filter((line) => line !== '')

const messages: ThreadMessage[] = []
result.forEach((line: string) => {
try {
messages.push(JSON.parse(line) as ThreadMessage)
} catch (err) {
console.error(err)
}
messages.push(JSON.parse(line))
})
return messages
} catch (err) {
Expand Down
6 changes: 4 additions & 2 deletions web/containers/Layout/BottomBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ import { MainViewState } from '@/constants/screens'
import { useActiveModel } from '@/hooks/useActiveModel'

import { useDownloadState } from '@/hooks/useDownloadState'
import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels'

import useGetSystemResources from '@/hooks/useGetSystemResources'
import { useMainViewState } from '@/hooks/useMainViewState'

import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'

const menuLinks = [
{
Expand All @@ -49,7 +50,8 @@ const BottomBar = () => {
const { activeModel, stateModel } = useActiveModel()
const { ram, cpu } = useGetSystemResources()
const progress = useAtomValue(appDownloadProgress)
const { downloadedModels } = useGetDownloadedModels()
const downloadedModels = useAtomValue(downloadedModelsAtom)

const { setMainViewState } = useMainViewState()
const { downloadStates } = useDownloadState()
const setShowSelectModelModal = useSetAtom(showSelectModelModalAtom)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ import {
Badge,
} from '@janhq/uikit'

import { useAtom } from 'jotai'
import { useAtom, useAtomValue } from 'jotai'
import { DatabaseIcon, CpuIcon } from 'lucide-react'

import { showSelectModelModalAtom } from '@/containers/Providers/KeyListener'

import { MainViewState } from '@/constants/screens'

import { useActiveModel } from '@/hooks/useActiveModel'
import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels'
import { useMainViewState } from '@/hooks/useMainViewState'

import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'

export default function CommandListDownloadedModel() {
const { setMainViewState } = useMainViewState()
const { downloadedModels } = useGetDownloadedModels()
const downloadedModels = useAtomValue(downloadedModelsAtom)
const { activeModel, startModel, stopModel } = useActiveModel()
const [serverEnabled] = useAtom(serverEnabledAtom)
const [showSelectModelModal, setShowSelectModelModal] = useAtom(
Expand Down
11 changes: 3 additions & 8 deletions web/containers/Layout/TopBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { MainViewState } from '@/constants/screens'

import { useClickOutside } from '@/hooks/useClickOutside'
import { useCreateNewThread } from '@/hooks/useCreateNewThread'
import useGetAssistants, { getAssistants } from '@/hooks/useGetAssistants'
import { useMainViewState } from '@/hooks/useMainViewState'

import { usePath } from '@/hooks/usePath'
Expand All @@ -29,13 +28,14 @@ import { showRightSideBarAtom } from '@/screens/Chat/Sidebar'

import { openFileTitle } from '@/utils/titleUtils'

import { assistantsAtom } from '@/helpers/atoms/Assistant.atom'
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'

const TopBar = () => {
const activeThread = useAtomValue(activeThreadAtom)
const { mainViewState } = useMainViewState()
const { requestCreateNewThread } = useCreateNewThread()
const { assistants } = useGetAssistants()
const assistants = useAtomValue(assistantsAtom)
const [showRightSideBar, setShowRightSideBar] = useAtom(showRightSideBarAtom)
const [showLeftSideBar, setShowLeftSideBar] = useAtom(showLeftSideBarAtom)
const showing = useAtomValue(showRightSideBarAtom)
Expand All @@ -61,12 +61,7 @@ const TopBar = () => {

const onCreateConversationClick = async () => {
if (assistants.length === 0) {
const res = await getAssistants()
if (res.length === 0) {
alert('No assistant available')
return
}
requestCreateNewThread(res[0])
alert('No assistant available')
} else {
requestCreateNewThread(assistants[0])
}
Expand Down
21 changes: 21 additions & 0 deletions web/containers/Providers/DataLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client'

import { Fragment, ReactNode } from 'react'

import useAssistants from '@/hooks/useAssistants'
import useModels from '@/hooks/useModels'
import useThreads from '@/hooks/useThreads'

type Props = {
children: ReactNode
}

const DataLoader: React.FC<Props> = ({ children }) => {
useModels()
useThreads()
useAssistants()

return <Fragment>{children}</Fragment>
}

export default DataLoader
6 changes: 3 additions & 3 deletions web/containers/Providers/EventHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
loadModelErrorAtom,
stateModelAtom,
} from '@/hooks/useActiveModel'
import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels'

import { queuedMessageAtom } from '@/hooks/useSendChatMessage'

Expand All @@ -29,6 +28,7 @@ import {
addNewMessageAtom,
updateMessageAtom,
} from '@/helpers/atoms/ChatMessage.atom'
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
import {
updateThreadWaitingForResponseAtom,
threadsAtom,
Expand All @@ -38,7 +38,7 @@ import {
export default function EventHandler({ children }: { children: ReactNode }) {
const addNewMessage = useSetAtom(addNewMessageAtom)
const updateMessage = useSetAtom(updateMessageAtom)
const { downloadedModels } = useGetDownloadedModels()
const downloadedModels = useAtomValue(downloadedModelsAtom)
const setActiveModel = useSetAtom(activeModelAtom)
const setStateModel = useSetAtom(stateModelAtom)
const setQueuedMessage = useSetAtom(queuedMessageAtom)
Expand Down Expand Up @@ -143,7 +143,7 @@ export default function EventHandler({ children }: { children: ReactNode }) {
?.addNewMessage(message)
}
},
[updateMessage, updateThreadWaiting]
[updateMessage, updateThreadWaiting, setIsGeneratingResponse]
)

useEffect(() => {
Expand Down
Loading

0 comments on commit 01fec49

Please sign in to comment.