diff --git a/docs/docs/about/about.md b/docs/docs/about/about.md deleted file mode 100644 index fea0b0c0b..000000000 --- a/docs/docs/about/about.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: About Jan -slug: /about ---- - -## Problem - -## Ideal Customer Persona - -## Business Model \ No newline at end of file diff --git a/docs/docs/about/brand-assets.md b/docs/docs/about/brand-assets.md deleted file mode 100644 index 3566f6256..000000000 --- a/docs/docs/about/brand-assets.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Brand Assets ---- diff --git a/docs/docs/about/team.md b/docs/docs/about/team.md deleted file mode 100644 index 492a7dce7..000000000 --- a/docs/docs/about/team.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Team ---- - diff --git a/docs/docs/apps/azure-openai.md b/docs/docs/apps/azure-openai.md new file mode 100644 index 000000000..76963b4eb --- /dev/null +++ b/docs/docs/apps/azure-openai.md @@ -0,0 +1,5 @@ +--- +title: "Azure OpenAI Plugin" +--- + +NPM Package: [@janhq/azure-openai-plugin](https://www.npmjs.com/package/@janhq/azure-openai-plugin) diff --git a/docs/docs/apps/data.md b/docs/docs/apps/data.md new file mode 100644 index 000000000..5fd3aadbd --- /dev/null +++ b/docs/docs/apps/data.md @@ -0,0 +1,5 @@ +--- +title: "Data Plugin" +--- + +NPM Package: [@janhq/data-plugin](https://www.npmjs.com/package/@janhq/data-plugin) diff --git a/docs/docs/apps/inference.md b/docs/docs/apps/inference.md new file mode 100644 index 000000000..ebd47db4d --- /dev/null +++ b/docs/docs/apps/inference.md @@ -0,0 +1,5 @@ +--- +title: "Inference Plugin" +--- + +NPM Package: [@janhq/inference-plugin](https://www.npmjs.com/package/@janhq/inference-plugin) diff --git a/docs/docs/apps/model-management.md b/docs/docs/apps/model-management.md new file mode 100644 index 000000000..b4775968b --- /dev/null +++ b/docs/docs/apps/model-management.md @@ -0,0 +1,5 @@ +--- +title: "Model Management Plugin" +--- + +NPM Package: [@janhq/model-management-plugin](https://www.npmjs.com/package/@janhq/model-management-plugin) diff --git a/docs/docs/apps/monitoring.md b/docs/docs/apps/monitoring.md new file mode 100644 index 000000000..e0e49ea80 --- /dev/null +++ b/docs/docs/apps/monitoring.md @@ -0,0 +1,5 @@ +--- +title: "Monitoring Plugin" +--- + +NPM Package: [@janhq/monitoring-plugin](https://www.npmjs.com/package/@janhq/monitoring-plugin) diff --git a/docs/docs/apps/rag.md b/docs/docs/apps/rag.md new file mode 100644 index 000000000..5d9084be8 --- /dev/null +++ b/docs/docs/apps/rag.md @@ -0,0 +1,5 @@ +--- +title: "RAG Plugin" +--- + +Coming soon. diff --git a/docs/docs/changelog/README.md b/docs/docs/changelog/README.md deleted file mode 100644 index 9ba595391..000000000 --- a/docs/docs/changelog/README.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -title: Changelog ---- - -TODO \ No newline at end of file diff --git a/docs/docs/docs/docs.md b/docs/docs/docs/docs.md deleted file mode 100644 index ed1a5cd97..000000000 --- a/docs/docs/docs/docs.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -title: Getting Started ---- - -TODO \ No newline at end of file diff --git a/docs/docs/docs/install/mac.md b/docs/docs/docs/install/mac.md deleted file mode 100644 index a43b6eecb..000000000 --- a/docs/docs/docs/install/mac.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Installing Jan on Linux ---- \ No newline at end of file diff --git a/docs/docs/docs/install/windows.md b/docs/docs/docs/install/windows.md deleted file mode 100644 index a43b6eecb..000000000 --- a/docs/docs/docs/install/windows.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Installing Jan on Linux ---- \ No newline at end of file diff --git a/docs/docs/getting-started/app-anatomy.md b/docs/docs/getting-started/app-anatomy.md new file mode 100644 index 000000000..16c94d318 --- /dev/null +++ b/docs/docs/getting-started/app-anatomy.md @@ -0,0 +1,62 @@ +--- +sidebar_position: 2 +title: Anatomy of an app +--- + +### High level architecture + +![High level architecture](img/architecture-0.drawio.png) +Jan mission is to power the next gen App with the limitless extensibility by providing BUILDER: + +- Unified API/ Helpers so that they only need to care about what matters +- Wide range of Optimized and State of the art models that can help your App with Thinking/ Hearing/ Seeing capabilities. This is powered by our [Nitro](https://github.com/janhq/nitro) +- Strong support for App marketplace and Model market place that streamline value from end customers to builders at all layers +- The most important: The user of Jan can use the Apps via UI and API for integration + +At Jan, we strongly believe in `portable AI` that is created once and run anywhere. + +### Low level architecture + +![Low level architecture](img/architecture-1.drawio.png) + +- Jan platform includes the following components: + + - Processes: + - UI process: + - This is Electron framework `renderer` component (Web technology equivalent) + - Jan provides core platform UI that: + - Allows App to `register()` function blueprint with name and arguments + - Run `execute()` registered App functions + - Node process (NodeJS technology equivalent) + - This is Electron framework `main process` component (NodeJS runtime) + - Jan provides core platform UI that: + - Allows App to `register()` function blueprint with name and arguments + - Run `execute()` registered App functions + - `@janhq/core` library that exposes Core API for App to reuse. Currently it only supports App `index.ts` + +- Vertically, there are `Platform Core` component and `App` component. Each of those includes UI and Node process that work in pair. + +## Events + +![Platform events](img/app-anatomy-4.drawio.jpg) + +#### onLaunch() + +![Platform onLaunch()](img/app-anatomy-1.drawio.jpg) + +#### onStart() + +![Platform onStart()](img/app-anatomy-2.drawio.jpg) + +#### onDispose() + +![Platform onDispose()](img/app-anatomy-3.drawio.jpg) + +#### onAppInstallation() and onAppUninstallation() + +The Platform simply restarts and trigger onDispose() then onLaunch(). + +### Information flow + +- When App is being used, here is how the information passes between Platform and Apps + ![Communication](img/app-anatomy-5.drawio.png) diff --git a/docs/docs/getting-started/build-an-app.md b/docs/docs/getting-started/build-an-app.md new file mode 100644 index 000000000..c8d29b315 --- /dev/null +++ b/docs/docs/getting-started/build-an-app.md @@ -0,0 +1,159 @@ +--- +sidebar_position: 1 +title: Build an app +--- + +# Build and publish an app + +You can build a custom AI application on top of Jan. +In this tutorial, you'll build a sample app and load it into Jan Desktop. + +## What you'll learn + +After you've completed this tutorial, you'll be able to: + +- Configure an environment for developing Jan apps. +- Compile a app from source code. +- Reload a app after making changes to it. + +## Prerequisites + +To complete this tutorial, you'll need: + +- [Git](https://git-scm.com/) installed on your local machine. +- A local development environment for [Node.js](https://node.js.org/en/about/). +- A code editor, such as [Visual Studio Code](https://code.visualstudio.com/). + +> When developing apps, one mistake can lead to unintended changes to your app. Please backup your data. + +## Development + +### Step 1: Download the sample app + +- Go to [Jan sample app](https://github.com/janhq/jan-sample-app) +- Select `Use this template button` at the top of the repository +- Select `Create a new repository` +- Select an owner and name for your new repository +- Click `Create repository` +- Git clone your new repository + +### Step 2: Installation + +> [!NOTE] +> +> You'll need to have a reasonably modern version of +> [Node.js](https://nodejs.org) handy. If you are using a version manager like +> [`nodenv`](https://github.com/nodenv/nodenv) or +> [`nvm`](https://github.com/nvm-sh/nvm), you can run `nodenv install` in the +> root of your repository to install the version specified in +> [`package.json`](./package.json). Otherwise, 20.x or later should work! + +1. :hammer_and_wrench: Install the dependencies + + ```bash + npm install + ``` + +1. :building_construction: Package the TypeScript for distribution + + ```bash + npm run bundle + ``` + +1. :white_check_mark: Check your artifact + + There will be a tgz file in your src directory now + +### Step 3: Update the App Manifest + +The [`package.json`](package.json) file lets you define your apps metadata, e.g. +app name, main entry, description and version. + +### Step 4: Implementation + +The [`src/`](./src/) directory is the heart of your app! You can replace the contents of this directory with your own code. + +- `index.ts` is your app's mainentrypoint. You can access the Web runtime and define UI in this file. +- `module.ts` is your Node runtime in which functions get executed. You should define core logic and compute-intensive workloads in this file. +- `index.ts` and `module.ts` interact with each other via RPC (See [Information flow](./app-anatomy.md#information-flow)) via [`invokePluginFunc`](../reference/01_init.md#invokepluginfunc) + +Import the Jan SDK + +```typescript +import { core } from "@janhq/core"; +``` + +#### index.ts + +Think of this as your "app frontend". You register events, custom functions here. + +Note: Most Jan app functions are processed asynchronously. In `index.ts`, you will see that the extension function will return a `Promise`. + +```typescript +import { core } from "@janhq/core"; + +function onStart(): Promise { + return core.invokePluginFunc(MODULE_PATH, "run", 0); +} +``` + +Define custom functions and register your implementation. + +```javascript +/** + * The entrypoint for the app. + */ + +import { PluginService, RegisterExtensionPoint, core } from "@janhq/core"; + +/** + * Invokes the `run` function from the `module.js` file using the `invokePluginFunc` method. + * "run" is the name of the function to invoke. + * @returns {Promise} A promise that resolves with the result of the `run` function. + */ +function onStart(): Promise { + return core.invokePluginFunc(MODULE_PATH, "run", 0); +} + +/** + * Initializes the plugin by registering the extension functions with the given register function. + * @param {Function} options.register - The function to use for registering the extension functions + */ +export function init({ register }: { register: RegisterExtensionPoint }) { + register(PluginService.OnStart, PLUGIN_NAME, onStart); +} +``` + +#### module.ts + +Think of this as your "app backend". Your core logic implementation goes here. + +```javascript +const path = require("path"); +const { app } = require("electron"); + +function run(param: number): [] { + console.log(`execute runner ${param} in main process`); + // Your code here + return []; +} + +module.exports = { + run, +}; +``` + +## App installation + +![Manual installation](img/build-app-1.png) + +- `Select` the built `*.tar.gz` file +- Jan will reload after new apps get installed + +## App uninstallation + +To be updated + +## App update + +To be updated diff --git a/docs/docs/getting-started/cloud-native.md b/docs/docs/getting-started/cloud-native.md new file mode 100644 index 000000000..7db615dfe --- /dev/null +++ b/docs/docs/getting-started/cloud-native.md @@ -0,0 +1,43 @@ +--- +sidebar_position: 5 +title: Cloud Native +--- + +Cloud Native is useful when you want to deploy Jan to a shared/remote/cloud server, rather than running it as a local Desktop app. + +> This is an experimental feature - expect breaking changes! + +### Getting Started + +#### Run from source code + +```bash +git clone https://github.com/janhq/jan +cd jan +git checkout feat-255 && git pull +yarn install +yarn start:server +``` + +Open your browser at [http://localhost:4000](http://localhost:4000) + +### Run from docker file + +```bash +git clone https://github.com/janhq/jan +cd jan +git checkout feat-255 && git pull +docker build --platform linux/x86_64 --progress=plain -t jan-server . +docker run --platform linux/x86_64 --name jan-server -p4000:4000 -p3928:3928 -it jan-server +``` + +Open your browser at [http://localhost:4000](http://localhost:4000) + +### Architecture + +![cloudnative](img/cloudnative.png) + +### TODOs + +- [Authencation Plugins](https://github.com/janhq/jan/issues/334) +- [Remote server](https://github.com/janhq/jan/issues/200) diff --git a/docs/docs/getting-started/img/app-anatomy-1.drawio.jpg b/docs/docs/getting-started/img/app-anatomy-1.drawio.jpg new file mode 100644 index 000000000..644acb43c Binary files /dev/null and b/docs/docs/getting-started/img/app-anatomy-1.drawio.jpg differ diff --git a/docs/docs/getting-started/img/app-anatomy-2.drawio.jpg b/docs/docs/getting-started/img/app-anatomy-2.drawio.jpg new file mode 100644 index 000000000..d8564cbc4 Binary files /dev/null and b/docs/docs/getting-started/img/app-anatomy-2.drawio.jpg differ diff --git a/docs/docs/getting-started/img/app-anatomy-3.drawio.jpg b/docs/docs/getting-started/img/app-anatomy-3.drawio.jpg new file mode 100644 index 000000000..4f2abcc7c Binary files /dev/null and b/docs/docs/getting-started/img/app-anatomy-3.drawio.jpg differ diff --git a/docs/docs/getting-started/img/app-anatomy-4.drawio.jpg b/docs/docs/getting-started/img/app-anatomy-4.drawio.jpg new file mode 100644 index 000000000..c0ca79cf1 Binary files /dev/null and b/docs/docs/getting-started/img/app-anatomy-4.drawio.jpg differ diff --git a/docs/docs/getting-started/img/app-anatomy-5.drawio.png b/docs/docs/getting-started/img/app-anatomy-5.drawio.png new file mode 100644 index 000000000..5caebb994 Binary files /dev/null and b/docs/docs/getting-started/img/app-anatomy-5.drawio.png differ diff --git a/docs/docs/getting-started/img/architecture-0.drawio.png b/docs/docs/getting-started/img/architecture-0.drawio.png new file mode 100644 index 000000000..55534a7e2 Binary files /dev/null and b/docs/docs/getting-started/img/architecture-0.drawio.png differ diff --git a/docs/docs/getting-started/img/architecture-1.drawio.png b/docs/docs/getting-started/img/architecture-1.drawio.png new file mode 100644 index 000000000..4897343b4 Binary files /dev/null and b/docs/docs/getting-started/img/architecture-1.drawio.png differ diff --git a/docs/docs/getting-started/img/architecture.png b/docs/docs/getting-started/img/architecture.png new file mode 100644 index 000000000..15ad4208c Binary files /dev/null and b/docs/docs/getting-started/img/architecture.png differ diff --git a/docs/docs/getting-started/img/build-app-1.png b/docs/docs/getting-started/img/build-app-1.png new file mode 100644 index 000000000..36538ce9c Binary files /dev/null and b/docs/docs/getting-started/img/build-app-1.png differ diff --git a/docs/docs/getting-started/img/cloudnative.png b/docs/docs/getting-started/img/cloudnative.png new file mode 100644 index 000000000..8d6268c39 Binary files /dev/null and b/docs/docs/getting-started/img/cloudnative.png differ diff --git a/docs/docs/getting-started/nitro.md b/docs/docs/getting-started/nitro.md new file mode 100644 index 000000000..e28035ae3 --- /dev/null +++ b/docs/docs/getting-started/nitro.md @@ -0,0 +1,76 @@ +--- +sidebar_position: 4 +title: Nitro (C++ Inference Engine) +--- + +Nitro, is the inference engine that powers Jan. Nitro is written in C++, optimized for edge deployment. + +⚡ Explore Nitro's codebase: [GitHub](https://github.com/janhq/nitro) + +## Dependencies and Acknowledgements: + +- [llama.cpp](https://github.com/ggerganov/llama.cpp): Nitro wraps Llama.cpp, which runs Llama models in C++ +- [drogon](https://github.com/drogonframework/drogon): Nitro runs Drogon, which is a fast, C++17/20 HTTP application framework. +- (Coming soon) tensorrt-llm support. + +## Features + +In addition to the above features, Nitro also provides: + +- OpenAI compatibility +- HTTP interface with no bindings needed +- Runs as a separate process, not interfering with main app processes +- Multi-threaded server supporting concurrent users +- 1-click install +- No hardware dedendencies +- Ships as a small binary (~3mb compressed on average) +- Runs on Windows, MacOS, and Linux +- Compatible with arm64, x86, and NVIDIA GPUs + +## HTTP Interface + +Nitro offers a straightforward HTTP interface. With compatibility for multiple standard APIs, including OpenAI formats. + +```bash +curl --location 'http://localhost:3928/inferences/llamacpp/chat_completion' \ + --header 'Content-Type: application/json' \ + --header 'Accept: text/event-stream' \ + --header 'Access-Control-Allow-Origin: *' \ + --data '{ + "messages": [ + {"content": "Hello there 👋", "role": "assistant"}, + {"content": "Can you write a long story", "role": "user"} + ], + "stream": true, + "model": "gpt-3.5-turbo", + "max_tokens": 2000 + }' +``` + +## Using Nitro + +**Step 1: Obtain Nitro**: +Access Nitro binaries from the release page. +🔗 [Download Nitro](https://github.com/janhq/nitro/releases) + +**Step 2: Source a Model**: +For those interested in the llama C++ integration, obtain a "GGUF" model from The Bloke's repository. +🔗 [Download Model](https://huggingface.co/TheBloke) + +**Step 3: Initialize Nitro**: +Launch Nitro and position your model using the following API call: + +```bash +curl -X POST 'http://localhost:3928/inferences/llamacpp/loadmodel' \ + -H 'Content-Type: application/json' \ + -d '{ + "llama_model_path": "/path/to/your_model.gguf", + "ctx_len": 2048, + "ngl": 100, + "embedding": true + }' +``` + +## Architecture diagram + +![Nitro Architecture](img/architecture.png) diff --git a/docs/docs/getting-started/publish-jan-app.md b/docs/docs/getting-started/publish-jan-app.md new file mode 100644 index 000000000..cc8fab010 --- /dev/null +++ b/docs/docs/getting-started/publish-jan-app.md @@ -0,0 +1,12 @@ +--- +sidebar_position: 3 +title: Publishing an app +--- + +After you have completed with local app development and want to publish to `Jan marketplace` for other to reuse, please follow the following steps + +- Step 1: Update your local `package.json` and configure `npm login` correctly +- Step 2: Run `npm publish` and set to public NPM package (so that other can install) - Please refer to our example [NPM retrieval plugin](https://www.npmjs.com/package/retrieval-plugin) +- Step 3: Go to `Jan plugin catalog`(https://github.com/janhq/plugin-catalog) and create a `Pull request` for new `App artifact` (which is a renamed version of your App `package.json`) - Please refer to example [retrieval-plugin](https://github.com/janhq/plugin-catalog/blob/main/retrieval-plugin.json) +- Step 4: We at Jan will be responsible to review and merge to `main` +- Step 5: Once your new app is on `main`, you and other Jan users can find it in `Jan marketplace` diff --git a/docs/docs/guides/concepts.md b/docs/docs/guides/concepts.md new file mode 100644 index 000000000..5edf9c128 --- /dev/null +++ b/docs/docs/guides/concepts.md @@ -0,0 +1,11 @@ +--- +title: Concepts +--- + +## Concepts + +- Jan Platform: Desktop app/ Cloud native SaaS that can run on Linux, Windows, Mac or even Server that comes with extensibilities, toolbox and state of the art but optimized models for next gen App. +- Jan App: Next gen App built on Jan Plaform as `portable intelligence` that can be run everywhere. +- Models: + - LLM models + - Other models diff --git a/docs/docs/docs/install/linux.md b/docs/docs/guides/linux.md similarity index 100% rename from docs/docs/docs/install/linux.md rename to docs/docs/guides/linux.md diff --git a/docs/docs/guides/mac.md b/docs/docs/guides/mac.md new file mode 100644 index 000000000..315c3bf68 --- /dev/null +++ b/docs/docs/guides/mac.md @@ -0,0 +1,3 @@ +--- +title: Installing Jan on Mac +--- \ No newline at end of file diff --git a/docs/docs/guides/troubleshooting.md b/docs/docs/guides/troubleshooting.md new file mode 100644 index 000000000..9662ac078 --- /dev/null +++ b/docs/docs/guides/troubleshooting.md @@ -0,0 +1,3 @@ +--- +title: Troubleshooting +--- diff --git a/docs/docs/guides/windows.md b/docs/docs/guides/windows.md new file mode 100644 index 000000000..18c61a4fb --- /dev/null +++ b/docs/docs/guides/windows.md @@ -0,0 +1,3 @@ +--- +title: Installing Jan on Windows +--- \ No newline at end of file diff --git a/docs/docs/platform/platform.md b/docs/docs/platform/platform.md deleted file mode 100644 index 11531572e..000000000 --- a/docs/docs/platform/platform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 1 -title: Overview -slug: /platform ---- diff --git a/docs/docs/products/desktop.md b/docs/docs/products/desktop.md deleted file mode 100644 index 302e25a92..000000000 --- a/docs/docs/products/desktop.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Jan Desktop ---- \ No newline at end of file diff --git a/docs/docs/products/mobile.md b/docs/docs/products/mobile.md deleted file mode 100644 index dd84f9c0b..000000000 --- a/docs/docs/products/mobile.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Jan Mobile ---- \ No newline at end of file diff --git a/docs/docs/products/products.md b/docs/docs/products/products.md deleted file mode 100644 index c95072f26..000000000 --- a/docs/docs/products/products.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Products -slug: /product ---- \ No newline at end of file diff --git a/docs/docs/products/server.md b/docs/docs/products/server.md deleted file mode 100644 index 0ce36871a..000000000 --- a/docs/docs/products/server.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Jan Server ---- \ No newline at end of file diff --git a/docs/docs/reference/01_init.md b/docs/docs/reference/01_init.md new file mode 100644 index 000000000..ad1acc956 --- /dev/null +++ b/docs/docs/reference/01_init.md @@ -0,0 +1,74 @@ +--- +title: "init" +--- + +`init` is the entrypoint for your application and its custom logic. `init` is a reserved function that Jan will look for to initialize your application. + +## Usage + +Importing + +```js +// javascript +const core = require("@janhq/core"); + +// typescript +import * as core from "@janhq/core"; +``` + +Setting up event listeners + +```js +export function init({ register }) { + myListener(); +} +``` + +Setting up core service implementation + +```js +export function init({ register }: { register: RegisterExtensionPoint }) { + register(DataService.GetConversations, "my-app-id", myImplementation); +} +``` + +## RegisterExtensionPoint + +`RegisterExtensionPoint` is used for app initialization. + +It lets you register `CoreService` functions/methods with the main application. + +```js +import { RegisterExtensionPoint } from "@janhq/core"; +``` + +```js +type RegisterExtensionPoint = ( + extensionName: string, + extensionId: string, + method: Function, + priority?: number +) +``` + +## invokePluginFunc + +`invokePluginFunc` is a way to invoke your custom functions (defined in your `module.ts`) from your application client (defined in your `index.ts`) + +```js +// index.ts: your application "frontend" and entrypoint +function foo(id: number) { + return core.invokePluginFunc(MODULE_PATH, "foo", param1, ...); +} + +export function init({ register }: { register: RegisterExtensionPoint }) { + register(Service.Foo, "my-app-id", foo); +} +``` + +```js +// module.ts: your application "backend" +export function foo(param1, ...) { + // Your code here +} +``` diff --git a/docs/docs/reference/02_coreservice.md b/docs/docs/reference/02_coreservice.md new file mode 100644 index 000000000..d9b0a80c7 --- /dev/null +++ b/docs/docs/reference/02_coreservice.md @@ -0,0 +1,94 @@ +--- +title: "CoreService" +--- + +`CoreService` provides an interface for implementing custom methods in Jan. +It lets you define shared behavior across your custom application, like how your app handles state, models, or inferencing behavior. + +## Usage + +```js +import { CoreService, ... } from "@janhq/core"; +``` + +## CoreService + +The `CoreService` type bundles the following services: + +- `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. diff --git a/docs/docs/reference/03_events.md b/docs/docs/reference/03_events.md new file mode 100644 index 000000000..0e0c8104d --- /dev/null +++ b/docs/docs/reference/03_events.md @@ -0,0 +1,85 @@ +--- +title: "events" +--- + +`events` lets you receive events about actions that take place in the app, like when a user sends a new message. + +You can then implement custom logic handlers for such events. + +## Usage + +```js +import { events } from "@janhq/core"; +``` + +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) +} +``` + +## EventName + +The `EventName` enum bundles the following events: + +- `OnNewConversation` +- `OnNewMessageRequest` +- `OnNewMessageResponse` +- `OnMessageResponseUpdate` +- `OnDownloadUpdate` +- `OnDownloadSuccess` +- `OnDownloadError` + +## event.on + +Adds an observer for an event. + +```js +const on: (eventName: string, handler: Function) => void = (eventName, handler); +``` + +## event.emit + +Emits an event. + +```js +const emit: (eventName: string, object: any) => void = (eventName, object); +``` + +## event.off + +Removes an observer for an event. + +```js +const off: (eventName: string, handler: Function) => void = + (eventName, handler); +``` diff --git a/docs/docs/reference/04_store.md b/docs/docs/reference/04_store.md new file mode 100644 index 000000000..5da2ee15a --- /dev/null +++ b/docs/docs/reference/04_store.md @@ -0,0 +1,76 @@ +--- +title: "store" +--- + +`store` is a helper object for working with Jan app's local storage database. + +By default, Jan ships with a [pouchDB](https://pouchdb.com/) client side noSQL db to persist usage state. + +_Note: default `store` logic is from [@data-plugin](https://www.npmjs.com/package/@janhq/data-plugin) which implements `StoreService`._ + +## Usage + +```js +import { store } from "@janhq/core"; +``` + +## 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. +} +``` diff --git a/docs/docs/reference/05_filesystem.md b/docs/docs/reference/05_filesystem.md new file mode 100644 index 000000000..baa1fa30a --- /dev/null +++ b/docs/docs/reference/05_filesystem.md @@ -0,0 +1,35 @@ +--- +title: "filesystem" +--- + +The core package also provides functions to perform file operations. Here are a couple of examples: + +## Usage + +```js +// javascript +const core = require("@janhq/core"); + +// typescript +import * as core from "@janhq/core"; +``` + +## 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) { + core.downloadFile(url, fileName); +} +``` + +## 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); +} +``` diff --git a/docs/docs/reference/06_preferences.md b/docs/docs/reference/06_preferences.md new file mode 100644 index 000000000..15e72e57d --- /dev/null +++ b/docs/docs/reference/06_preferences.md @@ -0,0 +1,59 @@ +--- +title: "preferences" +--- + +`preferences` is a helper object for adding settings fields to your app. + +## Usage + +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)) ?? ""; +}; +``` + +## registerPreferences + +## get + +## set + +## clear diff --git a/docs/docs/solutions/industries/education.md b/docs/docs/solutions/industries/education.md deleted file mode 100644 index 8f8b9a0a1..000000000 --- a/docs/docs/solutions/industries/education.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Education ---- \ No newline at end of file diff --git a/docs/docs/solutions/industries/finance.md b/docs/docs/solutions/industries/finance.md deleted file mode 100644 index 55663a756..000000000 --- a/docs/docs/solutions/industries/finance.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Finance ---- \ No newline at end of file diff --git a/docs/docs/solutions/industries/healthcare.md b/docs/docs/solutions/industries/healthcare.md deleted file mode 100644 index 368cefa52..000000000 --- a/docs/docs/solutions/industries/healthcare.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Healthcare ---- \ No newline at end of file diff --git a/docs/docs/solutions/industries/law.md b/docs/docs/solutions/industries/law.md deleted file mode 100644 index 772ec3739..000000000 --- a/docs/docs/solutions/industries/law.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Law ---- \ No newline at end of file diff --git a/docs/docs/solutions/industries/public-sector.md b/docs/docs/solutions/industries/public-sector.md deleted file mode 100644 index aec5dd5be..000000000 --- a/docs/docs/solutions/industries/public-sector.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Public Sector ---- \ No newline at end of file diff --git a/docs/docs/solutions/industries/software.md b/docs/docs/solutions/industries/software.md deleted file mode 100644 index 4afbce7e8..000000000 --- a/docs/docs/solutions/industries/software.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Software Engineering ---- \ No newline at end of file diff --git a/docs/docs/solutions/personal-ai.md b/docs/docs/solutions/personal-ai.md deleted file mode 100644 index f4d6dc387..000000000 --- a/docs/docs/solutions/personal-ai.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Personal AI ---- \ No newline at end of file diff --git a/docs/docs/solutions/self-hosted.md b/docs/docs/solutions/self-hosted.md deleted file mode 100644 index 227b09923..000000000 --- a/docs/docs/solutions/self-hosted.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Self-Hosted ChatGPT ---- \ No newline at end of file diff --git a/docs/docs/solutions/solutions.md b/docs/docs/solutions/solutions.md deleted file mode 100644 index 5cbb047a4..000000000 --- a/docs/docs/solutions/solutions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Overview -slug: /solutions ---- \ No newline at end of file diff --git a/docs/docs/tutorials/build-chat-app.md b/docs/docs/tutorials/build-chat-app.md new file mode 100644 index 000000000..5ab6eec6b --- /dev/null +++ b/docs/docs/tutorials/build-chat-app.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +title: Building a chat app +--- + +TODO diff --git a/docs/docs/tutorials/build-rag-app.md b/docs/docs/tutorials/build-rag-app.md new file mode 100644 index 000000000..a5b54c5f2 --- /dev/null +++ b/docs/docs/tutorials/build-rag-app.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 2 +title: Building a RAG app +--- + +TODO diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 8ffebf68b..f9f0eb6dc 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -117,19 +117,13 @@ const config = { src: "img/logo.svg", }, items: [ - // Navbar Top + // Navbar left // { // type: "docSidebar", // sidebarId: "featuresSidebar", // position: "left", // label: "Platform", // }, - // { - // type: "docSidebar", - // sidebarId: "solutionsSidebar", - // position: "left", - // label: "Solutions", - // }, { type: "docSidebar", sidebarId: "companySidebar", @@ -137,28 +131,18 @@ const config = { label: "Company", }, // Navbar right - // { - // type: "docSidebar", - // sidebarId: "docsSidebar", - // position: "right", - // label: "Docs", - // }, - // { - // type: "docSidebar", - // sidebarId: "hardwareSidebar", - // position: "right", - // label: "Hardware", - // }, - // { - // position: "right", - // label: "API", - // to: "/api", - // }, - // { - // href: "https://github.com/janhq/jan", - // label: "GitHub", - // position: "right", - // }, + { + type: "docSidebar", + sidebarId: "guidesSidebar", + position: "right", + label: "User Guides", + }, + { + type: "docSidebar", + sidebarId: "devSidebar", + position: "right", + label: "Developer", + }, ], }, prism: { diff --git a/docs/sidebars.js b/docs/sidebars.js index 7dc7ab662..cd5f7721b 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -4,7 +4,7 @@ - render a sidebar for each doc of that group - provide next/previous navigation - The sidebars can be generated from the filesystem, or explicitly defined here. + The sidebars are explicitly defined here. Create as many sidebars as you want. */ @@ -13,19 +13,7 @@ /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { - // By default, Docusaurus generates a sidebar from the docs folder structure - - // But you can create a sidebar manually featuresSidebar: [ - "platform/platform", - { - type: "category", - label: "Products", - collapsible: true, - collapsed: false, - link: { type: "doc", id: "products/products" }, - items: ["products/desktop", "products/mobile", "products/server"], - }, { type: "category", label: "Features", @@ -41,154 +29,87 @@ const sidebars = { }, ], - // Note: Tab name is "Use Cases" - solutionsSidebar: [ - // "solutions/solutions", + // Autogenerate docs from /guides + guidesSidebar: [ { type: "category", - label: "Solutions", - collapsible: true, - collapsed: false, - items: ["solutions/self-hosted", "solutions/personal-ai"], - }, - // { - // type: "category", - // label: "Industries", - // collapsible: true, - // collapsed: false, - // items: [ - // "solutions/industries/software", - // "solutions/industries/education", - // "solutions/industries/law", - // "solutions/industries/public-sector", - // "solutions/industries/finance", - // "solutions/industries/healthcare", - // ], - // }, - ], - - docsSidebar: [ - { type: "doc", label: "Getting Started", id: "docs/docs" }, - { - type: "category", - label: "Install", - collapsible: true, - collapsed: false, - items: [ - { type: "doc", label: "Windows", id: "docs/install/windows" }, - { type: "doc", label: "Mac", id: "docs/install/mac" }, - { type: "doc", label: "Linux", id: "docs/install/linux" }, - ], - }, - ], - - hardwareSidebar: [ - // { - // type: "category", - // label: "Overview", - // collapsible: true, - // collapsed: true, - // link: { type: "doc", id: "hardware/hardware" }, - // items: [ - // { - // type: "doc", - // label: "Cloud vs. Self-Hosting", - // id: "hardware/overview/cloud-vs-self-hosting", - // }, - // { - // type: "doc", - // label: "CPUs vs. GPUs", - // id: "hardware/overview/cpu-vs-gpu", - // }, - // ], - // }, - // { - // type: "category", - // label: "Recommendations", - // collapsible: true, - // collapsed: false, - // items: [ - // { - // type: "doc", - // label: "By Hardware", - // id: "hardware/recommendations/by-hardware", - // }, - // { - // type: "doc", - // label: "By Budget", - // id: "hardware/recommendations/by-budget", - // }, - // { - // type: "doc", - // label: "By Model", - // id: "hardware/recommendations/by-model", - // }, - // { - // type: "doc", - // label: "By Use Case", - // id: "hardware/recommendations/by-usecase", - // }, - // ], - // }, - // { - // type: "category", - // label: "Anatomy of a Thinking Machine", - // collapsible: true, - // collapsed: true, - // link: { type: "doc", id: "hardware/concepts/concepts" }, - // items: [ - // { - // type: "doc", - // label: "Chassis", - // id: "hardware/concepts/chassis", - // }, - // { - // type: "doc", - // label: "Motherboard", - // id: "hardware/concepts/motherboard", - // }, - // { - // type: "doc", - // label: "CPU and RAM", - // id: "hardware/concepts/cpu-and-ram", - // }, - // { - // type: "doc", - // label: "GPU and VRAM", - // id: "hardware/concepts/gpu-and-vram", - // }, - // { - // type: "doc", - // label: "Storage", - // id: "hardware/concepts/storage", - // }, - // { - // type: "doc", - // label: "Network", - // id: "hardware/concepts/network", - // }, - - // { - // type: "doc", - // label: "Power Supply", - // id: "hardware/concepts/power", - // }, - // ], - // }, - { - type: "category", - label: "Hardware Examples", + label: "Guides", collapsible: true, collapsed: true, - link: { type: "doc", id: "hardware/community" }, items: [ { type: "autogenerated", - dirName: "hardware/examples", + dirName: "guides", }, ], }, ], + + // + devSidebar: [ + { + type: "category", + label: "Getting Started", + collapsible: true, + collapsed: false, + items: [ + { + type: "autogenerated", + dirName: "getting-started", + }, + ], + }, + { + type: "category", + label: "Reference", + collapsible: true, + collapsed: false, + items: [ + { + type: "autogenerated", + dirName: "reference", + }, + ], + }, + { + type: "category", + label: "Apps (Plugins)", + collapsible: true, + collapsed: true, + items: [ + { + type: "autogenerated", + dirName: "apps", + }, + ], + }, + // { + // type: "category", + // label: "Tutorials", + // collapsible: true, + // collapsed: false, + // items: [ + // { + // type: "autogenerated", + // dirName: "tutorials", + // }, + // ], + // }, + // { + // type: "category", + // label: "Articles", + // collapsible: true, + // collapsed: false, + // items: [ + // { + // type: "doc", + // label: "Nitro", + // id: "articles/nitro", + // }, + // ], + // }, + ], + companySidebar: [ // { // type: "category", diff --git a/docs/src/styles/base.scss b/docs/src/styles/base.scss index 6de9a10fd..fb6388922 100644 --- a/docs/src/styles/base.scss +++ b/docs/src/styles/base.scss @@ -30,7 +30,7 @@ @apply text-sm; @apply antialiased; @apply bg-white dark:bg-black; - @apply text-gray-700 dark:text-gray-500; + @apply text-gray-700 dark:text-gray-400; } img { pointer-events: none; diff --git a/docs/src/styles/tweaks.scss b/docs/src/styles/tweaks.scss index 3b5e425e3..14ec842a9 100644 --- a/docs/src/styles/tweaks.scss +++ b/docs/src/styles/tweaks.scss @@ -84,4 +84,17 @@ a { @apply text-blue-600 dark:text-blue-400; } + ul { + list-style: revert; + } + ol { + list-style: decimal; + } + ul, + ol { + padding-left: 16px; + li { + @apply leading-loose; + } + } } diff --git a/plugins/data-plugin/package.json b/plugins/data-plugin/package.json index 995d88a6c..8ac3136f4 100644 --- a/plugins/data-plugin/package.json +++ b/plugins/data-plugin/package.json @@ -47,4 +47,4 @@ "pouchdb-node", "pouchdb-find" ] -} +} \ No newline at end of file