Skip to content

Commit

Permalink
feat: jan on web - experimental
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-jan committed Dec 23, 2024
1 parent 7140978 commit 53026f4
Show file tree
Hide file tree
Showing 8 changed files with 386 additions and 37 deletions.
2 changes: 2 additions & 0 deletions extensions/inference-cortex-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
* @returns
*/
private clean(): Promise<any> {
// @ts-ignore
if (!window.electronAPI) return Promise.resolve()
return ky
.delete(`${CORTEX_API_URL}/processmanager/destroy`, {
timeout: 2000, // maximum 2 seconds
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
"copy:assets": "cpx \"pre-install/*.tgz\" \"electron/pre-install/\" && cpx \"themes/**\" \"electron/themes\"",
"dev:electron": "yarn copy:assets && yarn workspace jan dev",
"dev:web": "yarn workspace @janhq/web dev",
"dev:web:standalone": "concurrently \"yarn workspace @janhq/web dev\" \"wait-on http://localhost:3000 && rsync -av --prune-empty-dirs --include '*/' --include 'dist/***' --include 'package.json' --include 'tsconfig.json' --exclude '*' ./extensions/ web/.next/static/extensions/\"",
"dev:server": "yarn workspace @janhq/server dev",
"dev": "turbo run dev --parallel --filter=!@janhq/server",
"build:server": "cd server && yarn install && yarn run build",
"build:core": "cd core && yarn install && yarn run build",
"build:web": "yarn workspace @janhq/web build && cpx \"web/out/**\" \"electron/renderer/\"",
"build:web": "yarn workspace @janhq/web build cpx \"web/out/**\" \"electron/renderer/\"",
"build:electron": "yarn copy:assets && yarn workspace jan build",
"build:electron:test": "yarn workspace jan build:test",
"build:extensions": "rimraf ./pre-install/*.tgz && turbo run @janhq/core#build && cd extensions && yarn install && turbo run build:publish && cd .. && yarn pre-install",
Expand Down
44 changes: 23 additions & 21 deletions web/extension/ExtensionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import { AIEngine, BaseExtension, ExtensionTypeEnum } from '@janhq/core'

import WebExtensions from './../extensions.json'

import Extension from './Extension'

/**
Expand Down Expand Up @@ -99,21 +101,26 @@ export class ExtensionManager {
* @returns An array of extensions.
*/
async getActive(): Promise<Extension[]> {
const res = await window.core?.api?.getActiveExtensions()
if (!res || !Array.isArray(res)) return []

const extensions: Extension[] = res.map(
(ext: any) =>
new Extension(
ext.url,
ext.name,
ext.productName,
ext.active,
ext.description,
ext.version
)
)
return extensions
if (window.electronAPI) {
const res = await window.core?.api?.getActiveExtensions()

if (!res || !Array.isArray(res)) return []

const extensions: Extension[] = res.map(
(ext: any) =>
new Extension(
ext.url,
ext.name,
ext.productName,
ext.active,
ext.description,
ext.version
)
)
return extensions
} else {
return WebExtensions
}
}

/**
Expand All @@ -123,12 +130,7 @@ export class ExtensionManager {
*/
async activateExtension(extension: Extension) {
// Import class
const extensionUrl = window.electronAPI
? extension.url
: extension.url.replace(
'extension://',
`${window.core?.api?.baseApiUrl ?? ''}/extensions/`
)
const extensionUrl = extension.url
await import(/* webpackIgnore: true */ extensionUrl).then(
(extensionClass) => {
// Register class if it has a default export
Expand Down
182 changes: 182 additions & 0 deletions web/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
[
{
"_active": true,
"listeners": {},
"origin": "janhq-conversational-extension-1.0.0.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/conversational-extension",
"productName": "Conversational",
"version": "1.0.0",
"main": "dist/index.js",
"description": "This extension enables conversations and state persistence via your filesystem",
"url": "../../extensions/conversational-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-model-extension-1.0.35.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/model-extension",
"productName": "Model Management",
"version": "1.0.35",
"main": "dist/index.js",
"description": "Model Management Extension provides model exploration and seamless downloads",
"url": "../../extensions/model-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-anthropic-extension-1.0.3.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-anthropic-extension",
"productName": "Anthropic Inference Engine",
"version": "1.0.3",
"main": "dist/index.js",
"description": "This extension enables Anthropic chat completion API calls",
"url": "../../extensions/inference-anthropic-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-martian-extension-1.0.1.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-martian-extension",
"productName": "Martian Inference Engine",
"version": "1.0.1",
"main": "dist/index.js",
"description": "This extension enables Martian chat completion API calls",
"url": "../../extensions/inference-martian-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-nvidia-extension-1.0.1.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-nvidia-extension",
"productName": "NVIDIA NIM Inference Engine",
"version": "1.0.1",
"main": "dist/index.js",
"description": "This extension enables NVIDIA chat completion API calls",
"url": "../../extensions/inference-nvidia-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-openrouter-extension-1.0.0.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-openrouter-extension",
"productName": "OpenRouter Inference Engine",
"version": "1.0.0",
"main": "dist/index.js",
"description": "This extension enables Open Router chat completion API calls",
"url": "../../extensions/inference-openrouter-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-cohere-extension-1.0.0.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-cohere-extension",
"productName": "Cohere Inference Engine",
"version": "1.0.0",
"main": "dist/index.js",
"description": "This extension enables Cohere chat completion API calls",
"url": "../../extensions/inference-cohere-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-groq-extension-1.0.1.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-groq-extension",
"productName": "Groq Inference Engine",
"version": "1.0.1",
"main": "dist/index.js",
"description": "This extension enables fast Groq chat completion API calls",
"url": "../../extensions/inference-groq-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-openai-extension-1.0.5.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-openai-extension",
"productName": "OpenAI Inference Engine",
"version": "1.0.5",
"main": "dist/index.js",
"description": "This extension enables OpenAI chat completion API calls",
"url": "../../extensions/inference-openai-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-mistral-extension-1.0.1.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-mistral-extension",
"productName": "MistralAI Inference Engine",
"version": "1.0.1",
"main": "dist/index.js",
"description": "This extension enables Mistral chat completion API calls",
"url": "../../extensions/inference-mistral-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-triton-trt-llm-extension-1.0.0.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-triton-trt-llm-extension",
"productName": "Triton-TRT-LLM Inference Engine",
"version": "1.0.0",
"main": "dist/index.js",
"description": "This extension enables Nvidia's TensorRT-LLM as an inference engine option",
"url": "../../extensions/inference-triton-trtllm-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-monitoring-extension-1.0.10.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/monitoring-extension",
"productName": "System Monitoring",
"version": "1.0.10",
"main": "dist/index.js",
"description": "This extension provides system health and OS level data",
"url": "../../extensions/monitoring-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-assistant-extension-1.0.1.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/assistant-extension",
"productName": "Jan Assistant",
"version": "1.0.1",
"main": "dist/index.js",
"description": "This extension enables assistants, including Jan, a default assistant that can call all downloaded models",
"url": "../../extensions/assistant-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-tensorrt-llm-extension-0.0.3.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/tensorrt-llm-extension",
"productName": "TensorRT-LLM Inference Engine",
"version": "0.0.3",
"main": "dist/index.js",
"description": "This extension enables Nvidia's TensorRT-LLM for the fastest GPU acceleration. See the [setup guide](https://jan.ai/guides/providers/tensorrt-llm/) for next steps.",
"url": "../../extensions/tensorrt-llm-extension/dist/index.js"
},
{
"_active": true,
"listeners": {},
"origin": "janhq-inference-cortex-extension-1.0.24.tgz",
"installOptions": { "version": false, "fullMetadata": true },
"name": "@janhq/inference-cortex-extension",
"productName": "Cortex Inference Engine",
"version": "1.0.24",
"main": "dist/index.js",
"description": "This extension embeds cortex.cpp, a lightweight inference engine written in C++. See https://jan.ai.\nAdditional dependencies could be installed to run without Cuda Toolkit installation.",
"url": "../../extensions/inference-cortex-extension/dist/index.js"
}
]
11 changes: 11 additions & 0 deletions web/hooks/useLoadTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
themeDataAtom,
themesOptionsAtom,
} from '@/helpers/atoms/Setting.atom'
import DefaultTheme from '@/theme.json'

type NativeThemeProps = 'light' | 'dark'

Expand Down Expand Up @@ -85,6 +86,16 @@ export const useLoadTheme = () => {
])

const applyTheme = useCallback(async () => {
if (!window.electronAPI) {
const theme = DefaultTheme as Theme
setThemeData(theme)
const variables = cssVars(theme.variables)
const headTag = document.getElementsByTagName('head')[0]
const styleTag = document.createElement('style')
styleTag.innerHTML = `:root {${variables}}`
headTag.appendChild(styleTag)
return
}
if (!themeData || !themeOptions || !themePath) {
await getThemes()
} else {
Expand Down
12 changes: 6 additions & 6 deletions web/hooks/useModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ const useModels = () => {
ModelManager.instance().models.get(e.id)?.metadata ?? e.metadata,
}))

const remoteModels = ModelManager.instance()
.models.values()
.toArray()
.filter((e) => !isLocalEngine(e.engine))
const remoteModels = Array.from(
ModelManager.instance().models.values()
).filter((e) => !isLocalEngine(e.engine))

const toUpdate = [
...localModels,
...remoteModels.filter(
Expand All @@ -68,7 +68,7 @@ const useModels = () => {
}

const getExtensionModels = () => {
const models = ModelManager.instance().models.values().toArray()
const models = Array.from(ModelManager.instance().models.values())
setExtensionModels(models)
}
// Fetch all data
Expand All @@ -79,7 +79,7 @@ const useModels = () => {
const reloadData = useDebouncedCallback(() => getData(), 300)

const updateStates = useCallback(() => {
const cachedModels = ModelManager.instance().models.values().toArray()
const cachedModels = Array.from(ModelManager.instance().models.values())
setDownloadedModels((downloadedModels) => [
...downloadedModels,
...cachedModels.filter(
Expand Down
25 changes: 16 additions & 9 deletions web/hooks/useSendChatMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,22 @@ export default function useSendChatMessage() {
setIsGeneratingResponse(true)

// Process message request with Assistants tools
const request = await ToolManager.instance().process(
requestBuilder.build(),
activeAssistantRef?.current.tools ?? []
)

// Request for inference
EngineManager.instance()
.get(requestBuilder.model?.engine ?? modelRequest.engine ?? '')
?.inference(request)
if (window.electronAPI) {
const request = await ToolManager.instance().process(
requestBuilder.build(),
activeAssistantRef?.current.tools ?? []
)

// Request for inference
EngineManager.instance()
.get(requestBuilder.model?.engine ?? modelRequest.engine ?? '')
?.inference(request)
} else {
// Request for inference
EngineManager.instance()
.get(requestBuilder.model?.engine ?? modelRequest.engine ?? '')
?.inference(requestBuilder.build())
}

// Reset states
setReloadModel(false)
Expand Down
Loading

0 comments on commit 53026f4

Please sign in to comment.