diff --git a/.github/workflows/jan-electron-linter-and-test.yml b/.github/workflows/jan-electron-linter-and-test.yml index 96258e709..55c3308da 100644 --- a/.github/workflows/jan-electron-linter-and-test.yml +++ b/.github/workflows/jan-electron-linter-and-test.yml @@ -22,6 +22,7 @@ on: branches: - main - dev + - release/** paths: - "electron/**" - .github/workflows/jan-electron-linter-and-test.yml diff --git a/README.md b/README.md index 0db57d808..8c3ff307b 100644 --- a/README.md +++ b/README.md @@ -43,31 +43,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute Stable (Recommended) - + jan.exe - + Intel - + M1/M2 - + jan.deb - + jan.AppImage @@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute Experimental (Nightly Build) - + jan.exe - + Intel - + M1/M2 - + jan.deb - + jan.AppImage @@ -327,6 +327,7 @@ Jan builds on top of other open-source projects: - [llama.cpp](https://github.com/ggerganov/llama.cpp) - [LangChain](https://github.com/langchain-ai) - [TensorRT](https://github.com/NVIDIA/TensorRT) +- [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM) ## Contact diff --git a/core/package.json b/core/package.json index 2f4f6b576..c4d0d475d 100644 --- a/core/package.json +++ b/core/package.json @@ -46,7 +46,7 @@ }, "devDependencies": { "@types/jest": "^29.5.12", - "@types/node": "^12.0.2", + "@types/node": "^20.11.4", "eslint": "8.57.0", "eslint-plugin-jest": "^27.9.0", "jest": "^29.7.0", diff --git a/core/src/api/index.ts b/core/src/api/index.ts index f97593934..8e41da0d1 100644 --- a/core/src/api/index.ts +++ b/core/src/api/index.ts @@ -33,7 +33,7 @@ export enum AppRoute { stopServer = 'stopServer', log = 'log', logServer = 'logServer', - systemInformations = 'systemInformations', + systemInformation = 'systemInformation', showToast = 'showToast', } @@ -95,6 +95,8 @@ export enum FileManagerRoute { getUserHomePath = 'getUserHomePath', fileStat = 'fileStat', writeBlob = 'writeBlob', + mkdir = 'mkdir', + rm = 'rm', } export type ApiFunction = (...args: any[]) => any diff --git a/core/src/core.ts b/core/src/core.ts index b8cbd3162..47c0fe6f2 100644 --- a/core/src/core.ts +++ b/core/src/core.ts @@ -1,4 +1,4 @@ -import { DownloadRequest, FileStat, NetworkConfig } from './types' +import { DownloadRequest, FileStat, NetworkConfig, SystemInformation } from './types' /** * Execute a extension module function in main process @@ -110,7 +110,8 @@ const isSubdirectory: (from: string, to: string) => Promise = (from: st * Get system information * @returns {Promise} - A promise that resolves with the system information. */ -const systemInformations: () => Promise = () => global.core.api?.systemInformations() +const systemInformation: () => Promise = () => + global.core.api?.systemInformation() /** * Show toast message from browser processes. @@ -146,7 +147,7 @@ export { log, isSubdirectory, getUserHomePath, - systemInformations, + systemInformation, showToast, FileStat, } diff --git a/core/src/extension.ts b/core/src/extension.ts index 22accb4b4..973d4778a 100644 --- a/core/src/extension.ts +++ b/core/src/extension.ts @@ -19,6 +19,7 @@ export interface Compatibility { const ALL_INSTALLATION_STATE = [ 'NotRequired', // not required. 'Installed', // require and installed. Good to go. + 'Updatable', // require and installed but need to be updated. 'NotInstalled', // require to be installed. 'Corrupted', // require but corrupted. Need to redownload. ] as const @@ -59,6 +60,13 @@ export abstract class BaseExtension implements ExtensionType { return undefined } + /** + * Determine if the extension is updatable. + */ + updatable(): boolean { + return false + } + /** * Determine if the prerequisites for the extension are installed. * diff --git a/core/src/extensions/ai-engines/LocalOAIEngine.ts b/core/src/extensions/ai-engines/LocalOAIEngine.ts index 79dbcbf5e..89444ff0f 100644 --- a/core/src/extensions/ai-engines/LocalOAIEngine.ts +++ b/core/src/extensions/ai-engines/LocalOAIEngine.ts @@ -1,4 +1,4 @@ -import { executeOnMain, getJanDataFolderPath, joinPath } from '../../core' +import { executeOnMain, getJanDataFolderPath, joinPath, systemInformation } from '../../core' import { events } from '../../events' import { Model, ModelEvent } from '../../types' import { OAIEngine } from './OAIEngine' @@ -30,11 +30,11 @@ export abstract class LocalOAIEngine extends OAIEngine { if (model.engine.toString() !== this.provider) return const modelFolder = await joinPath([await getJanDataFolderPath(), this.modelFolder, model.id]) - + const systemInfo = await systemInformation() const res = await executeOnMain(this.nodeModule, this.loadModelFunctionName, { modelFolder, model, - }) + }, systemInfo) if (res?.error) { events.emit(ModelEvent.OnModelFail, { diff --git a/core/src/extensions/monitoring.ts b/core/src/extensions/monitoring.ts index 8d61580fc..2d75e0218 100644 --- a/core/src/extensions/monitoring.ts +++ b/core/src/extensions/monitoring.ts @@ -1,5 +1,5 @@ import { BaseExtension, ExtensionTypeEnum } from '../extension' -import { GpuSetting, MonitoringInterface } from '../index' +import { GpuSetting, MonitoringInterface, OperatingSystemInfo } from '../index' /** * Monitoring extension for system monitoring. @@ -16,4 +16,5 @@ export abstract class MonitoringExtension extends BaseExtension implements Monit abstract getGpuSetting(): Promise abstract getResourcesInfo(): Promise abstract getCurrentLoad(): Promise + abstract getOsInfo(): Promise } diff --git a/core/src/fs.ts b/core/src/fs.ts index 71538ae9c..dacdbb6d6 100644 --- a/core/src/fs.ts +++ b/core/src/fs.ts @@ -37,12 +37,17 @@ const readdirSync = (...args: any[]) => global.core.api?.readdirSync(...args) */ const mkdirSync = (...args: any[]) => global.core.api?.mkdirSync(...args) +const mkdir = (...args: any[]) => global.core.api?.mkdir(...args) + /** * Removes a directory at the specified path. * @returns {Promise} A Promise that resolves when the directory is removed successfully. */ const rmdirSync = (...args: any[]) => global.core.api?.rmdirSync(...args, { recursive: true, force: true }) + +const rm = (path: string) => global.core.api?.rm(path) + /** * Deletes a file from the local file system. * @param {string} path - The path of the file to delete. @@ -92,7 +97,9 @@ export const fs = { existsSync, readdirSync, mkdirSync, + mkdir, rmdirSync, + rm, unlinkSync, appendFileSync, copyFileSync, diff --git a/core/src/node/api/processors/fsExt.ts b/core/src/node/api/processors/fsExt.ts index 4787da65b..9b88cfef9 100644 --- a/core/src/node/api/processors/fsExt.ts +++ b/core/src/node/api/processors/fsExt.ts @@ -88,4 +88,28 @@ export class FSExt implements Processor { }) }) } + + mkdir(path: string): Promise { + return new Promise((resolve, reject) => { + fs.mkdir(path, { recursive: true }, (err) => { + if (err) { + reject(err) + } else { + resolve() + } + }) + }) + } + + rmdir(path: string): Promise { + return new Promise((resolve, reject) => { + fs.rm(path, { recursive: true }, (err) => { + if (err) { + reject(err) + } else { + resolve() + } + }) + }) + } } diff --git a/core/src/node/extension/store.ts b/core/src/node/extension/store.ts index 93b1aeb2b..630756485 100644 --- a/core/src/node/extension/store.ts +++ b/core/src/node/extension/store.ts @@ -93,8 +93,7 @@ export function persistExtensions() { */ export async function installExtensions(extensions: any) { const installed: Extension[] = [] - for (const ext of extensions) { - // Set install options and activation based on input type + const installations = extensions.map((ext: any): Promise => { const isObject = typeof ext === 'object' const spec = isObject ? [ext.specifier, ext] : [ext] const activate = isObject ? ext.activate !== false : true @@ -102,15 +101,17 @@ export async function installExtensions(extensions: any) { // Install and possibly activate extension const extension = new Extension(...spec) if (!extension.origin) { - continue + return Promise.resolve() } - await extension._install() - if (activate) extension.setActive(true) + return extension._install().then(() => { + if (activate) extension.setActive(true) + // Add extension to store if needed + addExtension(extension) + installed.push(extension) + }) + }) - // Add extension to store if needed - addExtension(extension) - installed.push(extension) - } + await Promise.all(installations) // Return list of all installed extensions return installed diff --git a/core/src/node/helper/config.ts b/core/src/node/helper/config.ts index 81bc64611..b5ec2e029 100644 --- a/core/src/node/helper/config.ts +++ b/core/src/node/helper/config.ts @@ -82,26 +82,34 @@ export const getJanExtensionsPath = (): string => { */ export const physicalCpuCount = async (): Promise => { const platform = os.platform() - if (platform === 'linux') { - const output = await exec('lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l') - return parseInt(output.trim(), 10) - } else if (platform === 'darwin') { - const output = await exec('sysctl -n hw.physicalcpu_max') - return parseInt(output.trim(), 10) - } else if (platform === 'win32') { - const output = await exec('WMIC CPU Get NumberOfCores') - return output - .split(os.EOL) - .map((line: string) => parseInt(line)) - .filter((value: number) => !isNaN(value)) - .reduce((sum: number, number: number) => sum + number, 1) - } else { - const cores = os.cpus().filter((cpu: any, index: number) => { - const hasHyperthreading = cpu.model.includes('Intel') - const isOdd = index % 2 === 1 - return !hasHyperthreading || isOdd - }) - return cores.length + try { + if (platform === 'linux') { + const output = await exec('lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l') + return parseInt(output.trim(), 10) + } else if (platform === 'darwin') { + const output = await exec('sysctl -n hw.physicalcpu_max') + return parseInt(output.trim(), 10) + } else if (platform === 'win32') { + const output = await exec('WMIC CPU Get NumberOfCores') + return output + .split(os.EOL) + .map((line: string) => parseInt(line)) + .filter((value: number) => !isNaN(value)) + .reduce((sum: number, number: number) => sum + number, 1) + } else { + const cores = os.cpus().filter((cpu: any, index: number) => { + const hasHyperthreading = cpu.model.includes('Intel') + const isOdd = index % 2 === 1 + return !hasHyperthreading || isOdd + }) + return cores.length + } + } catch (err) { + console.warn('Failed to get physical CPU count', err) + // Divide by 2 to get rid of hyper threading + const coreCount = Math.ceil(os.cpus().length / 2) + console.debug('Using node API to get physical CPU count:', coreCount) + return coreCount } } diff --git a/core/src/node/helper/resource.ts b/core/src/node/helper/resource.ts index c79a63688..faaaace05 100644 --- a/core/src/node/helper/resource.ts +++ b/core/src/node/helper/resource.ts @@ -1,6 +1,6 @@ import { SystemResourceInfo } from '../../types' import { physicalCpuCount } from './config' -import { log, logServer } from './log' +import { log } from './log' export const getSystemResourceInfo = async (): Promise => { const cpu = await physicalCpuCount() diff --git a/core/src/types/miscellaneous/systemResourceInfo.ts b/core/src/types/miscellaneous/systemResourceInfo.ts index f7dd4a82b..fb059b1ba 100644 --- a/core/src/types/miscellaneous/systemResourceInfo.ts +++ b/core/src/types/miscellaneous/systemResourceInfo.ts @@ -30,3 +30,27 @@ export type GpuSettingInfo = { name: string arch?: string } + +export type SystemInformation = { + gpuSetting: GpuSetting + osInfo?: OperatingSystemInfo +} + +export const SupportedPlatforms = ['win32', 'linux', 'darwin'] as const +export type SupportedPlatformTuple = typeof SupportedPlatforms +export type SupportedPlatform = SupportedPlatformTuple[number] + +export type OperatingSystemInfo = { + platform: SupportedPlatform | 'unknown' + arch: string + release: string + machine: string + version: string + totalMem: number + freeMem: number +} + +export type CpuCoreInfo = { + model: string + speed: number +} diff --git a/docs/.env.example b/docs/.env.example index 22f6e715f..56b26dafb 100644 --- a/docs/.env.example +++ b/docs/.env.example @@ -3,4 +3,5 @@ UMAMI_PROJECT_API_KEY=xxxx UMAMI_APP_URL=xxxx ALGOLIA_API_KEY=xxxx ALGOLIA_APP_ID=xxxx -GITHUB_ACCESS_TOKEN=xxxx \ No newline at end of file +GITHUB_ACCESS_TOKEN=xxxx +API_KEY_BREVO=xxxx \ No newline at end of file diff --git a/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx b/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx index ef418ff97..6c208764d 100644 --- a/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx +++ b/docs/blog/01-january-10-2024-bitdefender-false-positive-flag.mdx @@ -5,6 +5,21 @@ slug: /postmortems/january-10-2024-bitdefender-false-positive-flag tags: [Postmortem] --- + + Jan 10, 2024 Incident Postmortem - Bitdefender False Positive Flag on Jan AI Resolved + + + + + + + + + + + + + Following the recent incident related to Jan version 0.4.4 triggering Bitdefender on Windows with Gen:Variant.Tedy.258323 on January 10, 2024, we wanted to provide a comprehensive postmortem and outline the necessary follow-up actions. ## Incident Overview diff --git a/docs/docs/about/2035.mdx b/docs/docs/about/2035.mdx index 3af7a3197..2806e7ade 100644 --- a/docs/docs/about/2035.mdx +++ b/docs/docs/about/2035.mdx @@ -2,6 +2,20 @@ title: Jan's Vision for 2035 --- + + Jan's Vision for 2035 + + + + + + + + + + + + [Jan 2035: A Robotics Company](https://hackmd.io/QIWyYbNNQVWVbupuI3kjAA) We only have 2 planning parameters: diff --git a/docs/docs/about/about.md b/docs/docs/about/about.md index a047ab910..32f4a3e4f 100644 --- a/docs/docs/about/about.md +++ b/docs/docs/about/about.md @@ -18,6 +18,20 @@ keywords: ] --- + + About Jan + + + + + + + + + + + + Jan turns computers into thinking machines to change how we use them. Jan is created and maintained by Jan Labs, a robotics company. diff --git a/docs/docs/about/faq.md b/docs/docs/about/faq.md index 29832e211..b4e05b3a6 100644 --- a/docs/docs/about/faq.md +++ b/docs/docs/about/faq.md @@ -1,3 +1,21 @@ +--- +title: Frequently Asked Questions (FAQ) - Jan +--- + + + Frequently Asked Questions (FAQ) + + + + + + + + + + + + # Frequently Asked Questions (FAQ) ## What is Jan? diff --git a/docs/docs/about/roadmap.md b/docs/docs/about/roadmap.md index 1c789d733..d818aa647 100644 --- a/docs/docs/about/roadmap.md +++ b/docs/docs/about/roadmap.md @@ -2,5 +2,19 @@ title: Roadmap --- + + Roadmap + + + + + + + + + + + + - [ ] [Immediate Roadmap on Github](https://github.com/orgs/janhq/projects/5/views/16) -- [ ] [Longer-term Roadmap on Discord](https://discord.gg/Ey62mynnYr) \ No newline at end of file +- [ ] [Longer-term Roadmap on Discord](https://discord.gg/Ey62mynnYr) diff --git a/docs/docs/acknowledgements.md b/docs/docs/acknowledgements.md index c68c4ed86..46418fc79 100644 --- a/docs/docs/acknowledgements.md +++ b/docs/docs/acknowledgements.md @@ -17,6 +17,17 @@ keywords: ] --- + + + + + + + + + + + # Acknowledgements We would like to express our gratitude to the following third-party libraries that have made the development of Jan possible. @@ -24,3 +35,4 @@ We would like to express our gratitude to the following third-party libraries th - [llama.cpp](https://github.com/ggerganov/llama.cpp/blob/master/LICENSE) - [LangChain.js](https://github.com/langchain-ai/langchainjs/blob/main/LICENSE) - [TensorRT](https://github.com/NVIDIA/TensorRT/blob/main/LICENSE) +- [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM/blob/main/LICENSE) diff --git a/docs/docs/community/community.mdx b/docs/docs/community/community.mdx index d4866490e..7c5ad9367 100644 --- a/docs/docs/community/community.mdx +++ b/docs/docs/community/community.mdx @@ -15,6 +15,20 @@ keywords: ] --- + + Jan's Community + + + + + + + + + + + + ## Socials - [Discord](https://discord.gg/SH3DGmUs6b) diff --git a/docs/docs/developer/01-overview/01-architecture.md b/docs/docs/developer/01-overview/01-architecture.md index 432b12537..218964bed 100644 --- a/docs/docs/developer/01-overview/01-architecture.md +++ b/docs/docs/developer/01-overview/01-architecture.md @@ -15,6 +15,20 @@ keywords: ] --- + + Jan AI Architecture - Modular and Extensible Framework + + + + + + + + + + + + :::warning This page is still under construction, and should be read as a scratchpad diff --git a/docs/docs/developer/01-overview/02-file-based.md b/docs/docs/developer/01-overview/02-file-based.md index 653eba3f5..2cd8a554c 100644 --- a/docs/docs/developer/01-overview/02-file-based.md +++ b/docs/docs/developer/01-overview/02-file-based.md @@ -15,6 +15,20 @@ keywords: ] --- + + Jan AI File-based Data Persistence Approach + + + + + + + + + + + + :::warning This page is still under construction, and should be read as a scratchpad diff --git a/docs/docs/developer/01-overview/03-user-interface.md b/docs/docs/developer/01-overview/03-user-interface.md index eb6eac89e..fa5a3de79 100644 --- a/docs/docs/developer/01-overview/03-user-interface.md +++ b/docs/docs/developer/01-overview/03-user-interface.md @@ -15,6 +15,20 @@ keywords: ] --- + + Jan AI User Interface - Customizable UI Kit + + + + + + + + + + + + :::warning This page is still under construction, and should be read as a scratchpad diff --git a/docs/docs/developer/01-overview/04-install-and-prerequisites.md b/docs/docs/developer/01-overview/04-install-and-prerequisites.md index 9752f7b72..a3e6ccfc1 100644 --- a/docs/docs/developer/01-overview/04-install-and-prerequisites.md +++ b/docs/docs/developer/01-overview/04-install-and-prerequisites.md @@ -18,6 +18,20 @@ keywords: ] --- + + Jan AI Installation and Setup Guide - Developer Prerequisites + + + + + + + + + + + + ## Requirements ### Hardware Requirements diff --git a/docs/docs/developer/01-overview/README.md b/docs/docs/developer/01-overview/README.md index 7bc3524de..4f094685a 100644 --- a/docs/docs/developer/01-overview/README.md +++ b/docs/docs/developer/01-overview/README.md @@ -15,6 +15,20 @@ keywords: ] --- + + Jan AI Developer Documentation - Building Extensions and SDK Overview + + + + + + + + + + + + The following docs are aimed at developers who want to build extensions on top of the Jan Framework. :::tip diff --git a/docs/docs/developer/02-build-assistant/01-your-first-assistant.md b/docs/docs/developer/02-build-assistant/01-your-first-assistant.md index 16b80fc5e..863d275fe 100644 --- a/docs/docs/developer/02-build-assistant/01-your-first-assistant.md +++ b/docs/docs/developer/02-build-assistant/01-your-first-assistant.md @@ -17,7 +17,20 @@ keywords: ] --- + + Your First Assistant + + + + + + + + + + + + :::caution This is currently under development. ::: - diff --git a/docs/docs/developer/04-build-extension/01-your-first-extension.md b/docs/docs/developer/04-build-extension/01-your-first-extension.md index f89f34053..3fa9f5da5 100644 --- a/docs/docs/developer/04-build-extension/01-your-first-extension.md +++ b/docs/docs/developer/04-build-extension/01-your-first-extension.md @@ -17,6 +17,20 @@ keywords: ] --- + + Building Your First Jan AI Extension - Quick Start Guide + + + + + + + + + + + + :::caution This is currently under development. ::: @@ -76,13 +90,13 @@ There are a few things to keep in mind when writing your extension code: In `index.ts`, you will see that the extension function will return a `Promise`. ```typescript - import { core } from "@janhq/core"; + import { core } from '@janhq/core' function onStart(): Promise { - return core.invokePluginFunc(MODULE_PATH, "run", 0); + return core.invokePluginFunc(MODULE_PATH, 'run', 0) } ``` For more information about the Jan Extension Core module, see the [documentation](https://github.com/janhq/jan/blob/main/core/README.md). -Now, go ahead and start customizing your extension! Happy coding! \ No newline at end of file +Now, go ahead and start customizing your extension! Happy coding! diff --git a/docs/docs/developer/05-framework/03-engineering/assistants.md b/docs/docs/developer/05-framework/03-engineering/assistants.md index fa9c593ab..90b52ab38 100644 --- a/docs/docs/developer/05-framework/03-engineering/assistants.md +++ b/docs/docs/developer/05-framework/03-engineering/assistants.md @@ -1,5 +1,5 @@ --- -title: "Assistants" +title: 'Assistants' description: Jan is a ChatGPT-alternative that runs on your own computer, with a local API server. keywords: [ @@ -14,6 +14,19 @@ keywords: ] --- + + Assistants + + + + + + + + + + + :::caution This is currently under development. diff --git a/docs/docs/developer/05-framework/03-engineering/chats.md b/docs/docs/developer/05-framework/03-engineering/chats.md index eb0ae287a..654621e30 100644 --- a/docs/docs/developer/05-framework/03-engineering/chats.md +++ b/docs/docs/developer/05-framework/03-engineering/chats.md @@ -14,6 +14,19 @@ keywords: ] --- + + Chats + + + + + + + + + + + :::caution This is currently under development. diff --git a/docs/docs/developer/05-framework/03-engineering/engine.md b/docs/docs/developer/05-framework/03-engineering/engine.md index 653576f1b..8ebfff88d 100644 --- a/docs/docs/developer/05-framework/03-engineering/engine.md +++ b/docs/docs/developer/05-framework/03-engineering/engine.md @@ -2,6 +2,19 @@ title: Engine --- + + Engine + + + + + + + + + + + :::caution Currently Under Development diff --git a/docs/docs/developer/05-framework/03-engineering/files.md b/docs/docs/developer/05-framework/03-engineering/files.md index 59ca27ec9..9f572af11 100644 --- a/docs/docs/developer/05-framework/03-engineering/files.md +++ b/docs/docs/developer/05-framework/03-engineering/files.md @@ -1,5 +1,5 @@ --- -title: "Files" +title: 'Files' description: Jan is a ChatGPT-alternative that runs on your own computer, with a local API server. keywords: [ @@ -14,6 +14,19 @@ keywords: ] --- + + Files + + + + + + + + + + + :::warning Draft Specification: functionality has not been implemented yet. diff --git a/docs/docs/developer/05-framework/03-engineering/messages.md b/docs/docs/developer/05-framework/03-engineering/messages.md index 8f2497002..6ddaba45d 100644 --- a/docs/docs/developer/05-framework/03-engineering/messages.md +++ b/docs/docs/developer/05-framework/03-engineering/messages.md @@ -14,6 +14,19 @@ keywords: ] --- + + Messages + + + + + + + + + + + :::caution This is currently under development. diff --git a/docs/docs/developer/05-framework/03-engineering/models.md b/docs/docs/developer/05-framework/03-engineering/models.md index 4e4c3c604..dbe134f07 100644 --- a/docs/docs/developer/05-framework/03-engineering/models.md +++ b/docs/docs/developer/05-framework/03-engineering/models.md @@ -14,6 +14,19 @@ keywords: ] --- + + Models + + + + + + + + + + + :::caution This is currently under development. diff --git a/docs/docs/developer/05-framework/03-engineering/threads.md b/docs/docs/developer/05-framework/03-engineering/threads.md index a1cd2b4df..f8ba018f8 100644 --- a/docs/docs/developer/05-framework/03-engineering/threads.md +++ b/docs/docs/developer/05-framework/03-engineering/threads.md @@ -14,6 +14,19 @@ keywords: ] --- + + Threads + + + + + + + + + + + :::caution This is currently under development. diff --git a/docs/docs/developer/05-framework/03-product/chat.md b/docs/docs/developer/05-framework/03-product/chat.md index b0dcce2d6..3b98485b8 100644 --- a/docs/docs/developer/05-framework/03-product/chat.md +++ b/docs/docs/developer/05-framework/03-product/chat.md @@ -14,6 +14,19 @@ keywords: ] --- + + Chat + + + + + + + + + + + ## Overview A home screen for users to chat with [assistants](/docs/engineering/assistants) via conversation [threads](/docs/engineering/threads). diff --git a/docs/docs/developer/05-framework/03-product/hub.md b/docs/docs/developer/05-framework/03-product/hub.md index 7171f8378..ea8dd81a5 100644 --- a/docs/docs/developer/05-framework/03-product/hub.md +++ b/docs/docs/developer/05-framework/03-product/hub.md @@ -14,6 +14,19 @@ keywords: ] --- + + Hub + + + + + + + + + + + ## Overview The Hub is like a store for everything, where users can discover and download models, assistants, and more. diff --git a/docs/docs/developer/05-framework/03-product/jan.md b/docs/docs/developer/05-framework/03-product/jan.md index 9e8973360..b906be09d 100644 --- a/docs/docs/developer/05-framework/03-product/jan.md +++ b/docs/docs/developer/05-framework/03-product/jan.md @@ -14,6 +14,19 @@ keywords: ] --- + + Jan (The Default Assistant) + + + + + + + + + + + Jan ships with a default assistant "Jan" that lets users chat with any open source model out-of-the-box. This assistant is defined in `/jan`. It is a generic assistant to illustrate power of Jan. In the future, it will support additional features e.g. multi-assistant conversations diff --git a/docs/docs/developer/05-framework/03-product/settings.md b/docs/docs/developer/05-framework/03-product/settings.md index 514139a00..515b5e802 100644 --- a/docs/docs/developer/05-framework/03-product/settings.md +++ b/docs/docs/developer/05-framework/03-product/settings.md @@ -14,6 +14,19 @@ keywords: ] --- + + Settings + + + + + + + + + + + ## Overview A settings page for users to add extensions, configure model settings, change app appearance, add keyboard shortcuts, and a plethora of other personalizations. diff --git a/docs/docs/developer/05-framework/03-product/system-monitor.md b/docs/docs/developer/05-framework/03-product/system-monitor.md index 761d9a7bf..15dae09ea 100644 --- a/docs/docs/developer/05-framework/03-product/system-monitor.md +++ b/docs/docs/developer/05-framework/03-product/system-monitor.md @@ -14,6 +14,19 @@ keywords: ] --- + + System Monitor + + + + + + + + + + + ## Overview An activity screen to monitor system health and running models. diff --git a/docs/docs/events/hcmc-oct23.md b/docs/docs/events/hcmc-oct23.md index 73898efcd..e70329b2d 100644 --- a/docs/docs/events/hcmc-oct23.md +++ b/docs/docs/events/hcmc-oct23.md @@ -1,10 +1,23 @@ --- title: "Jan's AI Hacker House (Ho Chi Minh City)" -description: "24-27 Oct 2023, District 3, HCMC. AI-focused talks, workshops and social events. Hosted by Jan.ai" +description: '24-27 Oct 2023, District 3, HCMC. AI-focused talks, workshops and social events. Hosted by Jan.ai' slug: /events/hcmc-oct23 image: /img/hcmc-launch-party.png --- + + Jan's AI Hacker House (Ho Chi Minh City) + + + + + + + + + + + ![](/img/hcmc-launch-party.png) 🎉 Join us at our Friday Launch Party for an evening of AI talks from other builders! [(RSVP here)](https://jan-launch-party.eventbrite.sg/) 🎉 diff --git a/docs/docs/events/nvidia-llm-day-nov-23.md b/docs/docs/events/nvidia-llm-day-nov-23.md index d467dcb6e..f739fb4ff 100644 --- a/docs/docs/events/nvidia-llm-day-nov-23.md +++ b/docs/docs/events/nvidia-llm-day-nov-23.md @@ -1,21 +1,33 @@ --- -title: "Nov 23: Nvidia GenAI Day" -description: Nvidia's LLM Day +title: 'Nov 23: Nvidia GenAI Day' +description: Nvidia's LLM Day --- + + Nov 23: Nvidia GenAI Day + + + + + + + + + + + ![](/img/nvidia-llm-day-header.png) ## Nvidia GenAI Innovation Day -Jan will be at Nvidia's GenAI Innovation Day in Nov '23, focusing on Enterprise use-cases of LLMs. +Jan will be at Nvidia's GenAI Innovation Day in Nov '23, focusing on Enterprise use-cases of LLMs. ### Location -- JW Marriott Hanoi Hotel +- JW Marriott Hanoi Hotel - 8:30am November 8th 2023 - Registration: [https://gmcgroup.com.vn/nvidia-genai-event/](https://gmcgroup.com.vn/nvidia-genai-event/) ### Programme ![](/img/nvidia-llm-day.png) - diff --git a/docs/docs/guides/integrations/interpreter.mdx b/docs/docs/guides/integrations/interpreter.mdx index be5829d8b..bd2ffb8de 100644 --- a/docs/docs/guides/integrations/interpreter.mdx +++ b/docs/docs/guides/integrations/interpreter.mdx @@ -18,6 +18,17 @@ keywords: ] --- + + Open Interpreter + + + + + + + + + ## Integrate Open Interpreter with Jan diff --git a/docs/docs/guides/integrations/raycast.mdx b/docs/docs/guides/integrations/raycast.mdx index 730e4d103..5823410b1 100644 --- a/docs/docs/guides/integrations/raycast.mdx +++ b/docs/docs/guides/integrations/raycast.mdx @@ -18,6 +18,17 @@ keywords: description: A step-by-step guide on how to integrate Jan with Raycast. --- + + Raycast + + + + + + + + + ## Integrate Raycast with Jan [Raycast](https://www.raycast.com/) is a productivity tool designed for macOS that enhances workflow efficiency by providing quick access to various tasks and functionalities through a keyboard-driven interface. To integrate Raycast with Jan, follow the steps below: diff --git a/docs/docs/guides/integrations/router.mdx b/docs/docs/guides/integrations/router.mdx index e9f6580ee..dfe44771f 100644 --- a/docs/docs/guides/integrations/router.mdx +++ b/docs/docs/guides/integrations/router.mdx @@ -18,6 +18,17 @@ keywords: ] --- + + OpenRouter + + + + + + + + + ## Integrate OpenRouter with Jan diff --git a/docs/docs/guides/remote-providers/groq.mdx b/docs/docs/guides/remote-providers/groq.mdx index c9837bcfc..2ae4027f9 100644 --- a/docs/docs/guides/remote-providers/groq.mdx +++ b/docs/docs/guides/remote-providers/groq.mdx @@ -17,6 +17,18 @@ keywords: ] --- + + Groq + + + + + + + + + + ## How to Integrate Mistral AI with Jan This guide provides step-by-step instructions on integrating the Groq API with Jan, enabling users to leverage Groq's capabilities within Jan's conversational interface. diff --git a/docs/docs/guides/remote-providers/mistral.mdx b/docs/docs/guides/remote-providers/mistral.mdx index 38f2dda25..88b98f880 100644 --- a/docs/docs/guides/remote-providers/mistral.mdx +++ b/docs/docs/guides/remote-providers/mistral.mdx @@ -17,6 +17,18 @@ keywords: ] --- + + Mistral AI + + + + + + + + + + ## How to Integrate Mistral AI with Jan [Mistral AI](https://docs.mistral.ai/) provides two ways to use their Large Language Models (LLM): diff --git a/docs/docs/guides/remote-providers/remote-server-integration.mdx b/docs/docs/guides/remote-providers/remote-server-integration.mdx index eb1e0bab7..2205c3f85 100644 --- a/docs/docs/guides/remote-providers/remote-server-integration.mdx +++ b/docs/docs/guides/remote-providers/remote-server-integration.mdx @@ -19,6 +19,18 @@ keywords: ] --- + + Remote Server Integration + + + + + + + + + + This guide will show you how to configure Jan as a client and point it to any remote & local (self-hosted) API server. ## OpenAI Platform Configuration diff --git a/docs/docs/guides/user-guides/advanced-settings.mdx b/docs/docs/guides/user-guides/advanced-settings.mdx index a9723c15d..3edf1f905 100644 --- a/docs/docs/guides/user-guides/advanced-settings.mdx +++ b/docs/docs/guides/user-guides/advanced-settings.mdx @@ -21,6 +21,20 @@ keywords: ] --- + + Advanced Settings + + + + + + + + + + + + import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/docs/hardware/community.md b/docs/docs/hardware/community.md index e1825b24b..5ba920d89 100644 --- a/docs/docs/hardware/community.md +++ b/docs/docs/hardware/community.md @@ -1,12 +1,36 @@ --- title: Hardware Examples description: Jan is a ChatGPT-alternative that runs on your own computer, with a local API server. -keywords: [Jan AI, Jan, ChatGPT alternative, local AI, private AI, conversational AI, no-subscription fee, large language model ] +keywords: + [ + Jan AI, + Jan, + ChatGPT alternative, + local AI, + private AI, + conversational AI, + no-subscription fee, + large language model, + ] --- + + Hardware Examples + + + + + + + + + + + + ## Add your own example -Add your own examples to this page by creating a new file in the `docs/docs/hardware/examples` directory. +Add your own examples to this page by creating a new file in the `docs/docs/hardware/examples` directory. ```shell docs @@ -18,9 +42,10 @@ docs // highlight-next-line └── .md ``` + ### File and Title Convention -We use a specific naming convention for the file name. +We use a specific naming convention for the file name. ```shell # Filename @@ -52,4 +77,4 @@ You are allowed to include affiliate links in your example. ## Longer-Term -We will likely build a simple web app to make it easier to add your own examples, sort and retrieve. \ No newline at end of file +We will likely build a simple web app to make it easier to add your own examples, sort and retrieve. diff --git a/docs/docs/hardware/concepts/gpu-and-vram.md b/docs/docs/hardware/concepts/gpu-and-vram.md index 57387e8d2..0a9316a90 100644 --- a/docs/docs/hardware/concepts/gpu-and-vram.md +++ b/docs/docs/hardware/concepts/gpu-and-vram.md @@ -2,6 +2,20 @@ title: GPUs and VRAM --- + + Understanding GPUs and VRAM for AI and Gaming + + + + + + + + + + + + ## What Is a GPU? A Graphics Card, or GPU (Graphics Processing Unit), is a fundamental component in modern computing. Think of it as the powerhouse behind rendering the stunning visuals you see on your screen. Similar to the motherboard in your computer, the graphics card is a printed circuit board. However, it's not just a passive piece of hardware; it's a sophisticated device equipped with essential components like fans, onboard RAM, a dedicated memory controller, BIOS, and various other features. If you want to learn more about GPUs then read here to [Understand the architecture of a GPU.](https://medium.com/codex/understanding-the-architecture-of-a-gpu-d5d2d2e8978b) diff --git a/docs/docs/hardware/overview/cloud-vs-self-hosting.md b/docs/docs/hardware/overview/cloud-vs-self-hosting.md index 0d34bb1a9..f4d4b2236 100644 --- a/docs/docs/hardware/overview/cloud-vs-self-hosting.md +++ b/docs/docs/hardware/overview/cloud-vs-self-hosting.md @@ -2,6 +2,18 @@ title: Cloud vs. Self-hosting Your AI --- + + Cloud vs. Self-hosting Your AI + + + + + + + + + + The choice of how to run your AI - on GPU cloud services, on-prem, or just using an API provider - involves various trade-offs. The following is a naive exploration of the pros and cons of renting vs self-hosting. ## Cost Comparison diff --git a/docs/docs/hardware/overview/cpu-vs-gpu.md b/docs/docs/hardware/overview/cpu-vs-gpu.md index f0f20d8d6..b50655574 100644 --- a/docs/docs/hardware/overview/cpu-vs-gpu.md +++ b/docs/docs/hardware/overview/cpu-vs-gpu.md @@ -2,6 +2,20 @@ title: GPU vs CPU What's the Difference? --- + + GPU vs CPU What's the Difference? + + + + + + + + + + + + ## CPU vs. GPU | | CPU | GPU | diff --git a/docs/docs/hardware/recommendations/by-budget.md b/docs/docs/hardware/recommendations/by-budget.md index 9e640fbc9..e556c77d3 100644 --- a/docs/docs/hardware/recommendations/by-budget.md +++ b/docs/docs/hardware/recommendations/by-budget.md @@ -2,6 +2,20 @@ title: Recommended AI Hardware by Budget --- + + Recommended AI Hardware Builds by Budget + + + + + + + + + + + + > :warning: **Warning:** Do your own research before any purchase. Jan is not liable for compatibility, performance or other issues. Products can become outdated quickly. ## Entry-level PC Build at $1000 diff --git a/docs/docs/hardware/recommendations/by-hardware.md b/docs/docs/hardware/recommendations/by-hardware.md index ee80a290c..dcd744d8b 100644 --- a/docs/docs/hardware/recommendations/by-hardware.md +++ b/docs/docs/hardware/recommendations/by-hardware.md @@ -2,6 +2,20 @@ title: Selecting AI Hardware --- + + Selecting AI Hardware + + + + + + + + + + + + When selecting a GPU for LLMs, remember that it's not just about the GPU itself. Consider the synergy with other components in your PC: - **CPU**: To ensure efficient processing, pair your GPU with a powerful CPU. LLMs benefit from fast processors, so having a capable CPU is essential. diff --git a/docs/docs/hardware/recommendations/by-model.md b/docs/docs/hardware/recommendations/by-model.md index 99d1ca8a2..e9fe1c3e8 100644 --- a/docs/docs/hardware/recommendations/by-model.md +++ b/docs/docs/hardware/recommendations/by-model.md @@ -2,6 +2,20 @@ title: Recommended AI Hardware by Model --- + + Recommended AI Hardware by Model + + + + + + + + + + + + ## Codellama 34b ### System Requirements: diff --git a/docs/docs/hardware/recommendations/by-usecase.md b/docs/docs/hardware/recommendations/by-usecase.md index 2ae0cb906..aa7a1bf75 100644 --- a/docs/docs/hardware/recommendations/by-usecase.md +++ b/docs/docs/hardware/recommendations/by-usecase.md @@ -2,6 +2,20 @@ title: Recommended AI Hardware by Use Case --- + + Recommended AI Hardware by Model + + + + + + + + + + + + ## Which AI Hardware to Choose Based on Your Use Case Artificial intelligence (AI) is rapidly changing the world, and AI hardware is becoming increasingly important for businesses and individuals alike. Choosing the right hardware for your AI needs is crucial to get the best performance and results. Here are some tips for selecting AI hardware based on your specific use case and requirements. diff --git a/docs/docs/how-we-work.md b/docs/docs/how-we-work.md index e81099d18..602f7c902 100644 --- a/docs/docs/how-we-work.md +++ b/docs/docs/how-we-work.md @@ -2,6 +2,18 @@ title: How We Work --- + + How We Work - Jan + + + + + + + + + + ### Open Source Jan is a startup with an open source business model. We believe in the need for an open source AI ecosystem, and are committed to building it. diff --git a/docs/docs/how-we-work/analytics/analytics.md b/docs/docs/how-we-work/analytics/analytics.md index 79e107a83..5991263cc 100644 --- a/docs/docs/how-we-work/analytics/analytics.md +++ b/docs/docs/how-we-work/analytics/analytics.md @@ -2,6 +2,18 @@ title: Analytics --- + + Analytics + + + + + + + + + + Adhering to Jan's privacy preserving philosophy, our analytics philosophy is to get "barely-enough-to-function'. #### What is tracked diff --git a/docs/docs/how-we-work/engineering/qa.mdx b/docs/docs/how-we-work/engineering/qa.mdx index f43caae4a..aa851dfa3 100644 --- a/docs/docs/how-we-work/engineering/qa.mdx +++ b/docs/docs/how-we-work/engineering/qa.mdx @@ -15,6 +15,18 @@ keywords: ] --- + + QA + + + + + + + + + + ### Phase 1: Planning #### Definition of Ready (DoR): diff --git a/docs/docs/how-we-work/project-management/project-management.md b/docs/docs/how-we-work/project-management/project-management.md index 58af4a0d3..85bbe0d75 100644 --- a/docs/docs/how-we-work/project-management/project-management.md +++ b/docs/docs/how-we-work/project-management/project-management.md @@ -2,6 +2,18 @@ title: Project Management --- + + Project Management + + + + + + + + + + We use the [Jan Monorepo Project](https://github.com/orgs/janhq/projects/5) in Github to manage our roadmap and sprint Kanbans. As much as possible, everyone owns their respective `epics` and `tasks`. @@ -58,7 +70,6 @@ We aim to always sprint on `tasks` that are a part of the [current roadmap](http - `Urgent bugs`: assign to an owner (or @engineers if you are not sure) && tag the current `sprint` & `milestone` - `All else`: assign the correct roadmap `label(s)` and owner (if any) - #### Request for help As a result, our feature prioritization can feel a bit black box at times. diff --git a/docs/docs/how-we-work/strategy/strategy.md b/docs/docs/how-we-work/strategy/strategy.md index 09d9b9fb4..a448c090e 100644 --- a/docs/docs/how-we-work/strategy/strategy.md +++ b/docs/docs/how-we-work/strategy/strategy.md @@ -2,7 +2,20 @@ title: Strategy --- + + Strategy + + + + + + + + + + We only have 2 planning parameters: + - 10 year vision - 2 week sprint - Quarterly OKRs @@ -46,7 +59,6 @@ Jan is a seamless user experience that runs on your personal computer, that glue - We run on top of a local folder of non-proprietary files, that anyone can tinker with (yes, even other apps!) - We provide open formats for packaging and distributing AI to run reproducibly across devices - ## Prerequisites - [Figma](https://figma.com) diff --git a/docs/docs/how-we-work/website-docs/website-docs.md b/docs/docs/how-we-work/website-docs/website-docs.md index 19fdc1676..9dcedb0b8 100644 --- a/docs/docs/how-we-work/website-docs/website-docs.md +++ b/docs/docs/how-we-work/website-docs/website-docs.md @@ -2,6 +2,18 @@ title: Website & Docs --- + + Website & Docs + + + + + + + + + + This website is built using [Docusaurus 3.0](https://docusaurus.io/), a modern static website generator. ### Information Architecture diff --git a/docs/docs/platforms/desktop.md b/docs/docs/platforms/desktop.md index fb4ea8389..d8c8a38cc 100644 --- a/docs/docs/platforms/desktop.md +++ b/docs/docs/platforms/desktop.md @@ -15,6 +15,18 @@ keywords: ] --- + + Jan Desktop + + + + + + + + + + # Turn any computer into an AI computer ![Alt text](image.png) diff --git a/docs/docs/privacy/privacy.md b/docs/docs/privacy/privacy.md index 56e81f3a1..e1f5d0f10 100644 --- a/docs/docs/privacy/privacy.md +++ b/docs/docs/privacy/privacy.md @@ -1,3 +1,21 @@ +--- +title: Privacy - Jan +--- + + + Privacy Policy - Jan + + + + + + + + + + + + # Privacy Policy Jan is committed to protecting your privacy and ensuring that your personal information is handled in a safe and responsible way. This policy outlines how we collect, store, and use your personal information when you use our mobile application. diff --git a/docs/docs/server-suite/enterprise.md b/docs/docs/server-suite/enterprise.md index 565c14fde..e08356954 100644 --- a/docs/docs/server-suite/enterprise.md +++ b/docs/docs/server-suite/enterprise.md @@ -15,6 +15,18 @@ keywords: ] --- + + Jan Enterprise + + + + + + + + + + # Customize and run AI across your organization Jan can professional backend to create, customize and run AIs at scale, for production-grade data centers. diff --git a/docs/docs/server-suite/home-server.md b/docs/docs/server-suite/home-server.md index 97f3afbc7..630d2b9d9 100644 --- a/docs/docs/server-suite/home-server.md +++ b/docs/docs/server-suite/home-server.md @@ -15,6 +15,18 @@ keywords: ] --- + + Jan Home Server + + + + + + + + + + # Customize and run AI across all of your devices Self-host and access your AI from anywhere with Jan server suite. diff --git a/docs/docs/support/support.md b/docs/docs/support/support.md index 5a1ec2097..856041f86 100644 --- a/docs/docs/support/support.md +++ b/docs/docs/support/support.md @@ -1,3 +1,21 @@ +--- +title: Support - Jan +--- + + + Support - Jan + + + + + + + + + + + + # Support - Bugs & requests: file a GitHub ticket [here](https://github.com/janhq/jan/issues) diff --git a/docs/docs/team/team.md b/docs/docs/team/team.md index 7d5e07cfb..2b8b24d01 100644 --- a/docs/docs/team/team.md +++ b/docs/docs/team/team.md @@ -2,6 +2,18 @@ title: Who we are --- + + Who we are - Jan + + + + + + + + + + What's Jan the company about? We aim to build the cognitive framework for future robots @@ -13,7 +25,6 @@ Jan is a startup with an open source business model. We believe in the need for - [Jan Desktop Client & Local server](https://jan.ai) (AGPLv3, built on Jan Framework) - [Nitro: run Local AI](https://github.com/janhq/nitro) (AGPLv3) - ### Bootstrapped Jan is currently a bootstrapped startup. @@ -25,4 +36,4 @@ We balance technical invention with the search for a sustainable business model. ## Our Team - Contributors -- Core Team \ No newline at end of file +- Core Team diff --git a/docs/docs/template/QA_script.md b/docs/docs/template/QA_script.md index 9c7eeaf18..de006c629 100644 --- a/docs/docs/template/QA_script.md +++ b/docs/docs/template/QA_script.md @@ -26,7 +26,6 @@ - [ ] :key::warning: Check that the uninstallation process removes the app successfully from the system. - [ ] Clean the Jan root directory and open the app to check if it creates all the necessary folders, especially models and extensions. - ## B. Overview ### 1. Shortcut key, memory usage / CPU usage @@ -71,10 +70,12 @@ - [ ] :key: Ensure that users switch between threads with different models, the app can handle it. ### 3. Model dropdown + - [ ] :key: Model list should highlight recommended based on user RAM - [ ] Model size should display (for both installed and imported models) ### 4. Users can click on a history thread + - [ ] Confirm that the chat window displays the entire conversation from the selected history thread without any missing messages. - [ ] :key: Check the performance and accuracy of the history feature when dealing with a large number of threads. - [ ] Validate that historical threads reflect the exact state of the chat at that time, including settings. @@ -82,12 +83,12 @@ - [ ] Confirm that changing the title of the thread updates correctly. ### 5. Users can config instructions for the assistant. + - [ ] Test if the instructions set by the user are being followed by the assistant in subsequent conversations. - [ ] :key: Validate that changes to instructions are updated in real time and do not require a restart of the application or session. - [ ] :key: Check for the ability to reset instructions to default or clear them completely. - [ ] :key: RAG - Users can import documents and the system should process queries about the uploaded file, providing accurate and appropriate responses in the conversation thread. - ## D. Hub ### 1. Users can discover recommended models (Jan ships with a few preconfigured model.json files) @@ -117,13 +118,14 @@ ### 5. Users can use the model as they want -- [ ] :key: Check `start` / `stop` / `delete` button response exactly what it does. +- [ ] :key: Check `start` / `stop` / `delete` button response exactly what it does. - [ ] Check if starting another model stops the other model entirely. - [x] :rocket: Check the `Explore models` navigate correctly to the model panel. - [ ] :key: Check when deleting a model it will delete all the files on the user's computer. - [ ] :warning:The recommended tags should present right for the user's hardware. ### 6. Users can Integrate With a Remote Server + - [ ] :key: Import openAI GPT model https://jan.ai/guides/using-models/integrate-with-remote-server/ and the model displayed in Hub / Thread dropdown - [ ] Users can use the remote model properly @@ -184,9 +186,10 @@ ## G. Local API server ### 1. Local Server Usage with Server Options + - [ ] :key: Explore API Reference: Swagger API for sending/receiving requests - - [ ] Use default server option - - [ ] Configure and use custom server options + - [ ] Use default server option + - [ ] Configure and use custom server options - [ ] Test starting/stopping the local API server with different Model/Model settings - [ ] Server logs captured with correct Server Options provided - [ ] Verify functionality of Open logs/Clear feature diff --git a/docs/docs/wall-of-love.md b/docs/docs/wall-of-love.md index f6bfe79d8..41f68b0f2 100644 --- a/docs/docs/wall-of-love.md +++ b/docs/docs/wall-of-love.md @@ -2,6 +2,18 @@ title: Wall of Love ❤️ --- + + Wall of Love ❤️ - Jan + + + + + + + + + + ## Twitter Check out our amazing users and what they are saying about Jan! diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 1d2a19d38..24bb39e8a 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -222,8 +222,7 @@ const config = { metadata: [ { name: 'description', - content: - 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.', + content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`, }, { name: 'keywords', @@ -233,12 +232,11 @@ const config = { { name: 'robots', content: 'index, follow' }, { property: 'og:title', - content: 'Jan | Open-source ChatGPT Alternative', + content: 'Jan AI | Rethink the Computer', }, { property: 'og:description', - content: - 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.', + content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`, }, { property: 'og:image', @@ -249,12 +247,11 @@ const config = { { property: 'twitter:site', content: '@janframework' }, { property: 'twitter:title', - content: 'Jan | Open-source ChatGPT Alternative', + content: 'Jan AI | Rethink the Computer', }, { property: 'twitter:description', - content: - 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.', + content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`, }, { property: 'twitter:image', @@ -280,8 +277,7 @@ const config = { '@context': 'https://schema.org/', '@type': 'localAI', 'name': 'Jan', - 'description': - 'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.', + 'description': `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`, 'keywords': 'Jan AI, Jan, ChatGPT alternative, local AI, private AI, conversational AI, no-subscription fee, large language model ', 'applicationCategory': 'BusinessApplication', @@ -338,10 +334,15 @@ const config = { position: 'left', label: 'Ecosystem', }, + { + to: 'download', + position: 'left', + label: 'Download', + }, // { // type: "docSidebar", // sidebarId: "pricingSidebar", - // positionL: "left", + // positionl: "left", // label: "Pricing", // }, // Navbar right @@ -403,6 +404,11 @@ const config = { }, }, + // Put your custom environment here + customFields: { + apiKeyBrevo: process.env.API_KEY_BREVO, + }, + themes: ['@docusaurus/theme-live-codeblock', '@docusaurus/theme-mermaid'], } diff --git a/docs/package.json b/docs/package.json index eb386d783..b4418453e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -37,9 +37,12 @@ "postcss": "^8.4.30", "posthog-docusaurus": "^2.0.0", "prism-react-renderer": "^1.3.5", + "lucide-react": "^0.291.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.47.0", "react-icons": "^4.11.0", + "react-tweet": "^3.2.0", "redocusaurus": "^2.0.0", "sass": "^1.69.3", "tailwind-merge": "^2.1.0", @@ -47,7 +50,7 @@ }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.0.0", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "tailwindcss-animate": "^1.0.7" }, "browserslist": { diff --git a/docs/src/containers/Banner/index.js b/docs/src/containers/Banner/index.js index 07622c63d..3538ab7a9 100644 --- a/docs/src/containers/Banner/index.js +++ b/docs/src/containers/Banner/index.js @@ -1,32 +1,43 @@ -import React from "react"; +import React from 'react' -import { useAppStars } from "@site/src/hooks/useAppStars"; -import { useAppRelease } from "@site/src/hooks/useAppRelease"; +import { useAppStars } from '@site/src/hooks/useAppStars' +import { useAppRelease } from '@site/src/hooks/useAppRelease' -import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; -import { BiLogoDiscordAlt } from "react-icons/bi"; +import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai' +import { BiLogoDiscordAlt } from 'react-icons/bi' +import { FaLinkedin } from 'react-icons/fa' const socials = [ { icon: , - href: "https://twitter.com/janframework", + href: 'https://twitter.com/janframework', }, { icon: , - href: "https://discord.com/invite/FTk2MvZwJH", + href: 'https://discord.com/invite/FTk2MvZwJH', }, { icon: , - href: "https://github.com/janhq/jan", + href: 'https://github.com/janhq/jan', }, -]; + { + icon: , + href: 'https://www.linkedin.com/company/janframework/', + }, +] export default function AnnoncementBanner() { - const { stargazers } = useAppStars(); - const { release } = useAppRelease(); + const { stargazers } = useAppStars() + const { release } = useAppRelease() return ( -
+
{social.icon} - ); + ) })}
- ); + ) } diff --git a/docs/src/containers/DownloadApp/index.js b/docs/src/containers/DownloadApp/index.js index d1b586698..9d1cd6a48 100644 --- a/docs/src/containers/DownloadApp/index.js +++ b/docs/src/containers/DownloadApp/index.js @@ -1,135 +1,161 @@ -import React, { useState, useEffect } from "react"; -import axios from "axios"; -import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; -import { twMerge } from "tailwind-merge"; +import React, { useState, useEffect } from 'react' +import axios from 'axios' +import { FaWindows, FaApple, FaLinux } from 'react-icons/fa' +import { twMerge } from 'tailwind-merge' +import { DownloadIcon } from 'lucide-react' const systemsTemplate = [ { - name: "Mac M1, M2, M3", + name: 'Mac M1, M2, M3', + label: 'Apple Silicon', logo: FaApple, - fileFormat: "{appname}-mac-arm64-{tag}.dmg", - comingSoon: false, + fileFormat: '{appname}-mac-arm64-{tag}.dmg', }, { - name: "Mac (Intel)", + name: 'Mac (Intel)', + label: 'Apple Intel', logo: FaApple, - fileFormat: "{appname}-mac-x64-{tag}.dmg", - comingSoon: false, + fileFormat: '{appname}-mac-x64-{tag}.dmg', }, { - name: "Windows", + name: 'Windows', + label: 'Standard (64-bit)', logo: FaWindows, - fileFormat: "{appname}-win-x64-{tag}.exe", + fileFormat: '{appname}-win-x64-{tag}.exe', }, { - name: "Linux (AppImage)", + name: 'Linux (AppImage)', + label: 'AppImage', logo: FaLinux, - fileFormat: "{appname}-linux-x86_64-{tag}.AppImage", + fileFormat: '{appname}-linux-x86_64-{tag}.AppImage', }, { - name: "Linux (deb)", + name: 'Linux (deb)', + label: 'Deb', logo: FaLinux, - fileFormat: "{appname}-linux-amd64-{tag}.deb", + fileFormat: '{appname}-linux-amd64-{tag}.deb', }, -]; +] + +const groupTemnplate = [ + { label: 'MacOS', name: 'mac', logo: FaApple }, + { label: 'Windows', name: 'windows', logo: FaWindows }, + { label: 'Linux', name: 'linux', logo: FaLinux }, +] export default function DownloadApp() { - const [systems, setSystems] = useState(systemsTemplate); + const [systems, setSystems] = useState(systemsTemplate) const getLatestReleaseInfo = async (repoOwner, repoName) => { - const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`; + const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest` try { - const response = await axios.get(url); - return response.data; + const response = await axios.get(url) + return response.data } catch (error) { - console.error(error); - return null; + console.error(error) + return null } - }; + } const extractAppName = (fileName) => { // Extract appname using a regex that matches the provided file formats - const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|amd64|x86_64)-.*$/; - const match = fileName.match(regex); - return match ? match[1] : null; - }; + const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|amd64|x86_64)-.*$/ + const match = fileName.match(regex) + return match ? match[1] : null + } useEffect(() => { const updateDownloadLinks = async () => { try { - const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); + const releaseInfo = await getLatestReleaseInfo('janhq', 'jan') // Extract appname from the first asset name - const firstAssetName = releaseInfo.assets[0].name; - const appname = extractAppName(firstAssetName); + const firstAssetName = releaseInfo.assets[0].name + const appname = extractAppName(firstAssetName) if (!appname) { console.error( - "Failed to extract appname from file name:", + 'Failed to extract appname from file name:', firstAssetName - ); + ) - return; + return } // Remove 'v' at the start of the tag_name - const tag = releaseInfo.tag_name.startsWith("v") + const tag = releaseInfo.tag_name.startsWith('v') ? releaseInfo.tag_name.substring(1) - : releaseInfo.tag_name; + : releaseInfo.tag_name const updatedSystems = systems.map((system) => { const downloadUrl = system.fileFormat - .replace("{appname}", appname) - .replace("{tag}", tag); + .replace('{appname}', appname) + .replace('{tag}', tag) return { ...system, href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, - }; - }); + } + }) - setSystems(updatedSystems); + setSystems(updatedSystems) } catch (error) { - console.error("Failed to update download links:", error); + console.error('Failed to update download links:', error) } - }; + } - updateDownloadLinks(); - }, []); + updateDownloadLinks() + }, []) + + const renderDownloadLink = (group) => { + return ( + <> + {systems + .filter((x) => x.name.toLowerCase().includes(group)) + .map((system, i) => ( + + ))} + + ) + } return ( -
-
- - Download for PC - -
- 🚧 - Warning: - - Jan is in the process of being built. Expect bugs! - -
-
-
- {systems.map((system, i) => ( - - - {system.name} - {system.comingSoon && ( - - Coming Soon - - )} - - ))} +
+
+ {groupTemnplate.map((item, i) => { + return ( +
+
+
+
+ +
+
{item.label}
+
+
+ {renderDownloadLink(item.name)} +
+
+
+ ) + })}
- ); + ) } diff --git a/docs/src/containers/Elements/dropdown.js b/docs/src/containers/Elements/dropdown.js index 91115c811..00176fdf2 100644 --- a/docs/src/containers/Elements/dropdown.js +++ b/docs/src/containers/Elements/dropdown.js @@ -1,134 +1,134 @@ -import React, { useState, useEffect } from "react"; -import { Fragment } from "react"; -import { Menu, Transition } from "@headlessui/react"; -import { ChevronDownIcon } from "@heroicons/react/20/solid"; -import axios from "axios"; -import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; +import React, { useState, useEffect } from 'react' +import { Fragment } from 'react' +import { Menu, Transition } from '@headlessui/react' +import { ChevronDownIcon } from '@heroicons/react/20/solid' +import axios from 'axios' +import { FaWindows, FaApple, FaLinux } from 'react-icons/fa' const systemsTemplate = [ { - name: "Download for Mac (M1/M2/M3)", + name: 'Download for Mac (M1/M2/M3)', logo: FaApple, - fileFormat: "{appname}-mac-arm64-{tag}.dmg", + fileFormat: '{appname}-mac-arm64-{tag}.dmg', }, { - name: "Download for Mac (Intel)", + name: 'Download for Mac (Intel)', logo: FaApple, - fileFormat: "{appname}-mac-x64-{tag}.dmg", + fileFormat: '{appname}-mac-x64-{tag}.dmg', }, { - name: "Download for Windows", + name: 'Download for Windows', logo: FaWindows, - fileFormat: "{appname}-win-x64-{tag}.exe", + fileFormat: '{appname}-win-x64-{tag}.exe', }, { - name: "Download for Linux (AppImage)", + name: 'Download for Linux (AppImage)', logo: FaLinux, - fileFormat: "{appname}-linux-x86_64-{tag}.AppImage", + fileFormat: '{appname}-linux-x86_64-{tag}.AppImage', }, { - name: "Download for Linux (deb)", + name: 'Download for Linux (deb)', logo: FaLinux, - fileFormat: "{appname}-linux-amd64-{tag}.deb", - } -]; + fileFormat: '{appname}-linux-amd64-{tag}.deb', + }, +] function classNames(...classes) { - return classes.filter(Boolean).join(" "); + return classes.filter(Boolean).join(' ') } export default function Dropdown() { - const [systems, setSystems] = useState(systemsTemplate); - const [defaultSystem, setDefaultSystem] = useState(systems[0]); + const [systems, setSystems] = useState(systemsTemplate) + const [defaultSystem, setDefaultSystem] = useState(systems[0]) const getLatestReleaseInfo = async (repoOwner, repoName) => { - const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`; + const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest` try { - const response = await axios.get(url); - return response.data; + const response = await axios.get(url) + return response.data } catch (error) { - console.error(error); - return null; + console.error(error) + return null } - }; + } const extractAppName = (fileName) => { // Extract appname using a regex that matches the provided file formats - const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/; - const match = fileName.match(regex); - return match ? match[1] : null; - }; + const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/ + const match = fileName.match(regex) + return match ? match[1] : null + } const changeDefaultSystem = async (systems) => { - const userAgent = navigator.userAgent; + const userAgent = navigator.userAgent - if (userAgent.includes("Windows")) { + if (userAgent.includes('Windows')) { // windows user - setDefaultSystem(systems[2]); - } else if (userAgent.includes("Linux")) { + setDefaultSystem(systems[2]) + } else if (userAgent.includes('Linux')) { // linux user - setDefaultSystem(systems[3]); - } else if (userAgent.includes("Mac OS")) { - setDefaultSystem(systems[0]); + setDefaultSystem(systems[3]) + } else if (userAgent.includes('Mac OS')) { + setDefaultSystem(systems[0]) } else { - setDefaultSystem(systems[1]); + setDefaultSystem(systems[1]) } - }; + } useEffect(() => { const updateDownloadLinks = async () => { try { - const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); + const releaseInfo = await getLatestReleaseInfo('janhq', 'jan') // Extract appname from the first asset name - const firstAssetName = releaseInfo.assets[0].name; - const appname = extractAppName(firstAssetName); + const firstAssetName = releaseInfo.assets[0].name + const appname = extractAppName(firstAssetName) if (!appname) { console.error( - "Failed to extract appname from file name:", + 'Failed to extract appname from file name:', firstAssetName - ); - changeDefaultSystem(systems); - return; + ) + changeDefaultSystem(systems) + return } // Remove 'v' at the start of the tag_name - const tag = releaseInfo.tag_name.startsWith("v") + const tag = releaseInfo.tag_name.startsWith('v') ? releaseInfo.tag_name.substring(1) - : releaseInfo.tag_name; + : releaseInfo.tag_name const updatedSystems = systems.map((system) => { const downloadUrl = system.fileFormat - .replace("{appname}", appname) - .replace("{tag}", tag); + .replace('{appname}', appname) + .replace('{tag}', tag) return { ...system, href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, - }; - }); + } + }) - setSystems(updatedSystems); - changeDefaultSystem(updatedSystems); + setSystems(updatedSystems) + changeDefaultSystem(updatedSystems) } catch (error) { - console.error("Failed to update download links:", error); + console.error('Failed to update download links:', error) } - }; + } - updateDownloadLinks(); - }, []); + updateDownloadLinks() + }, []) return (
{defaultSystem.name} - + Open OS options @@ -141,7 +141,7 @@ export default function Dropdown() { leaveFrom="transform opacity-100 scale-100" leaveTo="transform opacity-0 scale-95" > - +
{systems.map((system) => ( {({ active }) => ( - + {system.name} @@ -171,5 +171,5 @@ export default function Dropdown() {
- ); + ) } diff --git a/docs/src/containers/Footer/index.js b/docs/src/containers/Footer/index.js index 3e62f579a..fa7bf83e7 100644 --- a/docs/src/containers/Footer/index.js +++ b/docs/src/containers/Footer/index.js @@ -1,134 +1,208 @@ -import React from "react"; +import React from 'react' -import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; -import { BiLogoDiscordAlt, BiLogoLinkedin } from "react-icons/bi"; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext' +import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai' +import { BiLogoDiscordAlt, BiLogoLinkedin } from 'react-icons/bi' +import { useForm } from 'react-hook-form' const socials = [ { - icon: , - href: "https://twitter.com/janframework", + icon: ( + + ), + href: 'https://twitter.com/janframework', }, { - icon: , - href: "https://discord.com/invite/FTk2MvZwJH", + icon: ( + + ), + href: 'https://discord.com/invite/FTk2MvZwJH', }, { - icon: , - href: "https://github.com/janhq/jan", + icon: ( + + ), + href: 'https://github.com/janhq/jan', }, { - icon: , - href: "https://www.linkedin.com/company/janframework/", - } -]; + icon: ( + + ), + href: 'https://www.linkedin.com/company/janframework/', + }, +] const menus = [ { - name: "For Developers", + name: 'Product', child: [ { - menu: "Documentation", - path: "/developer", + menu: 'Download', + path: '/download', }, { - menu: "Hardware", - path: "/hardware", + menu: 'Documentation', + path: '/developer', }, { - menu: "API Reference", - path: "/api-reference", - }, - { - menu: "Changelog", - path: "https://github.com/janhq/jan/releases", + menu: 'Changelog', + path: 'https://github.com/janhq/jan/releases', external: true, }, ], }, { - name: "Community", + name: 'For Developers', child: [ { - menu: "Github", - path: "https://github.com/janhq/jan", - external: true, + menu: 'Guides', + path: '/guides', }, { - menu: "Discord", - path: "https://discord.gg/FTk2MvZwJH", - external: true, + menu: 'Developer', + path: '/developer', }, { - menu: "Twitter", - path: "https://twitter.com/janframework", - external: true, + menu: 'API Reference', + path: '/api-reference', }, - { - menu: "LinkedIn", - path: "https://www.linkedin.com/company/janframework/", - external: true, - } ], }, { - name: "Company", + name: 'Community', child: [ { - menu: "About", - path: "/about", - }, - { - menu: "Blog", - path: "/blog", - }, - { - menu: "Careers", - path: "https://janai.bamboohr.com/careers", + menu: 'Github', + path: 'https://github.com/janhq/jan', external: true, }, { - menu: "Newsletter", - path: "/community#newsletter", - } + menu: 'Discord', + path: 'https://discord.gg/FTk2MvZwJH', + external: true, + }, + { + menu: 'Twitter', + path: 'https://twitter.com/janframework', + external: true, + }, + { + menu: 'LinkedIn', + path: 'https://www.linkedin.com/company/janframework/', + external: true, + }, ], }, -]; + { + name: 'Company', + child: [ + { + menu: 'About', + path: '/about', + }, + { + menu: 'Blog', + path: '/blog', + }, + { + menu: 'Careers', + path: 'https://janai.bamboohr.com/careers', + external: true, + }, + { + menu: 'Newsletter', + path: '/community#newsletter', + }, + ], + }, +] -const getCurrentYear = new Date().getFullYear(); +const getCurrentYear = new Date().getFullYear() export default function Footer() { + const { register, handleSubmit, reset } = useForm({ + defaultValues: { + email: '', + }, + }) + + const { + siteConfig: { customFields }, + } = useDocusaurusContext() + + const onSubmit = (data) => { + const { email } = data + const options = { + method: 'POST', + headers: { + 'accept': 'application/json', + 'content-type': 'application/json', + 'api-key': customFields.apiKeyBrevo, + }, + body: JSON.stringify({ + updateEnabled: false, + email, + listIds: [13], + }), + } + + if (email) { + fetch('https://api.brevo.com/v3/contacts', options) + .then((response) => response.json()) + .then((response) => { + if (response.id) { + reset() + } + }) + .catch((err) => console.error(err)) + } + } + return ( -