From a50ea4a6343985842615f6ffe206b056716e9bf2 Mon Sep 17 00:00:00 2001 From: Louis Date: Mon, 22 Jan 2024 10:26:49 +0700 Subject: [PATCH] refactor: deprecate extension type implementation (#1677) * refactor: deprecate extension type implementation * chore: update README.md * refactor: EventName to use the events defined in /types --- core/README.md | 397 +++--------------- core/src/events.ts | 25 -- core/src/extension.ts | 11 +- core/src/extensions/assistant.ts | 17 +- core/src/extensions/conversational.ts | 9 +- core/src/extensions/inference.ts | 13 +- core/src/extensions/model.ts | 26 +- core/src/extensions/monitoring.ts | 15 +- extensions/assistant-extension/src/index.ts | 8 +- .../conversational-extension/src/index.ts | 10 +- .../inference-nitro-extension/src/index.ts | 41 +- .../inference-openai-extension/src/index.ts | 76 +--- .../src/index.ts | 72 +--- extensions/model-extension/src/index.ts | 12 +- extensions/monitoring-extension/src/index.ts | 11 +- web/containers/Providers/EventHandler.tsx | 23 +- web/extension/ExtensionManager.ts | 4 +- web/hooks/useActiveModel.ts | 7 +- web/hooks/useCreateNewThread.ts | 4 +- web/hooks/useDeleteModel.ts | 4 +- web/hooks/useDeleteThread.ts | 6 +- web/hooks/useDownloadModel.ts | 4 +- web/hooks/useGetAssistants.ts | 4 +- web/hooks/useGetConfiguredModels.ts | 4 +- web/hooks/useGetDownloadedModels.ts | 4 +- web/hooks/useGetSystemResources.ts | 8 +- web/hooks/useSendChatMessage.ts | 12 +- web/hooks/useSetActiveThread.ts | 8 +- web/hooks/useThreads.ts | 4 +- web/hooks/useUpdateModelParameters.ts | 4 +- web/screens/Chat/ErrorMessage/index.tsx | 4 +- web/screens/Chat/MessageToolbar/index.tsx | 4 +- web/screens/Chat/index.tsx | 4 +- web/services/extensionService.ts | 14 +- 34 files changed, 242 insertions(+), 627 deletions(-) diff --git a/core/README.md b/core/README.md index 62988ef76b..925ffaf7b8 100644 --- a/core/README.md +++ b/core/README.md @@ -1,348 +1,69 @@ ## @janhq/core -> The module includes functions for communicating with core APIs, registering plugin extensions, and exporting type definitions. +> This module includes functions for communicating with core APIs, registering app extensions, and exporting type definitions. ## Usage ### Import the package ```js -// javascript -const core = require("@janhq/core"); - -// typescript +// Web / extension runtime import * as core from "@janhq/core"; -``` - -### Register Plugin Extensions - -Every plugin must define an `init` function in its main entry file to initialize the plugin and register its extensions with the Jan platform. - -You can `register` any function as a plugin extension using `CoreServiceAPI` below. For example, the `DataService.GetConversations` entry name can be used to register a function that retrieves conversations. - -Once the extension is registered, it can be used by other plugins or components in the Jan platform. For example, a UI component might use the DataService.GetConversations extension to retrieve a list of conversations to display to the user. - -```js -import { RegisterExtensionPoint, DataService } from "@janhq/core"; - -function getConversations() { - // Your logic here -} - -export function init({ register }: { register: RegisterExtensionPoint }) { - register(DataService.GetConversations, getConversations.name, getConversations); -} -``` - -### Interact with Local Data Storage - -The Core API allows you to interact with local data storage. Here are a couple of examples of how you can use it: - -#### Insert Data - -You can use the store.insertOne function to insert data into a specific collection in the local data store. - -```js -import { store } from "@janhq/core"; - -function insertData() { - store.insertOne("conversations", { name: "meow" }); - // Insert a new document with { name: "meow" } into the "conversations" collection. -} -``` - -#### Get Data - -To retrieve data from a collection in the local data store, you can use the `store.findOne` or `store.findMany` function. It allows you to filter and retrieve documents based on specific criteria. - -store.getOne(collectionName, key) retrieves a single document that matches the provided key in the specified collection. -store.getMany(collectionName, selector, sort) retrieves multiple documents that match the provided selector in the specified collection. - -```js -import { store } from "@janhq/core"; - -function getData() { - const selector = { name: "meow" }; - const data = store.findMany("conversations", selector); - // Retrieve documents from the "conversations" collection that match the filter. -} -``` - -#### Update Data - -You can update data in the local store using these functions: - -store.updateOne(collectionName, key, update) updates a single document that matches the provided key in the specified collection. -store.updateMany(collectionName, selector, update) updates multiple documents that match the provided selector in the specified collection. - -```js -function updateData() { - const selector = { name: "meow" }; - const update = { name: "newName" }; - store.updateOne("conversations", selector, update); - // Update a document in the "conversations" collection. -} -``` - -#### Delete Data - -You can delete data from the local data store using these functions: - -store.deleteOne(collectionName, key) deletes a single document that matches the provided key in the specified collection. -store.deleteMany(collectionName, selector) deletes multiple documents that match the provided selector in the specified collection. - -```js -function deleteData() { - const selector = { name: "meow" }; - store.deleteOne("conversations", selector); - // Delete a document from the "conversations" collection. -} -``` - -### Events - -You can subscribe to NewMessageRequest events by defining a function to handle the event and registering it with the events object: - -```js -import { events } from "@janhq/core"; - -function handleMessageRequest(message: NewMessageRequest) { - // Your logic here. For example: - // const response = openai.createChatCompletion({...}) -} -function registerListener() { - events.on(EventName.OnNewMessageRequest, handleMessageRequest); -} -// Register the listener function with the relevant extension points. -export function init({ register }) { - registerListener(); -} -``` - -In this example, we're defining a function called handleMessageRequest that takes a NewMessageRequest object as its argument. We're also defining a function called registerListener that registers the handleMessageRequest function as a listener for NewMessageRequest events using the on method of the events object. - -```js -import { events } from "@janhq/core"; - -function handleMessageRequest(data: NewMessageRequest) { - // Your logic here. For example: - const response = openai.createChatCompletion({...}) - const message: NewMessageResponse = { - ...data, - message: response.data.choices[0].message.content - } - // Now emit event so the app can display in the conversation - events.emit(EventName.OnNewMessageResponse, message) -} -``` - -### Preferences - -To register plugin preferences, you can use the preferences object from the @janhq/core package. Here's an example of how to register and retrieve plugin preferences: - -```js -import { PluginService, preferences } from "@janhq/core"; - -const pluginName = "your-first-plugin"; -const preferenceKey = ""; -const preferenceName = "Your First Preference"; -const preferenceDescription = "This is for example only"; -const defaultValue = ""; - -export function init({ register }: { register: RegisterExtensionPoint }) { - // Register preference update handlers. E.g. update plugin instance with new configuration - register(PluginService.OnPreferencesUpdate, pluginName, onPreferencesUpdate); - - // Register plugin preferences. E.g. Plugin need apiKey to connect to your service - preferences.registerPreferences < - string > - (register, pluginName, preferenceKey, preferenceName, preferenceDescription, defaultValue); -} -``` - -In this example, we're registering preference update handlers and plugin preferences using the preferences object. We're also defining a PluginName constant to use as the name of the plugin. - -To retrieve the values of the registered preferences, we're using the get method of the preferences object and passing in the name of the plugin and the name of the preference. - -```js -import { preferences } from "@janhq/core"; - -const pluginName = "your-first-plugin"; -const preferenceKey = "apiKey"; - -const setup = async () => { - // Retrieve apiKey - const apiKey: string = (await preferences.get(pluginName, preferenceKey)) ?? ""; -}; -``` - -### Access Core API - -To access the Core API in your plugin, you can follow the code examples and explanations provided below. - -##### Import Core API and Store Module - -In your main entry code (e.g., `index.ts`), start by importing the necessary modules and functions from the `@janhq/core` library. - -```js -// index.ts -import * as core from "@janhq/core"; -``` - -#### Perform File Operations - -The Core API also provides functions to perform file operations. Here are a couple of examples: - -#### Download a File - -You can download a file from a specified URL and save it with a given file name using the core.downloadFile function. - -```js -function downloadModel(url: string, fileName: string, network?: { proxy?: string, ignoreSSL?: boolean }) { - core.downloadFile(url, fileName, network); -} -``` - -#### Delete a File - -To delete a file, you can use the core.deleteFile function, providing the path to the file you want to delete. - -```js -function deleteModel(filePath: string) { - core.deleteFile(path); -} -``` - -#### Execute plugin module in main process - -To execute a plugin module in the main process of your application, you can follow the steps outlined below. - -##### Import the `core` Object - -In your main process code (e.g., `index.ts`), start by importing the `core` object from the `@janhq/core` library. - -```js -// index.ts -import * as core from "@janhq/core"; -``` - -##### Define the Module Path - -Specify the path to the plugin module you want to execute. This path should lead to the module file (e.g., module.js) that contains the functions you wish to call. - -```js -// index.ts -const MODULE_PATH = "data-plugin/dist/module.js"; -``` - -##### Define the Function to Execute - -Create a function that will execute a function defined in your plugin module. In the example provided, the function `getConversationMessages` is created to invoke the `getConvMessages` function from the plugin module. - -```js -// index.ts -function getConversationMessages(id: number) { - return core.invokePluginFunc(MODULE_PATH, "getConvMessages", id); -} - -export function init({ register }: { register: RegisterExtensionPoint }) { - register(DataService.GetConversationMessages, getConversationMessages.name, getConversationMessages); -} -``` - -##### Define Your Plugin Module - -In your plugin module (e.g., module.ts), define the logic for the function you wish to execute. In the example, the function getConvMessages is defined with a placeholder comment indicating where your logic should be implemented. - -```js -// module.ts -function getConvMessages(id: number) { - // Your logic here -} - -module.exports = { - getConvMessages, -}; -``` - -## CoreService API - -The `CoreService` type is an exported union type that includes: - -- `StoreService` -- `DataService` -- `InferenceService` -- `ModelManagementService` -- `SystemMonitoringService` -- `PreferenceService` - -## StoreService - -The `StoreService` enum represents available methods for managing the database store. It includes the following methods: - -- `CreateCollection`: Creates a new collection in the data store. -- `DeleteCollection`: Deletes an existing collection from the data store. -- `InsertOne`: Inserts a new value into an existing collection in the data store. -- `UpdateOne`: Updates an existing value in an existing collection in the data store. -- `UpdateMany`: Updates multiple records in a collection in the data store. -- `DeleteOne`: Deletes an existing value from an existing collection in the data store. -- `DeleteMany`: Deletes multiple records in a collection in the data store. -- `FindMany`: Retrieves multiple records from a collection in the data store. -- `FindOne`: Retrieves a single record from a collection in the data store. - -## DataService - -The `DataService` enum represents methods related to managing conversations and messages. It includes the following methods: - -- `GetConversations`: Gets a list of conversations from the data store. -- `CreateConversation`: Creates a new conversation in the data store. -- `DeleteConversation`: Deletes an existing conversation from the data store. -- `CreateMessage`: Creates a new message in an existing conversation in the data store. -- `UpdateMessage`: Updates an existing message in an existing conversation in the data store. -- `GetConversationMessages`: Gets a list of messages for an existing conversation from the data store. - -## InferenceService - -The `InferenceService` enum exports: - -- `InitModel`: Initializes a model for inference. -- `StopModel`: Stops a running inference model. - -## ModelManagementService - -The `ModelManagementService` enum provides methods for managing models: - -- `GetDownloadedModels`: Gets a list of downloaded models. -- `GetAvailableModels`: Gets a list of available models from data store. -- `DeleteModel`: Deletes a downloaded model. -- `DownloadModel`: Downloads a model from the server. -- `SearchModels`: Searches for models on the server. -- `GetConfiguredModels`: Gets configured models from the data store. -- `StoreModel`: Stores a model in the data store. -- `UpdateFinishedDownloadAt`: Updates the finished download time for a model in the data store. -- `GetUnfinishedDownloadModels`: Gets a list of unfinished download models from the data store. -- `GetFinishedDownloadModels`: Gets a list of finished download models from the data store. -- `DeleteDownloadModel`: Deletes a downloaded model from the data store. -- `GetModelById`: Gets a model by its ID from the data store. - -## PreferenceService - -The `PreferenceService` enum provides methods for managing plugin preferences: - -- `ExperimentComponent`: Represents the UI experiment component for a testing function. - -## SystemMonitoringService - -The `SystemMonitoringService` enum includes methods for monitoring system resources: - -- `GetResourcesInfo`: Gets information about system resources. -- `GetCurrentLoad`: Gets the current system load. - -## PluginService - -The `PluginService` enum includes plugin cycle handlers: - -- `OnStart`: Handler for starting. E.g. Create a collection. -- `OnPreferencesUpdate`: Handler for preferences update. E.g. Update instances with new configurations. -For more detailed information on each of these components, please refer to the source code. +// Node runtime +import * as node from "@janhq/core/node"; +``` + +## Build an Extension + +1. Download an extension template, for example, [https://github.com/janhq/extension-template](https://github.com/janhq/extension-template). + +2. Update the source code: + 1. Open `index.ts` in your code editor. + 2. Rename the extension class from `SampleExtension` to your preferred extension name. + 3. Import modules from the core package. + ```ts + import * as core from "@janhq/core"; + ``` + 4. In the `onLoad()` method, add your code: + ```ts + // Example of listening to app events and providing customized inference logic: + import * as core from "@janhq/core"; + + export default class MyExtension extends BaseExtension { + // On extension load + onLoad() { + core.events.on(MessageEvent.OnMessageSent, (data) => MyExtension.inference(data, this)); + } + + // Customized inference logic + private static inference(incomingMessage: MessageRequestData) { + + // Prepare customized message content + const content: ThreadContent = { + type: ContentType.Text, + text: { + value: "I'm Jan Assistant!", + annotations: [], + }, + }; + + // Modify message and send out + const outGoingMessage: ThreadMessage = { + ...incomingMessage, + content + }; + } + } + ``` +3. Build the extension: + 1. Navigate to the extension directory. + 2. Install dependencies. + ```bash + yarn install + ``` + 3. Compile the source code. The following command keeps running in the terminal and rebuilds the extension when you modify the source code. + ```bash + yarn build + ``` + 4. Select the generated .tgz from Jan > Settings > Extension > Manual Installation. \ No newline at end of file diff --git a/core/src/events.ts b/core/src/events.ts index 7d38770467..700807b0cc 100644 --- a/core/src/events.ts +++ b/core/src/events.ts @@ -1,28 +1,3 @@ -// TODO: refactor EventName to use the events defined in /types -/** - * The `EventName` enumeration contains the names of all the available events in the Jan platform. - */ -export enum EventName { - /** The `OnMessageSent` event is emitted when a message is sent. */ - OnMessageSent = 'OnMessageSent', - /** The `OnMessageResponse` event is emitted when a message is received. */ - OnMessageResponse = 'OnMessageResponse', - /** The `OnMessageUpdate` event is emitted when a message is updated. */ - OnMessageUpdate = 'OnMessageUpdate', - /** The `OnModelInit` event is emitted when a model inits. */ - OnModelInit = 'OnModelInit', - /** The `OnModelReady` event is emitted when a model ready. */ - OnModelReady = 'OnModelReady', - /** The `OnModelFail` event is emitted when a model fails loading. */ - OnModelFail = 'OnModelFail', - /** The `OnModelStop` event is emitted when a model start to stop. */ - OnModelStop = 'OnModelStop', - /** The `OnModelStopped` event is emitted when a model stopped ok. */ - OnModelStopped = 'OnModelStopped', - /** The `OnInferenceStopped` event is emitted when a inference is stopped. */ - OnInferenceStopped = 'OnInferenceStopped', -} - /** * Adds an observer for an event. * diff --git a/core/src/extension.ts b/core/src/extension.ts index fc1031a53e..0b7f9b7fc1 100644 --- a/core/src/extension.ts +++ b/core/src/extension.ts @@ -1,4 +1,4 @@ -export enum ExtensionType { +export enum ExtensionTypeEnum { Assistant = "assistant", Conversational = "conversational", Inference = "inference", @@ -6,17 +6,22 @@ export enum ExtensionType { SystemMonitoring = "systemMonitoring", } +export interface ExtensionType { + type(): ExtensionTypeEnum | undefined; +} /** * Represents a base extension. * This class should be extended by any class that represents an extension. */ -export abstract class BaseExtension { +export abstract class BaseExtension implements ExtensionType { /** * Returns the type of the extension. * @returns {ExtensionType} The type of the extension * Undefined means its not extending any known extension by the application. */ - abstract type(): ExtensionType | undefined; + type(): ExtensionTypeEnum | undefined { + return undefined; + } /** * Called when the extension is loaded. * Any initialization logic for the extension should be put here. diff --git a/core/src/extensions/assistant.ts b/core/src/extensions/assistant.ts index 96646e374c..ba345711ae 100644 --- a/core/src/extensions/assistant.ts +++ b/core/src/extensions/assistant.ts @@ -1,12 +1,19 @@ -import { Assistant, AssistantInterface } from '../index' -import { BaseExtension } from '../extension' +import { Assistant, AssistantInterface } from "../index"; +import { BaseExtension, ExtensionTypeEnum } from "../extension"; /** * Assistant extension for managing assistants. * @extends BaseExtension */ export abstract class AssistantExtension extends BaseExtension implements AssistantInterface { - abstract createAssistant(assistant: Assistant): Promise - abstract deleteAssistant(assistant: Assistant): Promise - abstract getAssistants(): Promise + /** + * Assistant extension type. + */ + type(): ExtensionTypeEnum | undefined { + return ExtensionTypeEnum.Assistant; + } + + abstract createAssistant(assistant: Assistant): Promise; + abstract deleteAssistant(assistant: Assistant): Promise; + abstract getAssistants(): Promise; } diff --git a/core/src/extensions/conversational.ts b/core/src/extensions/conversational.ts index 673ea9c11e..4319784c35 100644 --- a/core/src/extensions/conversational.ts +++ b/core/src/extensions/conversational.ts @@ -1,5 +1,5 @@ import { Thread, ThreadInterface, ThreadMessage, MessageInterface } from '../index' -import { BaseExtension } from '../extension' +import { BaseExtension, ExtensionTypeEnum } from '../extension' /** * Conversational extension. Persists and retrieves conversations. @@ -10,6 +10,13 @@ export abstract class ConversationalExtension extends BaseExtension implements ThreadInterface, MessageInterface { + /** + * Conversation extension type. + */ + type(): ExtensionTypeEnum | undefined { + return ExtensionTypeEnum.Conversational; + } + abstract getThreads(): Promise abstract saveThread(thread: Thread): Promise abstract deleteThread(threadId: string): Promise diff --git a/core/src/extensions/inference.ts b/core/src/extensions/inference.ts index f3654934af..c551d108f5 100644 --- a/core/src/extensions/inference.ts +++ b/core/src/extensions/inference.ts @@ -1,9 +1,16 @@ -import { InferenceInterface, MessageRequest, ThreadMessage } from '../index' -import { BaseExtension } from '../extension' +import { InferenceInterface, MessageRequest, ThreadMessage } from "../index"; +import { BaseExtension, ExtensionTypeEnum } from "../extension"; /** * Inference extension. Start, stop and inference models. */ export abstract class InferenceExtension extends BaseExtension implements InferenceInterface { - abstract inference(data: MessageRequest): Promise + /** + * Inference extension type. + */ + type(): ExtensionTypeEnum | undefined { + return ExtensionTypeEnum.Inference; + } + + abstract inference(data: MessageRequest): Promise; } diff --git a/core/src/extensions/model.ts b/core/src/extensions/model.ts index 00fe2cf4da..30aa5b6ba2 100644 --- a/core/src/extensions/model.ts +++ b/core/src/extensions/model.ts @@ -1,14 +1,24 @@ -import { BaseExtension } from '../extension' -import { Model, ModelInterface } from '../index' +import { BaseExtension, ExtensionTypeEnum } from "../extension"; +import { Model, ModelInterface } from "../index"; /** * Model extension for managing models. */ export abstract class ModelExtension extends BaseExtension implements ModelInterface { - abstract downloadModel(model: Model, network?: { proxy: string, ignoreSSL?: boolean }): Promise - abstract cancelModelDownload(modelId: string): Promise - abstract deleteModel(modelId: string): Promise - abstract saveModel(model: Model): Promise - abstract getDownloadedModels(): Promise - abstract getConfiguredModels(): Promise + /** + * Model extension type. + */ + type(): ExtensionTypeEnum | undefined { + return ExtensionTypeEnum.Model; + } + + abstract downloadModel( + model: Model, + network?: { proxy: string; ignoreSSL?: boolean }, + ): Promise; + abstract cancelModelDownload(modelId: string): Promise; + abstract deleteModel(modelId: string): Promise; + abstract saveModel(model: Model): Promise; + abstract getDownloadedModels(): Promise; + abstract getConfiguredModels(): Promise; } diff --git a/core/src/extensions/monitoring.ts b/core/src/extensions/monitoring.ts index 94f437f86a..2de9b9ae56 100644 --- a/core/src/extensions/monitoring.ts +++ b/core/src/extensions/monitoring.ts @@ -1,11 +1,18 @@ -import { BaseExtension } from '../extension' -import { MonitoringInterface } from '../index' +import { BaseExtension, ExtensionTypeEnum } from "../extension"; +import { MonitoringInterface } from "../index"; /** * Monitoring extension for system monitoring. * @extends BaseExtension */ export abstract class MonitoringExtension extends BaseExtension implements MonitoringInterface { - abstract getResourcesInfo(): Promise - abstract getCurrentLoad(): Promise + /** + * Monitoring extension type. + */ + type(): ExtensionTypeEnum | undefined { + return ExtensionTypeEnum.SystemMonitoring; + } + + abstract getResourcesInfo(): Promise; + abstract getCurrentLoad(): Promise; } diff --git a/extensions/assistant-extension/src/index.ts b/extensions/assistant-extension/src/index.ts index 0c5745b3d9..96de33b7be 100644 --- a/extensions/assistant-extension/src/index.ts +++ b/extensions/assistant-extension/src/index.ts @@ -1,14 +1,10 @@ -import { ExtensionType, fs, Assistant } from "@janhq/core"; +import { fs, Assistant } from "@janhq/core"; import { AssistantExtension } from "@janhq/core"; import { join } from "path"; -export default class JanAssistantExtension implements AssistantExtension { +export default class JanAssistantExtension extends AssistantExtension { private static readonly _homeDir = "file://assistants"; - type(): ExtensionType { - return ExtensionType.Assistant; - } - async onLoad() { // making the assistant directory if (!(await fs.existsSync(JanAssistantExtension._homeDir))) diff --git a/extensions/conversational-extension/src/index.ts b/extensions/conversational-extension/src/index.ts index 70eb9f8513..66becb7482 100644 --- a/extensions/conversational-extension/src/index.ts +++ b/extensions/conversational-extension/src/index.ts @@ -1,5 +1,4 @@ import { - ExtensionType, fs, joinPath, ConversationalExtension, @@ -12,19 +11,12 @@ import { * functionality for managing threads. */ export default class JSONConversationalExtension - implements ConversationalExtension + extends ConversationalExtension { private static readonly _homeDir = 'file://threads' private static readonly _threadInfoFileName = 'thread.json' private static readonly _threadMessagesFileName = 'messages.jsonl' - /** - * Returns the type of the extension. - */ - type(): ExtensionType { - return ExtensionType.Conversational - } - /** * Called when the extension is loaded. */ diff --git a/extensions/inference-nitro-extension/src/index.ts b/extensions/inference-nitro-extension/src/index.ts index fdd352aad2..ba3705fde6 100644 --- a/extensions/inference-nitro-extension/src/index.ts +++ b/extensions/inference-nitro-extension/src/index.ts @@ -9,10 +9,8 @@ import { ChatCompletionRole, ContentType, - EventName, MessageRequest, MessageStatus, - ExtensionType, ThreadContent, ThreadMessage, events, @@ -23,6 +21,9 @@ import { InferenceExtension, log, InferenceEngine, + MessageEvent, + ModelEvent, + InferenceEvent, } from "@janhq/core"; import { requestInference } from "./helpers/sse"; import { ulid } from "ulid"; @@ -32,7 +33,7 @@ import { ulid } from "ulid"; * The class provides methods for initializing and stopping a model, and for making inference requests. * It also subscribes to events emitted by the @janhq/core package and handles new message requests. */ -export default class JanInferenceNitroExtension implements InferenceExtension { +export default class JanInferenceNitroExtension extends InferenceExtension { private static readonly _homeDir = "file://engines"; private static readonly _settingsDir = "file://settings"; private static readonly _engineMetadataFileName = "nitro.json"; @@ -66,14 +67,6 @@ export default class JanInferenceNitroExtension implements InferenceExtension { */ private nitroProcessInfo: any = undefined; - /** - * Returns the type of the extension. - * @returns {ExtensionType} The type of the extension. - */ - type(): ExtensionType { - return ExtensionType.Inference; - } - /** * Subscribes to events emitted by the @janhq/core package. */ @@ -89,15 +82,15 @@ export default class JanInferenceNitroExtension implements InferenceExtension { this.writeDefaultEngineSettings(); // Events subscription - events.on(EventName.OnMessageSent, (data: MessageRequest) => + events.on(MessageEvent.OnMessageSent, (data: MessageRequest) => this.onMessageRequest(data) ); - events.on(EventName.OnModelInit, (model: Model) => this.onModelInit(model)); + events.on(ModelEvent.OnModelInit, (model: Model) => this.onModelInit(model)); - events.on(EventName.OnModelStop, (model: Model) => this.onModelStop(model)); + events.on(ModelEvent.OnModelStop, (model: Model) => this.onModelStop(model)); - events.on(EventName.OnInferenceStopped, () => this.onInferenceStopped()); + events.on(InferenceEvent.OnInferenceStopped, () => this.onInferenceStopped()); // Attempt to fetch nvidia info await executeOnMain(NODE, "updateNvidiaInfo", {}); @@ -140,12 +133,12 @@ export default class JanInferenceNitroExtension implements InferenceExtension { }); if (nitroInitResult?.error) { - events.emit(EventName.OnModelFail, model); + events.emit(ModelEvent.OnModelFail, model); return; } this._currentModel = model; - events.emit(EventName.OnModelReady, model); + events.emit(ModelEvent.OnModelReady, model); this.getNitroProcesHealthIntervalId = setInterval( () => this.periodicallyGetNitroHealth(), @@ -157,7 +150,7 @@ export default class JanInferenceNitroExtension implements InferenceExtension { if (model.engine !== "nitro") return; await executeOnMain(NODE, "stopModel"); - events.emit(EventName.OnModelStopped, {}); + events.emit(ModelEvent.OnModelStopped, {}); // stop the periocally health check if (this.getNitroProcesHealthIntervalId) { @@ -175,7 +168,7 @@ export default class JanInferenceNitroExtension implements InferenceExtension { const isRunning = this.nitroProcessInfo?.isRunning ?? false; if (isRunning && health.isRunning === false) { console.debug("Nitro process is stopped"); - events.emit(EventName.OnModelStopped, {}); + events.emit(ModelEvent.OnModelStopped, {}); } this.nitroProcessInfo = health; } @@ -241,7 +234,7 @@ export default class JanInferenceNitroExtension implements InferenceExtension { updated: timestamp, object: "thread.message", }; - events.emit(EventName.OnMessageResponse, message); + events.emit(MessageEvent.OnMessageResponse, message); this.isCancelled = false; this.controller = new AbortController(); @@ -261,22 +254,22 @@ export default class JanInferenceNitroExtension implements InferenceExtension { }, }; message.content = [messageContent]; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, complete: async () => { message.status = message.content.length ? MessageStatus.Ready : MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, error: async (err) => { if (this.isCancelled || message.content.length) { message.status = MessageStatus.Stopped; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); return; } message.status = MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); log(`[APP]::Error: ${err.message}`); }, }); diff --git a/extensions/inference-openai-extension/src/index.ts b/extensions/inference-openai-extension/src/index.ts index 246aa124b1..54572041d7 100644 --- a/extensions/inference-openai-extension/src/index.ts +++ b/extensions/inference-openai-extension/src/index.ts @@ -9,16 +9,17 @@ import { ChatCompletionRole, ContentType, - EventName, MessageRequest, MessageStatus, - ExtensionType, ThreadContent, ThreadMessage, events, fs, + BaseExtension, + MessageEvent, + ModelEvent, + InferenceEvent, } from "@janhq/core"; -import { InferenceExtension } from "@janhq/core"; import { requestInference } from "./helpers/sse"; import { ulid } from "ulid"; import { join } from "path"; @@ -28,7 +29,7 @@ import { join } from "path"; * The class provides methods for initializing and stopping a model, and for making inference requests. * It also subscribes to events emitted by the @janhq/core package and handles new message requests. */ -export default class JanInferenceOpenAIExtension implements InferenceExtension { +export default class JanInferenceOpenAIExtension extends BaseExtension { private static readonly _homeDir = "file://engines"; private static readonly _engineMetadataFileName = "openai.json"; @@ -42,14 +43,6 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { controller = new AbortController(); isCancelled = false; - /** - * Returns the type of the extension. - * @returns {ExtensionType} The type of the extension. - */ - // TODO: To fix - type(): ExtensionType { - return undefined; - } /** * Subscribes to events emitted by the @janhq/core package. */ @@ -63,18 +56,18 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { JanInferenceOpenAIExtension.writeDefaultEngineSettings(); // Events subscription - events.on(EventName.OnMessageSent, (data) => + events.on(MessageEvent.OnMessageSent, (data) => JanInferenceOpenAIExtension.handleMessageRequest(data, this) ); - events.on(EventName.OnModelInit, (model: OpenAIModel) => { + events.on(ModelEvent.OnModelInit, (model: OpenAIModel) => { JanInferenceOpenAIExtension.handleModelInit(model); }); - events.on(EventName.OnModelStop, (model: OpenAIModel) => { + events.on(ModelEvent.OnModelStop, (model: OpenAIModel) => { JanInferenceOpenAIExtension.handleModelStop(model); }); - events.on(EventName.OnInferenceStopped, () => { + events.on(InferenceEvent.OnInferenceStopped, () => { JanInferenceOpenAIExtension.handleInferenceStopped(this); }); } @@ -104,43 +97,6 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { console.error(err); } } - - /** - * Makes a single response inference request. - * @param {MessageRequest} data - The data for the inference request. - * @returns {Promise} A promise that resolves with the inference response. - */ - async inference(data: MessageRequest): Promise { - const timestamp = Date.now(); - - const message: ThreadMessage = { - thread_id: data.threadId, - created: timestamp, - updated: timestamp, - status: MessageStatus.Ready, - id: "", - role: ChatCompletionRole.Assistant, - object: "thread.message", - content: [], - }; - - return new Promise(async (resolve, reject) => { - requestInference( - data.messages ?? [], - JanInferenceOpenAIExtension._engineSettings, - JanInferenceOpenAIExtension._currentModel - ).subscribe({ - next: (_content) => {}, - complete: async () => { - resolve(message); - }, - error: async (err) => { - reject(err); - }, - }); - }); - } - private static async handleModelInit(model: OpenAIModel) { if (model.engine !== "openai") { return; @@ -148,7 +104,7 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { JanInferenceOpenAIExtension._currentModel = model; JanInferenceOpenAIExtension.writeDefaultEngineSettings(); // Todo: Check model list with API key - events.emit(EventName.OnModelReady, model); + events.emit(ModelEvent.OnModelReady, model); } } @@ -156,7 +112,7 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { if (model.engine !== "openai") { return; } - events.emit(EventName.OnModelStopped, model); + events.emit(ModelEvent.OnModelStopped, model); } private static async handleInferenceStopped( @@ -192,7 +148,7 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { updated: timestamp, object: "thread.message", }; - events.emit(EventName.OnMessageResponse, message); + events.emit(MessageEvent.OnMessageResponse, message); instance.isCancelled = false; instance.controller = new AbortController(); @@ -215,18 +171,18 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { }, }; message.content = [messageContent]; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, complete: async () => { message.status = message.content.length ? MessageStatus.Ready : MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, error: async (err) => { if (instance.isCancelled || message.content.length > 0) { message.status = MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); return; } const messageContent: ThreadContent = { @@ -238,7 +194,7 @@ export default class JanInferenceOpenAIExtension implements InferenceExtension { }; message.content = [messageContent]; message.status = MessageStatus.Ready; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, }); } diff --git a/extensions/inference-triton-trtllm-extension/src/index.ts b/extensions/inference-triton-trtllm-extension/src/index.ts index aed2f581ac..11ddf78933 100644 --- a/extensions/inference-triton-trtllm-extension/src/index.ts +++ b/extensions/inference-triton-trtllm-extension/src/index.ts @@ -9,18 +9,18 @@ import { ChatCompletionRole, ContentType, - EventName, MessageRequest, MessageStatus, ModelSettingParams, - ExtensionType, ThreadContent, ThreadMessage, events, fs, Model, + BaseExtension, + MessageEvent, + ModelEvent, } from "@janhq/core"; -import { InferenceExtension } from "@janhq/core"; import { requestInference } from "./helpers/sse"; import { ulid } from "ulid"; import { join } from "path"; @@ -32,7 +32,7 @@ import { EngineSettings } from "./@types/global"; * It also subscribes to events emitted by the @janhq/core package and handles new message requests. */ export default class JanInferenceTritonTrtLLMExtension - implements InferenceExtension + extends BaseExtension { private static readonly _homeDir = "file://engines"; private static readonly _engineMetadataFileName = "triton_trtllm.json"; @@ -46,14 +46,6 @@ export default class JanInferenceTritonTrtLLMExtension controller = new AbortController(); isCancelled = false; - /** - * Returns the type of the extension. - * @returns {ExtensionType} The type of the extension. - */ - // TODO: To fix - type(): ExtensionType { - return undefined; - } /** * Subscribes to events emitted by the @janhq/core package. */ @@ -62,15 +54,15 @@ export default class JanInferenceTritonTrtLLMExtension JanInferenceTritonTrtLLMExtension.writeDefaultEngineSettings(); // Events subscription - events.on(EventName.OnMessageSent, (data) => + events.on(MessageEvent.OnMessageSent, (data) => JanInferenceTritonTrtLLMExtension.handleMessageRequest(data, this) ); - events.on(EventName.OnModelInit, (model: Model) => { + events.on(ModelEvent.OnModelInit, (model: Model) => { JanInferenceTritonTrtLLMExtension.handleModelInit(model); }); - events.on(EventName.OnModelStop, (model: Model) => { + events.on(ModelEvent.OnModelStop, (model: Model) => { JanInferenceTritonTrtLLMExtension.handleModelStop(model); }); } @@ -131,41 +123,6 @@ export default class JanInferenceTritonTrtLLMExtension this.controller?.abort(); } - /** - * Makes a single response inference request. - * @param {MessageRequest} data - The data for the inference request. - * @returns {Promise} A promise that resolves with the inference response. - */ - async inference(data: MessageRequest): Promise { - const timestamp = Date.now(); - const message: ThreadMessage = { - thread_id: data.threadId, - created: timestamp, - updated: timestamp, - status: MessageStatus.Ready, - id: "", - role: ChatCompletionRole.Assistant, - object: "thread.message", - content: [], - }; - - return new Promise(async (resolve, reject) => { - requestInference( - data.messages ?? [], - JanInferenceTritonTrtLLMExtension._engineSettings, - JanInferenceTritonTrtLLMExtension._currentModel - ).subscribe({ - next: (_content) => {}, - complete: async () => { - resolve(message); - }, - error: async (err) => { - reject(err); - }, - }); - }); - } - private static async handleModelInit(model: Model) { if (model.engine !== "triton_trtllm") { return; @@ -173,8 +130,7 @@ export default class JanInferenceTritonTrtLLMExtension JanInferenceTritonTrtLLMExtension._currentModel = model; JanInferenceTritonTrtLLMExtension.writeDefaultEngineSettings(); // Todo: Check model list with API key - events.emit(EventName.OnModelReady, model); - // events.emit(EventName.OnModelFail, model) + events.emit(ModelEvent.OnModelReady, model); } } @@ -182,7 +138,7 @@ export default class JanInferenceTritonTrtLLMExtension if (model.engine !== "triton_trtllm") { return; } - events.emit(EventName.OnModelStopped, model); + events.emit(ModelEvent.OnModelStopped, model); } /** @@ -211,7 +167,7 @@ export default class JanInferenceTritonTrtLLMExtension updated: timestamp, object: "thread.message", }; - events.emit(EventName.OnMessageResponse, message); + events.emit(MessageEvent.OnMessageResponse, message); instance.isCancelled = false; instance.controller = new AbortController(); @@ -234,18 +190,18 @@ export default class JanInferenceTritonTrtLLMExtension }, }; message.content = [messageContent]; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, complete: async () => { message.status = message.content.length ? MessageStatus.Ready : MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, error: async (err) => { if (instance.isCancelled || message.content.length) { message.status = MessageStatus.Error; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); return; } const messageContent: ThreadContent = { @@ -257,7 +213,7 @@ export default class JanInferenceTritonTrtLLMExtension }; message.content = [messageContent]; message.status = MessageStatus.Ready; - events.emit(EventName.OnMessageUpdate, message); + events.emit(MessageEvent.OnMessageUpdate, message); }, }); } diff --git a/extensions/model-extension/src/index.ts b/extensions/model-extension/src/index.ts index f1573dd465..1328e83df6 100644 --- a/extensions/model-extension/src/index.ts +++ b/extensions/model-extension/src/index.ts @@ -1,5 +1,4 @@ import { - ExtensionType, fs, downloadFile, abortDownload, @@ -14,7 +13,7 @@ import { /** * A extension for models */ -export default class JanModelExtension implements ModelExtension { +export default class JanModelExtension extends ModelExtension { private static readonly _homeDir = 'file://models' private static readonly _modelMetadataFileName = 'model.json' private static readonly _supportedModelFormat = '.gguf' @@ -24,15 +23,6 @@ export default class JanModelExtension implements ModelExtension { private static readonly _configDirName = 'config' private static readonly _defaultModelFileName = 'default-model.json' - /** - * Implements type from JanExtension. - * @override - * @returns The type of the extension. - */ - type(): ExtensionType { - return ExtensionType.Model - } - /** * Called when the extension is loaded. * @override diff --git a/extensions/monitoring-extension/src/index.ts b/extensions/monitoring-extension/src/index.ts index f1cbf6dad4..d3f20b4376 100644 --- a/extensions/monitoring-extension/src/index.ts +++ b/extensions/monitoring-extension/src/index.ts @@ -1,4 +1,3 @@ -import { ExtensionType } from "@janhq/core"; import { MonitoringExtension } from "@janhq/core"; import { executeOnMain } from "@janhq/core"; @@ -6,15 +5,7 @@ import { executeOnMain } from "@janhq/core"; * JanMonitoringExtension is a extension that provides system monitoring functionality. * It implements the MonitoringExtension interface from the @janhq/core package. */ -export default class JanMonitoringExtension implements MonitoringExtension { - /** - * Returns the type of the extension. - * @returns The ExtensionType.SystemMonitoring value. - */ - type(): ExtensionType { - return ExtensionType.SystemMonitoring; - } - +export default class JanMonitoringExtension extends MonitoringExtension { /** * Called when the extension is loaded. */ diff --git a/web/containers/Providers/EventHandler.tsx b/web/containers/Providers/EventHandler.tsx index 66622b1b6c..1f9d6d7af0 100644 --- a/web/containers/Providers/EventHandler.tsx +++ b/web/containers/Providers/EventHandler.tsx @@ -3,12 +3,13 @@ import { ReactNode, useEffect, useRef } from 'react' import { events, - EventName, ThreadMessage, - ExtensionType, + ExtensionTypeEnum, MessageStatus, Model, ConversationalExtension, + MessageEvent, + ModelEvent, } from '@janhq/core' import { useAtomValue, useSetAtom } from 'jotai' @@ -100,14 +101,14 @@ export default function EventHandler({ children }: { children: ReactNode }) { lastMessage: messageContent, } extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.saveThread({ ...thread, metadata, }) extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.addNewMessage(message) } } @@ -115,19 +116,19 @@ export default function EventHandler({ children }: { children: ReactNode }) { useEffect(() => { if (window.core?.events) { - events.on(EventName.OnMessageResponse, handleNewMessageResponse) - events.on(EventName.OnMessageUpdate, handleMessageResponseUpdate) - events.on(EventName.OnModelReady, handleModelReady) - events.on(EventName.OnModelFail, handleModelFail) - events.on(EventName.OnModelStopped, handleModelStopped) + events.on(MessageEvent.OnMessageResponse, handleNewMessageResponse) + events.on(MessageEvent.OnMessageUpdate, handleMessageResponseUpdate) + events.on(ModelEvent.OnModelReady, handleModelReady) + events.on(ModelEvent.OnModelFail, handleModelFail) + events.on(ModelEvent.OnModelStopped, handleModelStopped) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { return () => { - events.off(EventName.OnMessageResponse, handleNewMessageResponse) - events.off(EventName.OnMessageUpdate, handleMessageResponseUpdate) + events.off(MessageEvent.OnMessageResponse, handleNewMessageResponse) + events.off(MessageEvent.OnMessageUpdate, handleMessageResponseUpdate) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) diff --git a/web/extension/ExtensionManager.ts b/web/extension/ExtensionManager.ts index 43847f3447..3074177bb8 100644 --- a/web/extension/ExtensionManager.ts +++ b/web/extension/ExtensionManager.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { BaseExtension, ExtensionType } from '@janhq/core' +import { BaseExtension, ExtensionTypeEnum } from '@janhq/core' import Extension from './Extension' @@ -23,7 +23,7 @@ export class ExtensionManager { * @param type - The type of the extension to retrieve. * @returns The extension, if found. */ - get(type: ExtensionType): T | undefined { + get(type: ExtensionTypeEnum): T | undefined { return this.extensions.get(type) as T | undefined } diff --git a/web/hooks/useActiveModel.ts b/web/hooks/useActiveModel.ts index 8c05a515ed..336f0be21a 100644 --- a/web/hooks/useActiveModel.ts +++ b/web/hooks/useActiveModel.ts @@ -1,5 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { EventName, events, Model } from '@janhq/core' +import { events, Model, ModelEvent } from '@janhq/core' import { atom, useAtom, useAtomValue } from 'jotai' import { toaster } from '@/containers/Toast' @@ -64,14 +63,14 @@ export function useActiveModel() { } localStorage.setItem(LAST_USED_MODEL_ID, model.id) - events.emit(EventName.OnModelInit, model) + events.emit(ModelEvent.OnModelInit, model) } const stopModel = async () => { if (activeModel) { setActiveModel(undefined) setStateModel({ state: 'stop', loading: true, model: activeModel.id }) - events.emit(EventName.OnModelStop, activeModel) + events.emit(ModelEvent.OnModelStop, activeModel) } } diff --git a/web/hooks/useCreateNewThread.ts b/web/hooks/useCreateNewThread.ts index 08b7a74302..e374d0cc5f 100644 --- a/web/hooks/useCreateNewThread.ts +++ b/web/hooks/useCreateNewThread.ts @@ -1,7 +1,7 @@ import { Assistant, ConversationalExtension, - ExtensionType, + ExtensionTypeEnum, Thread, ThreadAssistantInfo, ThreadState, @@ -104,7 +104,7 @@ export const useCreateNewThread = () => { } extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.saveThread(thread) } diff --git a/web/hooks/useDeleteModel.ts b/web/hooks/useDeleteModel.ts index e8472d7ed2..cd7292997f 100644 --- a/web/hooks/useDeleteModel.ts +++ b/web/hooks/useDeleteModel.ts @@ -1,4 +1,4 @@ -import { ExtensionType, ModelExtension, Model } from '@janhq/core' +import { ExtensionTypeEnum, ModelExtension, Model } from '@janhq/core' import { toaster } from '@/containers/Toast' @@ -11,7 +11,7 @@ export default function useDeleteModel() { const deleteModel = async (model: Model) => { await extensionManager - .get(ExtensionType.Model) + .get(ExtensionTypeEnum.Model) ?.deleteModel(model.id) // reload models diff --git a/web/hooks/useDeleteThread.ts b/web/hooks/useDeleteThread.ts index 2aac2b2070..84dd8a468f 100644 --- a/web/hooks/useDeleteThread.ts +++ b/web/hooks/useDeleteThread.ts @@ -1,6 +1,6 @@ import { ChatCompletionRole, - ExtensionType, + ExtensionTypeEnum, ConversationalExtension, } from '@janhq/core' @@ -44,7 +44,7 @@ export default function useDeleteThread() { if (thread) { await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.writeMessages( threadId, messages.filter((msg) => msg.role === ChatCompletionRole.System) @@ -61,7 +61,7 @@ export default function useDeleteThread() { } try { await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.deleteThread(threadId) const availableThreads = threads.filter((c) => c.id !== threadId) setThreads(availableThreads) diff --git a/web/hooks/useDownloadModel.ts b/web/hooks/useDownloadModel.ts index 14051fa63b..49dbe1d5b4 100644 --- a/web/hooks/useDownloadModel.ts +++ b/web/hooks/useDownloadModel.ts @@ -2,7 +2,7 @@ import { useContext } from 'react' import { Model, - ExtensionType, + ExtensionTypeEnum, ModelExtension, abortDownload, joinPath, @@ -43,7 +43,7 @@ export default function useDownloadModel() { addNewDownloadingModel(model) await extensionManager - .get(ExtensionType.Model) + .get(ExtensionTypeEnum.Model) ?.downloadModel(model, { ignoreSSL, proxy }) } const abortModelDownload = async (model: Model) => { diff --git a/web/hooks/useGetAssistants.ts b/web/hooks/useGetAssistants.ts index bc81968357..2b34bfbd14 100644 --- a/web/hooks/useGetAssistants.ts +++ b/web/hooks/useGetAssistants.ts @@ -1,12 +1,12 @@ import { useEffect, useState } from 'react' -import { Assistant, ExtensionType, AssistantExtension } from '@janhq/core' +import { Assistant, ExtensionTypeEnum, AssistantExtension } from '@janhq/core' import { extensionManager } from '@/extension/ExtensionManager' export const getAssistants = async (): Promise => extensionManager - .get(ExtensionType.Assistant) + .get(ExtensionTypeEnum.Assistant) ?.getAssistants() ?? [] /** diff --git a/web/hooks/useGetConfiguredModels.ts b/web/hooks/useGetConfiguredModels.ts index d79778a00c..5662d534e1 100644 --- a/web/hooks/useGetConfiguredModels.ts +++ b/web/hooks/useGetConfiguredModels.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' -import { ExtensionType, ModelExtension } from '@janhq/core' +import { ExtensionTypeEnum, ModelExtension } from '@janhq/core' import { Model } from '@janhq/core' import { extensionManager } from '@/extension/ExtensionManager' @@ -11,7 +11,7 @@ export function useGetConfiguredModels() { const getConfiguredModels = async (): Promise => { const models = await extensionManager - .get(ExtensionType.Model) + .get(ExtensionTypeEnum.Model) ?.getConfiguredModels() return models ?? [] } diff --git a/web/hooks/useGetDownloadedModels.ts b/web/hooks/useGetDownloadedModels.ts index adeb6eed75..f509fce632 100644 --- a/web/hooks/useGetDownloadedModels.ts +++ b/web/hooks/useGetDownloadedModels.ts @@ -1,6 +1,6 @@ import { useEffect } from 'react' -import { ExtensionType, ModelExtension, Model } from '@janhq/core' +import { ExtensionTypeEnum, ModelExtension, Model } from '@janhq/core' import { atom, useAtom } from 'jotai' @@ -22,5 +22,5 @@ export function useGetDownloadedModels() { export const getDownloadedModels = async (): Promise => extensionManager - .get(ExtensionType.Model) + .get(ExtensionTypeEnum.Model) ?.getDownloadedModels() ?? [] diff --git a/web/hooks/useGetSystemResources.ts b/web/hooks/useGetSystemResources.ts index 9d6716480d..af08653a9a 100644 --- a/web/hooks/useGetSystemResources.ts +++ b/web/hooks/useGetSystemResources.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' -import { ExtensionType } from '@janhq/core' +import { ExtensionTypeEnum } from '@janhq/core' import { MonitoringExtension } from '@janhq/core' import { useSetAtom } from 'jotai' @@ -21,12 +21,14 @@ export default function useGetSystemResources() { const getSystemResources = async () => { if ( - !extensionManager.get(ExtensionType.SystemMonitoring) + !extensionManager.get( + ExtensionTypeEnum.SystemMonitoring + ) ) { return } const monitoring = extensionManager.get( - ExtensionType.SystemMonitoring + ExtensionTypeEnum.SystemMonitoring ) const resourceInfor = await monitoring?.getResourcesInfo() const currentLoadInfor = await monitoring?.getCurrentLoad() diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index b4fdc9bd37..bf9740489f 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -4,15 +4,15 @@ import { ChatCompletionMessage, ChatCompletionRole, ContentType, - EventName, MessageRequest, MessageStatus, - ExtensionType, + ExtensionTypeEnum, Thread, ThreadMessage, events, Model, ConversationalExtension, + MessageEvent, } from '@janhq/core' import { useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -116,7 +116,7 @@ export default function useSendChatMessage() { await WaitForModelStarting(modelId) setQueuedMessage(false) } - events.emit(EventName.OnMessageSent, messageRequest) + events.emit(MessageEvent.OnMessageSent, messageRequest) } // TODO: Refactor @louis @@ -181,7 +181,7 @@ export default function useSendChatMessage() { updateThread(updatedThread) await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.saveThread(updatedThread) } @@ -253,7 +253,7 @@ export default function useSendChatMessage() { addNewMessage(threadMessage) await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.addNewMessage(threadMessage) const modelId = selectedModel?.id ?? activeThread.assistants[0].model.id @@ -265,7 +265,7 @@ export default function useSendChatMessage() { setQueuedMessage(false) } - events.emit(EventName.OnMessageSent, messageRequest) + events.emit(MessageEvent.OnMessageSent, messageRequest) setReloadModel(false) setEngineParamsUpdate(false) diff --git a/web/hooks/useSetActiveThread.ts b/web/hooks/useSetActiveThread.ts index c029ec46c4..76a744bcd3 100644 --- a/web/hooks/useSetActiveThread.ts +++ b/web/hooks/useSetActiveThread.ts @@ -1,6 +1,6 @@ import { - EventName, - ExtensionType, + InferenceEvent, + ExtensionTypeEnum, Thread, events, ConversationalExtension, @@ -29,11 +29,11 @@ export default function useSetActiveThread() { return } - events.emit(EventName.OnInferenceStopped, thread.id) + events.emit(InferenceEvent.OnInferenceStopped, thread.id) // load the corresponding messages const messages = await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.getAllMessages(thread.id) setThreadMessage(thread.id, messages ?? []) diff --git a/web/hooks/useThreads.ts b/web/hooks/useThreads.ts index 6469696749..b79cfea927 100644 --- a/web/hooks/useThreads.ts +++ b/web/hooks/useThreads.ts @@ -1,5 +1,5 @@ import { - ExtensionType, + ExtensionTypeEnum, Thread, ThreadState, ConversationalExtension, @@ -99,7 +99,7 @@ const useThreads = () => { const getLocalThreads = async (): Promise => (await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.getThreads()) ?? [] export default useThreads diff --git a/web/hooks/useUpdateModelParameters.ts b/web/hooks/useUpdateModelParameters.ts index 0edca51362..80070ef26e 100644 --- a/web/hooks/useUpdateModelParameters.ts +++ b/web/hooks/useUpdateModelParameters.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ConversationalExtension, - ExtensionType, + ExtensionTypeEnum, Thread, ThreadAssistantInfo, } from '@janhq/core' @@ -73,7 +73,7 @@ export default function useUpdateModelParameters() { } await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.saveThread(updatedThread) } diff --git a/web/screens/Chat/ErrorMessage/index.tsx b/web/screens/Chat/ErrorMessage/index.tsx index f4c5fc45a3..41d58dbdd6 100644 --- a/web/screens/Chat/ErrorMessage/index.tsx +++ b/web/screens/Chat/ErrorMessage/index.tsx @@ -1,7 +1,7 @@ import { ChatCompletionRole, ConversationalExtension, - ExtensionType, + ExtensionTypeEnum, MessageStatus, ThreadMessage, } from '@janhq/core' @@ -32,7 +32,7 @@ const ErrorMessage = ({ message }: { message: ThreadMessage }) => { deleteMessage(message.id ?? '') if (thread) { await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.writeMessages( thread.id, messages.filter((msg) => msg.id !== message.id) diff --git a/web/screens/Chat/MessageToolbar/index.tsx b/web/screens/Chat/MessageToolbar/index.tsx index 721b0476b6..183eae814e 100644 --- a/web/screens/Chat/MessageToolbar/index.tsx +++ b/web/screens/Chat/MessageToolbar/index.tsx @@ -1,6 +1,6 @@ import { MessageStatus, - ExtensionType, + ExtensionTypeEnum, ThreadMessage, ChatCompletionRole, } from '@janhq/core' @@ -31,7 +31,7 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => { deleteMessage(message.id ?? '') if (thread) { await extensionManager - .get(ExtensionType.Conversational) + .get(ExtensionTypeEnum.Conversational) ?.writeMessages( thread.id, messages.filter((msg) => msg.id !== message.id) diff --git a/web/screens/Chat/index.tsx b/web/screens/Chat/index.tsx index 2e2e6ffeca..684027e497 100644 --- a/web/screens/Chat/index.tsx +++ b/web/screens/Chat/index.tsx @@ -1,6 +1,6 @@ import { ChangeEvent, Fragment, KeyboardEvent, useEffect, useRef } from 'react' -import { EventName, MessageStatus, events } from '@janhq/core' +import { InferenceEvent, MessageStatus, events } from '@janhq/core' import { Button, Textarea } from '@janhq/uikit' import { useAtom, useAtomValue } from 'jotai' @@ -104,7 +104,7 @@ const ChatScreen = () => { ) const onStopInferenceClick = async () => { - events.emit(EventName.OnInferenceStopped, {}) + events.emit(InferenceEvent.OnInferenceStopped, {}) } return ( diff --git a/web/services/extensionService.ts b/web/services/extensionService.ts index b18fb3cc1e..6ae4f78f05 100644 --- a/web/services/extensionService.ts +++ b/web/services/extensionService.ts @@ -1,15 +1,15 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ 'use client' -import { ExtensionType } from '@janhq/core' +import { ExtensionTypeEnum } from '@janhq/core' import { extensionManager } from '@/extension/ExtensionManager' export const isCoreExtensionInstalled = () => { - if (!extensionManager.get(ExtensionType.Conversational)) { + if (!extensionManager.get(ExtensionTypeEnum.Conversational)) { return false } - if (!extensionManager.get(ExtensionType.Inference)) return false - if (!extensionManager.get(ExtensionType.Model)) { + if (!extensionManager.get(ExtensionTypeEnum.Inference)) return false + if (!extensionManager.get(ExtensionTypeEnum.Model)) { return false } return true @@ -21,9 +21,9 @@ export const setupBaseExtensions = async () => { const baseExtensions = await window.core?.api.baseExtensions() if ( - !extensionManager.get(ExtensionType.Conversational) || - !extensionManager.get(ExtensionType.Inference) || - !extensionManager.get(ExtensionType.Model) + !extensionManager.get(ExtensionTypeEnum.Conversational) || + !extensionManager.get(ExtensionTypeEnum.Inference) || + !extensionManager.get(ExtensionTypeEnum.Model) ) { const installed = await extensionManager.install(baseExtensions) if (installed) {