From 1f641f35caa67f75fe88a946318684c2111f94c2 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 26 Dec 2023 16:01:05 +0700 Subject: [PATCH] fix: app issues with server refactoring --- core/src/node/api/common/builder.ts | 2 +- core/src/node/api/routes/fs.ts | 15 ++++++----- electron/handlers/fs.ts | 2 +- extensions/assistant-extension/src/index.ts | 8 ++++-- .../conversational-extension/src/index.ts | 25 ++++++++++++------- .../inference-nitro-extension/src/index.ts | 7 +++--- .../inference-nitro-extension/src/module.ts | 4 +++ .../inference-openai-extension/src/index.ts | 11 +++----- .../src/index.ts | 12 ++++----- web/hooks/useEngineSettings.ts | 10 +++++--- web/hooks/useSendChatMessage.ts | 2 +- web/screens/Chat/ChatBody/index.tsx | 4 +-- 12 files changed, 59 insertions(+), 43 deletions(-) diff --git a/core/src/node/api/common/builder.ts b/core/src/node/api/common/builder.ts index 85c9c88516..4081e859f8 100644 --- a/core/src/node/api/common/builder.ts +++ b/core/src/node/api/common/builder.ts @@ -107,7 +107,7 @@ export const getMessages = async (threadId: string) => { const messageFilePath = join(threadDirPath, messageFile) const lines = fs - .readFileSync(messageFilePath) + .readFileSync(messageFilePath, 'utf-8') .toString() .split('\n') .filter((line: any) => line !== '') diff --git a/core/src/node/api/routes/fs.ts b/core/src/node/api/routes/fs.ts index b4934604b4..f0cf1eeedc 100644 --- a/core/src/node/api/routes/fs.ts +++ b/core/src/node/api/routes/fs.ts @@ -3,17 +3,20 @@ import { join } from 'path' import { HttpServer, userSpacePath } from '../../index' export const fsRouter = async (app: HttpServer) => { - const moduleName = "fs" + const moduleName = 'fs' // Generate handlers for each fs route Object.values(FileSystemRoute).forEach((route) => { app.post(`/${route}`, async (req, res) => { const body = JSON.parse(req.body as any) try { - const result = await import(moduleName).then(mdl => { return mdl[route]( - ...body.map((arg: any) => - arg.includes('file:/') ? join(userSpacePath, arg.replace('file:/', '')) : arg, - ), - ) + const result = await import(moduleName).then((mdl) => { + return mdl[route]( + ...body.map((arg: any) => + typeof arg === 'string' && arg.includes('file:/') + ? join(userSpacePath, arg.replace('file:/', '')) + : arg, + ), + ) }) res.status(200).send(result) } catch (ex) { diff --git a/electron/handlers/fs.ts b/electron/handlers/fs.ts index 7e92fc0f12..fdfaba6063 100644 --- a/electron/handlers/fs.ts +++ b/electron/handlers/fs.ts @@ -13,7 +13,7 @@ export function handleFsIPCs() { return import(moduleName).then((mdl) => mdl[route]( ...args.map((arg) => - arg.includes('file:/') + typeof arg === 'string' && arg.includes('file:/') ? join(userSpacePath, arg.replace('file:/', '')) : arg ) diff --git a/extensions/assistant-extension/src/index.ts b/extensions/assistant-extension/src/index.ts index 92ca8f2fda..0c5745b3d9 100644 --- a/extensions/assistant-extension/src/index.ts +++ b/extensions/assistant-extension/src/index.ts @@ -20,7 +20,7 @@ export default class JanAssistantExtension implements AssistantExtension { /** * Called when the extension is unloaded. */ - onUnload(): void { } + onUnload(): void {} async createAssistant(assistant: Assistant): Promise { const assistantDir = join(JanAssistantExtension._homeDir, assistant.id); @@ -48,6 +48,7 @@ export default class JanAssistantExtension implements AssistantExtension { for (const fileName of allFileName) { const filePath = join(JanAssistantExtension._homeDir, fileName); + if (filePath.includes(".DS_Store")) continue; const jsonFiles: string[] = (await fs.readdirSync(filePath)).filter( (file: string) => file === "assistant.json" ); @@ -57,7 +58,10 @@ export default class JanAssistantExtension implements AssistantExtension { continue; } - const content = await fs.readFileSync(join(filePath, jsonFiles[0]), 'utf-8'); + const content = await fs.readFileSync( + join(filePath, jsonFiles[0]), + "utf-8" + ); const assistant: Assistant = typeof content === "object" ? content : JSON.parse(content); diff --git a/extensions/conversational-extension/src/index.ts b/extensions/conversational-extension/src/index.ts index cf594f9baf..53e1bd8999 100644 --- a/extensions/conversational-extension/src/index.ts +++ b/extensions/conversational-extension/src/index.ts @@ -8,7 +8,8 @@ import { join } from 'path' * functionality for managing threads. */ export default class JSONConversationalExtension - implements ConversationalExtension { + implements ConversationalExtension +{ private static readonly _homeDir = 'file://threads' private static readonly _threadInfoFileName = 'thread.json' private static readonly _threadMessagesFileName = 'messages.jsonl' @@ -96,7 +97,8 @@ export default class JSONConversationalExtension */ deleteThread(threadId: string): Promise { return fs.rmdirSync( - join(JSONConversationalExtension._homeDir, `${threadId}`) + join(JSONConversationalExtension._homeDir, `${threadId}`), + { recursive: true } ) } @@ -153,7 +155,8 @@ export default class JSONConversationalExtension JSONConversationalExtension._homeDir, threadDirName, JSONConversationalExtension._threadInfoFileName - ) + ), + 'utf-8' ) } @@ -168,6 +171,8 @@ export default class JSONConversationalExtension const threadDirs: string[] = [] for (let i = 0; i < fileInsideThread.length; i++) { + if (fileInsideThread[i].includes('.DS_Store')) continue + const path = join( JSONConversationalExtension._homeDir, fileInsideThread[i] @@ -202,12 +207,14 @@ export default class JSONConversationalExtension JSONConversationalExtension._threadMessagesFileName ) - const result = await fs.readFileSync(messageFilePath, 'utf-8').then((content) => - content - .toString() - .split('\n') - .filter((line) => line !== '') - ) + const result = await fs + .readFileSync(messageFilePath, 'utf-8') + .then((content) => + content + .toString() + .split('\n') + .filter((line) => line !== '') + ) const messages: ThreadMessage[] = [] result.forEach((line: string) => { diff --git a/extensions/inference-nitro-extension/src/index.ts b/extensions/inference-nitro-extension/src/index.ts index a9976abf9b..686aa1097b 100644 --- a/extensions/inference-nitro-extension/src/index.ts +++ b/extensions/inference-nitro-extension/src/index.ts @@ -17,7 +17,6 @@ import { ThreadMessage, events, executeOnMain, - getUserSpace, fs, Model, } from "@janhq/core"; @@ -93,9 +92,9 @@ export default class JanInferenceNitroExtension implements InferenceExtension { JanInferenceNitroExtension._engineMetadataFileName ); if (await fs.existsSync(engineFile)) { - JanInferenceNitroExtension._engineSettings = JSON.parse( - await fs.readFileSync(engineFile) - ); + const engine = await fs.readFileSync(engineFile, 'utf-8'); + JanInferenceNitroExtension._engineSettings = + typeof engine === "object" ? engine : JSON.parse(engine); } else { await fs.writeFileSync( engineFile, diff --git a/extensions/inference-nitro-extension/src/module.ts b/extensions/inference-nitro-extension/src/module.ts index bca0b6fccd..5e3c13c966 100644 --- a/extensions/inference-nitro-extension/src/module.ts +++ b/extensions/inference-nitro-extension/src/module.ts @@ -37,6 +37,10 @@ function stopModel(): Promise { */ async function initModel(wrapper: any): Promise { currentModelFile = wrapper.modelFullPath; + const janRoot = path.join(require("os").homedir(), "jan"); + if (!currentModelFile.includes(janRoot)) { + currentModelFile = path.join(janRoot, currentModelFile); + } if (wrapper.model.engine !== "nitro") { return Promise.resolve({ error: "Not a nitro model" }); } else { diff --git a/extensions/inference-openai-extension/src/index.ts b/extensions/inference-openai-extension/src/index.ts index c38fb7c5ac..d612e474e9 100644 --- a/extensions/inference-openai-extension/src/index.ts +++ b/extensions/inference-openai-extension/src/index.ts @@ -87,14 +87,9 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { JanInferenceOpenAIExtension._engineMetadataFileName ); if (await fs.existsSync(engineFile)) { - try { - JanInferenceOpenAIExtension._engineSettings = JSON.parse( - await fs.readFileSync(engineFile) - ); - } catch { - JanInferenceOpenAIExtension._engineSettings = - await fs.readFileSync(engineFile); - } + const engine = await fs.readFileSync(engineFile, 'utf-8'); + JanInferenceOpenAIExtension._engineSettings = + typeof engine === "object" ? engine : JSON.parse(engine); } else { await fs.writeFileSync( engineFile, diff --git a/extensions/inference-triton-trtllm-extension/src/index.ts b/extensions/inference-triton-trtllm-extension/src/index.ts index 0970b19345..7ef5270e70 100644 --- a/extensions/inference-triton-trtllm-extension/src/index.ts +++ b/extensions/inference-triton-trtllm-extension/src/index.ts @@ -57,9 +57,9 @@ export default class JanInferenceTritonTrtLLMExtension /** * Subscribes to events emitted by the @janhq/core package. */ - onLoad(): void { - fs.mkdirSync(JanInferenceTritonTrtLLMExtension._homeDir); - JanInferenceTritonTrtLLMExtension.writeDefaultEngineSettings(); + async onLoad() { + if (!(await fs.existsSync(JanInferenceTritonTrtLLMExtension._homeDir))) + JanInferenceTritonTrtLLMExtension.writeDefaultEngineSettings(); // Events subscription events.on(EventName.OnMessageSent, (data) => @@ -99,9 +99,9 @@ export default class JanInferenceTritonTrtLLMExtension JanInferenceTritonTrtLLMExtension._engineMetadataFileName ); if (await fs.existsSync(engine_json)) { - JanInferenceTritonTrtLLMExtension._engineSettings = JSON.parse( - await fs.readFileSync(engine_json) - ); + const engine = await fs.readFileSync(engine_json, "utf-8"); + JanInferenceTritonTrtLLMExtension._engineSettings = + typeof engine === "object" ? engine : JSON.parse(engine); } else { await fs.writeFileSync( engine_json, diff --git a/web/hooks/useEngineSettings.ts b/web/hooks/useEngineSettings.ts index 9fe2e4541d..2e8fed55af 100644 --- a/web/hooks/useEngineSettings.ts +++ b/web/hooks/useEngineSettings.ts @@ -4,9 +4,13 @@ import { fs } from '@janhq/core' export const useEngineSettings = () => { const readOpenAISettings = async () => { - const settings = await fs.readFileSync(join('engines', 'openai.json')) + if (!fs.existsSync(join('file://engines', 'openai.json'))) return {} + const settings = await fs.readFileSync( + join('file://engines', 'openai.json'), + 'utf-8' + ) if (settings) { - return JSON.parse(settings) + return typeof settings === 'object' ? settings : JSON.parse(settings) } return {} } @@ -18,7 +22,7 @@ export const useEngineSettings = () => { const settings = await readOpenAISettings() settings.api_key = apiKey await fs.writeFileSync( - join('engines', 'openai.json'), + join('file://engines', 'openai.json'), JSON.stringify(settings) ) } diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index 8913104d32..17aba82f2a 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -171,7 +171,7 @@ export default function useSendChatMessage() { updateThreadInitSuccess(activeThread.id) updateThread(updatedThread) - extensionManager + await extensionManager .get(ExtensionType.Conversational) ?.saveThread(updatedThread) } diff --git a/web/screens/Chat/ChatBody/index.tsx b/web/screens/Chat/ChatBody/index.tsx index 4d86e9e44b..b9a74fa8df 100644 --- a/web/screens/Chat/ChatBody/index.tsx +++ b/web/screens/Chat/ChatBody/index.tsx @@ -126,8 +126,8 @@ const ChatBody: React.FC = () => { className="mt-10 flex flex-col items-center" > - Oops! The generation was interrupted. Let's - give it another go! + Oops! The generation was interrupted. Let's give it + another go!