Merge branch 'dev' of https://github.com/janhq/jan into dev
This commit is contained in:
commit
b2ab5423df
@ -44,16 +44,17 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.base_ref }}
|
||||
- name: Use Node.js v20.9.0
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: v20.9.0
|
||||
node-version: 20
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
make config-yarn
|
||||
yarn
|
||||
yarn build:core
|
||||
yarn build:joi
|
||||
yarn build:core
|
||||
|
||||
- name: Run test coverage
|
||||
run: yarn test:coverage
|
||||
@ -66,7 +67,7 @@ jobs:
|
||||
|
||||
test-on-macos:
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
runs-on: [self-hosted, macOS, macos-desktop]
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Getting the repo
|
||||
uses: actions/checkout@v3
|
||||
@ -78,6 +79,10 @@ jobs:
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set IS_TEST environment variable
|
||||
run: |
|
||||
echo "IS_TEST=true" >> $GITHUB_ENV
|
||||
|
||||
- name: 'Cleanup cache'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
@ -100,18 +105,13 @@ jobs:
|
||||
|
||||
- name: Linter and test
|
||||
run: |
|
||||
npm config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
yarn config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
make test
|
||||
env:
|
||||
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
|
||||
# TURBO_API: '${{ secrets.TURBO_API }}'
|
||||
# TURBO_TEAM: 'macos'
|
||||
# TURBO_TOKEN: '${{ secrets.TURBO_TOKEN }}'
|
||||
|
||||
test-on-macos-pr-target:
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
|
||||
runs-on: [self-hosted, macOS, macos-desktop]
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Getting the repo
|
||||
uses: actions/checkout@v3
|
||||
@ -131,8 +131,6 @@ jobs:
|
||||
|
||||
- name: Linter and test
|
||||
run: |
|
||||
npm config set registry https://registry.npmjs.org --global
|
||||
yarn config set registry https://registry.npmjs.org --global
|
||||
make test
|
||||
env:
|
||||
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
|
||||
@ -182,13 +180,8 @@ jobs:
|
||||
- name: Linter and test
|
||||
shell: powershell
|
||||
run: |
|
||||
npm config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
yarn config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
make test
|
||||
# env:
|
||||
# TURBO_API: '${{ secrets.TURBO_API }}'
|
||||
# TURBO_TEAM: 'windows'
|
||||
# TURBO_TOKEN: '${{ secrets.TURBO_TOKEN }}'
|
||||
|
||||
test-on-windows-pr:
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
|
||||
runs-on: windows-desktop-default-windows-security
|
||||
@ -199,7 +192,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Installing node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
@ -230,17 +223,11 @@ jobs:
|
||||
- name: Linter and test
|
||||
shell: powershell
|
||||
run: |
|
||||
npm config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
yarn config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
make test
|
||||
# env:
|
||||
# TURBO_API: '${{ secrets.TURBO_API }}'
|
||||
# TURBO_TEAM: 'windows'
|
||||
# TURBO_TOKEN: '${{ secrets.TURBO_TOKEN }}'
|
||||
|
||||
test-on-windows-pr-target:
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
|
||||
runs-on: windows-desktop-default-windows-security
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Getting the repo
|
||||
uses: actions/checkout@v3
|
||||
@ -268,12 +255,10 @@ jobs:
|
||||
- name: Linter and test
|
||||
shell: powershell
|
||||
run: |
|
||||
npm config set registry https://registry.npmjs.org --global
|
||||
yarn config set registry https://registry.npmjs.org --global
|
||||
make test
|
||||
|
||||
test-on-ubuntu:
|
||||
runs-on: [self-hosted, Linux, ubuntu-desktop]
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
- name: Getting the repo
|
||||
@ -311,13 +296,7 @@ jobs:
|
||||
run: |
|
||||
export DISPLAY=$(w -h | awk 'NR==1 {print $2}')
|
||||
echo -e "Display ID: $DISPLAY"
|
||||
npm config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
yarn config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
make test
|
||||
# env:
|
||||
# TURBO_API: '${{ secrets.TURBO_API }}'
|
||||
# TURBO_TEAM: 'linux'
|
||||
# TURBO_TOKEN: '${{ secrets.TURBO_TOKEN }}'
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
@ -327,7 +306,7 @@ jobs:
|
||||
retention-days: 2
|
||||
|
||||
coverage-check:
|
||||
runs-on: [self-hosted, Linux, ubuntu-desktop]
|
||||
runs-on: ubuntu-latest
|
||||
needs: base_branch_cov
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
@ -341,6 +320,9 @@ jobs:
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Install yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: 'Cleanup cache'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
@ -356,15 +338,9 @@ jobs:
|
||||
run: |
|
||||
export DISPLAY=$(w -h | awk 'NR==1 {print $2}')
|
||||
echo -e "Display ID: $DISPLAY"
|
||||
npm config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
yarn config set registry ${{ secrets.NPM_PROXY }} --global
|
||||
make lint
|
||||
yarn build:test
|
||||
yarn test:coverage
|
||||
# env:
|
||||
# TURBO_API: '${{ secrets.TURBO_API }}'
|
||||
# TURBO_TEAM: 'linux'
|
||||
# TURBO_TOKEN: '${{ secrets.TURBO_TOKEN }}'
|
||||
|
||||
- name: Generate Code Coverage report
|
||||
id: code-coverage
|
||||
@ -377,7 +353,7 @@ jobs:
|
||||
show-annotations: 'warning'
|
||||
|
||||
test-on-ubuntu-pr-target:
|
||||
runs-on: [self-hosted, Linux, ubuntu-desktop]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- name: Getting the repo
|
||||
@ -400,6 +376,4 @@ jobs:
|
||||
run: |
|
||||
export DISPLAY=$(w -h | awk 'NR==1 {print $2}')
|
||||
echo -e "Display ID: $DISPLAY"
|
||||
npm config set registry https://registry.npmjs.org --global
|
||||
yarn config set registry https://registry.npmjs.org --global
|
||||
make test
|
||||
|
||||
4
.github/workflows/publish-npm-core.yml
vendored
4
.github/workflows/publish-npm-core.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Publish plugin models Package to npmjs
|
||||
name: Publish core Package to npmjs
|
||||
on:
|
||||
push:
|
||||
tags: ["v[0-9]+.[0-9]+.[0-9]+-core"]
|
||||
@ -45,7 +45,7 @@ jobs:
|
||||
node-version: "20.x"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- run: cd core && yarn install && yarn build
|
||||
- run: cd core && corepack enable && corepack prepare yarn@4.5.3 --activate && yarn --version && yarn install && yarn build
|
||||
|
||||
- run: cd core && yarn publish --access public
|
||||
if: github.event_name == 'push'
|
||||
|
||||
4
.github/workflows/publish-npm-joi.yml
vendored
4
.github/workflows/publish-npm-joi.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Publish plugin models Package to npmjs
|
||||
name: Publish joi Package to npmjs
|
||||
on:
|
||||
push:
|
||||
tags: ["v[0-9]+.[0-9]+.[0-9]+-joi"]
|
||||
@ -45,7 +45,7 @@ jobs:
|
||||
node-version: "20.x"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- run: cd joi && yarn install && yarn build
|
||||
- run: cd joi && corepack enable && corepack prepare yarn@4.5.3 --activate && yarn --version && yarn install && yarn build
|
||||
|
||||
- run: cd joi && yarn publish --access public
|
||||
if: github.event_name == 'push'
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -8,7 +8,6 @@ error.log
|
||||
node_modules
|
||||
*.tgz
|
||||
!charts/server/charts/*.tgz
|
||||
yarn.lock
|
||||
dist
|
||||
build
|
||||
.DS_Store
|
||||
@ -48,3 +47,7 @@ coverage
|
||||
test_results.html
|
||||
*.tsbuildinfo
|
||||
electron/shared/**
|
||||
|
||||
# docs
|
||||
docs/yarn.lock
|
||||
electron/.version.bak
|
||||
|
||||
3
.yarnrc.yml
Normal file
3
.yarnrc.yml
Normal file
@ -0,0 +1,3 @@
|
||||
nmHoistingLimits: workspaces
|
||||
nodeLinker: node-modules
|
||||
checksumBehavior: update
|
||||
31
Makefile
31
Makefile
@ -10,23 +10,23 @@ REPORT_PORTAL_DESCRIPTION ?= "Jan App report"
|
||||
all:
|
||||
@echo "Specify a target to run"
|
||||
|
||||
# Builds the UI kit
|
||||
build-joi:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
cd joi && yarn config set network-timeout 300000 && yarn install && yarn build
|
||||
else
|
||||
cd joi && yarn install && yarn build
|
||||
endif
|
||||
# Config yarn version
|
||||
|
||||
config-yarn:
|
||||
corepack enable
|
||||
corepack prepare yarn@4.5.3 --activate
|
||||
yarn --version
|
||||
yarn config set -H enableImmutableInstalls false
|
||||
|
||||
# Installs yarn dependencies and builds core and extensions
|
||||
install-and-build: build-joi
|
||||
install-and-build: config-yarn
|
||||
ifeq ($(OS),Windows_NT)
|
||||
yarn config set network-timeout 300000
|
||||
echo "skip"
|
||||
endif
|
||||
yarn global add turbo@1.13.2
|
||||
yarn install
|
||||
yarn build:joi
|
||||
yarn build:core
|
||||
yarn build:server
|
||||
yarn install
|
||||
yarn build:extensions
|
||||
|
||||
check-file-counts: install-and-build
|
||||
@ -117,9 +117,8 @@ build: check-file-counts
|
||||
|
||||
clean:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
-powershell -Command "Get-ChildItem -Path . -Include node_modules, .next, dist, build, out, .turbo -Recurse -Directory | Remove-Item -Recurse -Force"
|
||||
-powershell -Command "Get-ChildItem -Path . -Include package-lock.json -Recurse -File | Remove-Item -Recurse -Force"
|
||||
-powershell -Command "Get-ChildItem -Path . -Include yarn.lock -Recurse -File | Remove-Item -Recurse -Force"
|
||||
-powershell -Command "Get-ChildItem -Path . -Include node_modules, .next, dist, build, out, .turbo, .yarn -Recurse -Directory | Remove-Item -Recurse -Force"
|
||||
-powershell -Command "Get-ChildItem -Path . -Include package-lock.json, tsconfig.tsbuildinfo -Recurse -File | Remove-Item -Recurse -Force"
|
||||
-powershell -Command "Remove-Item -Recurse -Force ./pre-install/*.tgz"
|
||||
-powershell -Command "Remove-Item -Recurse -Force ./extensions/*/*.tgz"
|
||||
-powershell -Command "Remove-Item -Recurse -Force ./electron/pre-install/*.tgz"
|
||||
@ -131,8 +130,8 @@ else ifeq ($(shell uname -s),Linux)
|
||||
find . -name "build" -type d -exec rm -rf '{}' +
|
||||
find . -name "out" -type d -exec rm -rf '{}' +
|
||||
find . -name ".turbo" -type d -exec rm -rf '{}' +
|
||||
find . -name ".yarn" -type d -exec rm -rf '{}' +
|
||||
find . -name "packake-lock.json" -type f -exec rm -rf '{}' +
|
||||
find . -name "yarn.lock" -type f -exec rm -rf '{}' +
|
||||
find . -name "package-lock.json" -type f -exec rm -rf '{}' +
|
||||
rm -rf ./pre-install/*.tgz
|
||||
rm -rf ./extensions/*/*.tgz
|
||||
@ -146,8 +145,8 @@ else
|
||||
find . -name "build" -type d -exec rm -rf '{}' +
|
||||
find . -name "out" -type d -exec rm -rf '{}' +
|
||||
find . -name ".turbo" -type d -exec rm -rf '{}' +
|
||||
find . -name ".yarn" -type d -exec rm -rf '{}' +
|
||||
find . -name "package-lock.json" -type f -exec rm -rf '{}' +
|
||||
find . -name "yarn.lock" -type f -exec rm -rf '{}' +
|
||||
rm -rf ./pre-install/*.tgz
|
||||
rm -rf ./extensions/*/*.tgz
|
||||
rm -rf ./electron/pre-install/*.tgz
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "@janhq/core",
|
||||
"version": "0.1.10",
|
||||
"description": "Jan app core lib",
|
||||
"description": "Core library for the Jan AI application framework",
|
||||
"keywords": [
|
||||
"jan",
|
||||
"core"
|
||||
],
|
||||
"homepage": "https://jan.ai",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "dist/core.es5.js",
|
||||
"module": "dist/core.cjs.js",
|
||||
"browser": "dist/index.js",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/node/index.cjs.js",
|
||||
"typings": "dist/types/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
@ -17,13 +18,13 @@
|
||||
],
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"exports": {
|
||||
".": "./dist/core.es5.js",
|
||||
".": "./dist/index.js",
|
||||
"./node": "./dist/node/index.cjs.js"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
".": [
|
||||
"./dist/core.es5.js.map",
|
||||
"./dist/index.js.map",
|
||||
"./dist/types/index.d.ts"
|
||||
],
|
||||
"node": [
|
||||
@ -36,25 +37,25 @@
|
||||
"lint": "tslint --project tsconfig.json -t codeFrame 'src/**/*.ts' 'test/**/*.ts'",
|
||||
"test": "jest",
|
||||
"prebuild": "rimraf dist",
|
||||
"build": "tsc --module commonjs && rollup -c rollup.config.ts",
|
||||
"start": "rollup -c rollup.config.ts -w"
|
||||
"build": "tsc -p . && rolldown -c rolldown.config.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20.11.4",
|
||||
"@npmcli/arborist": "^7.1.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.10.0",
|
||||
"@types/pacote": "^11.1.7",
|
||||
"@types/request": "^2.48.12",
|
||||
"electron": "33.2.1",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-junit": "^16.0.0",
|
||||
"jest-runner": "^29.7.0",
|
||||
"pacote": "^21.0.0",
|
||||
"request": "^2.88.2",
|
||||
"request-progress": "^3.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.38.5",
|
||||
"rollup-plugin-commonjs": "^9.1.8",
|
||||
"rollup-plugin-json": "^3.1.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"rollup-plugin-typescript2": "^0.36.0",
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-jest": "^29.2.5",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3"
|
||||
@ -62,5 +63,6 @@
|
||||
"dependencies": {
|
||||
"rxjs": "^7.8.1",
|
||||
"ulidx": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
51
core/rolldown.config.mjs
Normal file
51
core/rolldown.config.mjs
Normal file
@ -0,0 +1,51 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
sourcemap: true,
|
||||
},
|
||||
platform: 'browser',
|
||||
external: ['path'],
|
||||
define: {
|
||||
NODE: JSON.stringify(`${pkgJson.name}/${pkgJson.node}`),
|
||||
VERSION: JSON.stringify(pkgJson.version),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'src/node/index.ts',
|
||||
external: [
|
||||
'fs/promises',
|
||||
'path',
|
||||
'pacote',
|
||||
'@types/pacote',
|
||||
'@npmcli/arborist',
|
||||
'ulidx',
|
||||
'node-fetch',
|
||||
'fs',
|
||||
'request',
|
||||
'crypto',
|
||||
'url',
|
||||
'http',
|
||||
'os',
|
||||
'util',
|
||||
'child_process',
|
||||
'electron',
|
||||
'request-progress',
|
||||
],
|
||||
output: {
|
||||
format: 'cjs',
|
||||
file: 'dist/node/index.cjs.js',
|
||||
sourcemap: true,
|
||||
inlineDynamicImports: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts'],
|
||||
},
|
||||
platform: 'node',
|
||||
},
|
||||
])
|
||||
@ -1,85 +0,0 @@
|
||||
import resolve from 'rollup-plugin-node-resolve'
|
||||
import commonjs from 'rollup-plugin-commonjs'
|
||||
import sourceMaps from 'rollup-plugin-sourcemaps'
|
||||
import typescript from 'rollup-plugin-typescript2'
|
||||
import json from 'rollup-plugin-json'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
|
||||
const pkg = require('./package.json')
|
||||
|
||||
export default [
|
||||
{
|
||||
input: `src/index.ts`,
|
||||
output: [
|
||||
// { file: pkg.main, name: libraryName, format: 'umd', sourcemap: true },
|
||||
{ file: pkg.main, format: 'es', sourcemap: true },
|
||||
],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: ['path'],
|
||||
watch: {
|
||||
include: 'src/**',
|
||||
},
|
||||
plugins: [
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({ useTsconfigDeclarationDir: true }),
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs(),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
replace({
|
||||
'preventAssignment': true,
|
||||
'node:crypto': 'crypto',
|
||||
'delimiters': ['"', '"'],
|
||||
}),
|
||||
resolve({
|
||||
browser: true,
|
||||
}),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: `src/node/index.ts`,
|
||||
output: [{ file: 'dist/node/index.cjs.js', format: 'cjs', sourcemap: true }],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: [
|
||||
'fs/promises',
|
||||
'path',
|
||||
'pacote',
|
||||
'@types/pacote',
|
||||
'@npmcli/arborist',
|
||||
'ulidx',
|
||||
'node-fetch',
|
||||
'fs',
|
||||
'request',
|
||||
'crypto',
|
||||
'url',
|
||||
'http',
|
||||
'os',
|
||||
'util',
|
||||
'child_process',
|
||||
],
|
||||
watch: {
|
||||
include: 'src/node/**',
|
||||
},
|
||||
plugins: [
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({ useTsconfigDeclarationDir: true }),
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs(),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
resolve(),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps(),
|
||||
],
|
||||
},
|
||||
]
|
||||
@ -1,4 +1,9 @@
|
||||
import { DownloadRequest, FileStat, NetworkConfig, SystemInformation } from '../types'
|
||||
import {
|
||||
DownloadRequest,
|
||||
FileStat,
|
||||
NetworkConfig,
|
||||
SystemInformation,
|
||||
} from '../types'
|
||||
|
||||
/**
|
||||
* Execute a extension module function in main process
|
||||
@ -9,11 +14,12 @@ import { DownloadRequest, FileStat, NetworkConfig, SystemInformation } from '../
|
||||
* @returns Promise<any>
|
||||
*
|
||||
*/
|
||||
const executeOnMain: (extension: string, method: string, ...args: any[]) => Promise<any> = (
|
||||
extension,
|
||||
method,
|
||||
...args
|
||||
) => globalThis.core?.api?.invokeExtensionFunc(extension, method, ...args)
|
||||
const executeOnMain: (
|
||||
extension: string,
|
||||
method: string,
|
||||
...args: any[]
|
||||
) => Promise<any> = (extension, method, ...args) =>
|
||||
globalThis.core?.api?.invokeExtensionFunc(extension, method, ...args)
|
||||
|
||||
/**
|
||||
* Downloads a file from a URL and saves it to the local file system.
|
||||
@ -23,10 +29,11 @@ const executeOnMain: (extension: string, method: string, ...args: any[]) => Prom
|
||||
*
|
||||
* @returns {Promise<any>} A promise that resolves when the file is downloaded.
|
||||
*/
|
||||
const downloadFile: (downloadRequest: DownloadRequest, network?: NetworkConfig) => Promise<any> = (
|
||||
downloadRequest,
|
||||
network
|
||||
) => globalThis.core?.api?.downloadFile(downloadRequest, network)
|
||||
const downloadFile: (
|
||||
downloadRequest: DownloadRequest,
|
||||
network?: NetworkConfig
|
||||
) => Promise<any> = (downloadRequest, network) =>
|
||||
globalThis.core?.api?.downloadFile(downloadRequest, network)
|
||||
|
||||
/**
|
||||
* Aborts the download of a specific file.
|
||||
@ -41,7 +48,8 @@ const abortDownload: (fileName: string) => Promise<any> = (fileName) =>
|
||||
*
|
||||
* @returns {Promise<string>} A Promise that resolves with Jan's data folder path.
|
||||
*/
|
||||
const getJanDataFolderPath = (): Promise<string> => globalThis.core.api?.getJanDataFolderPath()
|
||||
const getJanDataFolderPath = (): Promise<string> =>
|
||||
globalThis.core.api?.getJanDataFolderPath()
|
||||
|
||||
/**
|
||||
* Opens the file explorer at a specific path.
|
||||
@ -64,14 +72,16 @@ const joinPath: (paths: string[]) => Promise<string> = (paths) =>
|
||||
* @param path - The file path to retrieve dirname.
|
||||
* @returns {Promise<string>} A promise that resolves the dirname.
|
||||
*/
|
||||
const dirName: (path: string) => Promise<string> = (path) => globalThis.core.api?.dirName(path)
|
||||
const dirName: (path: string) => Promise<string> = (path) =>
|
||||
globalThis.core.api?.dirName(path)
|
||||
|
||||
/**
|
||||
* Retrieve the basename from an url.
|
||||
* @param path - The path to retrieve.
|
||||
* @returns {Promise<string>} A promise that resolves with the basename.
|
||||
*/
|
||||
const baseName: (paths: string) => Promise<string> = (path) => globalThis.core.api?.baseName(path)
|
||||
const baseName: (paths: string) => Promise<string> = (path) =>
|
||||
globalThis.core.api?.baseName(path)
|
||||
|
||||
/**
|
||||
* Opens an external URL in the default web browser.
|
||||
@ -87,13 +97,15 @@ const openExternalUrl: (url: string) => Promise<any> = (url) =>
|
||||
*
|
||||
* @returns {Promise<string>} - A promise that resolves with the resource path.
|
||||
*/
|
||||
const getResourcePath: () => Promise<string> = () => globalThis.core.api?.getResourcePath()
|
||||
const getResourcePath: () => Promise<string> = () =>
|
||||
globalThis.core.api?.getResourcePath()
|
||||
|
||||
/**
|
||||
* Gets the user's home path.
|
||||
* @returns return user's home path
|
||||
*/
|
||||
const getUserHomePath = (): Promise<string> => globalThis.core.api?.getUserHomePath()
|
||||
const getUserHomePath = (): Promise<string> =>
|
||||
globalThis.core.api?.getUserHomePath()
|
||||
|
||||
/**
|
||||
* Log to file from browser processes.
|
||||
@ -111,8 +123,10 @@ const log: (message: string, fileName?: string) => void = (message, fileName) =>
|
||||
*
|
||||
* @returns {Promise<boolean>} - A promise that resolves with a boolean indicating whether the path is a subdirectory.
|
||||
*/
|
||||
const isSubdirectory: (from: string, to: string) => Promise<boolean> = (from: string, to: string) =>
|
||||
globalThis.core.api?.isSubdirectory(from, to)
|
||||
const isSubdirectory: (from: string, to: string) => Promise<boolean> = (
|
||||
from: string,
|
||||
to: string
|
||||
) => globalThis.core.api?.isSubdirectory(from, to)
|
||||
|
||||
/**
|
||||
* Get system information
|
||||
@ -159,5 +173,4 @@ export {
|
||||
systemInformation,
|
||||
showToast,
|
||||
dirName,
|
||||
FileStat,
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ export enum ExtensionTypeEnum {
|
||||
Model = 'model',
|
||||
SystemMonitoring = 'systemMonitoring',
|
||||
HuggingFace = 'huggingFace',
|
||||
Engine = 'engine',
|
||||
}
|
||||
|
||||
export interface ExtensionType {
|
||||
|
||||
91
core/src/browser/extensions/enginesManagement.ts
Normal file
91
core/src/browser/extensions/enginesManagement.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import {
|
||||
InferenceEngine,
|
||||
Engines,
|
||||
EngineVariant,
|
||||
EngineReleased,
|
||||
DefaultEngineVariant,
|
||||
} from '../../types'
|
||||
import { BaseExtension, ExtensionTypeEnum } from '../extension'
|
||||
|
||||
/**
|
||||
* Engine management extension. Persists and retrieves engine management.
|
||||
* @abstract
|
||||
* @extends BaseExtension
|
||||
*/
|
||||
export abstract class EngineManagementExtension extends BaseExtension {
|
||||
type(): ExtensionTypeEnum | undefined {
|
||||
return ExtensionTypeEnum.Engine
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns A Promise that resolves to an object of list engines.
|
||||
*/
|
||||
abstract getEngines(): Promise<Engines>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to an array of installed engine.
|
||||
*/
|
||||
abstract getInstalledEngines(name: InferenceEngine): Promise<EngineVariant[]>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @param version - Version of the engine.
|
||||
* @param platform - Optional to sort by operating system. macOS, linux, windows.
|
||||
* @returns A Promise that resolves to an array of latest released engine by version.
|
||||
*/
|
||||
abstract getReleasedEnginesByVersion(
|
||||
name: InferenceEngine,
|
||||
version: string,
|
||||
platform?: string
|
||||
): Promise<EngineReleased[]>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @param platform - Optional to sort by operating system. macOS, linux, windows.
|
||||
* @returns A Promise that resolves to an array of latest released engine.
|
||||
*/
|
||||
abstract getLatestReleasedEngine(
|
||||
name: InferenceEngine,
|
||||
platform?: string
|
||||
): Promise<EngineReleased[]>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to intall of engine.
|
||||
*/
|
||||
abstract installEngine(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version?: string }
|
||||
): Promise<{ messages: string }>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to unintall of engine.
|
||||
*/
|
||||
abstract uninstallEngine(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version: string }
|
||||
): Promise<{ messages: string }>
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to an object of default engine.
|
||||
*/
|
||||
abstract getDefaultEngineVariant(name: InferenceEngine): Promise<DefaultEngineVariant>
|
||||
|
||||
/**
|
||||
* @body variant - string
|
||||
* @body version - string
|
||||
* @returns A Promise that resolves to set default engine.
|
||||
*/
|
||||
abstract setDefaultEngineVariant(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version: string }
|
||||
): Promise<{ messages: string }>
|
||||
|
||||
/**
|
||||
* @returns A Promise that resolves to update engine.
|
||||
*/
|
||||
abstract updateEngine(name: InferenceEngine): Promise<{ messages: string }>
|
||||
}
|
||||
@ -28,3 +28,8 @@ export { ModelExtension } from './model'
|
||||
* Base AI Engines.
|
||||
*/
|
||||
export * from './engines'
|
||||
|
||||
/**
|
||||
* Engines Management
|
||||
*/
|
||||
export * from './enginesManagement'
|
||||
|
||||
@ -4,16 +4,6 @@ jest.mock('../../helper', () => ({
|
||||
}))
|
||||
import { App } from './app'
|
||||
|
||||
it('should call stopServer', () => {
|
||||
const app = new App()
|
||||
const stopServerMock = jest.fn().mockResolvedValue('Server stopped')
|
||||
jest.mock('@janhq/server', () => ({
|
||||
stopServer: stopServerMock,
|
||||
}))
|
||||
app.stopServer()
|
||||
expect(stopServerMock).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should correctly retrieve basename', () => {
|
||||
const app = new App()
|
||||
const result = app.baseName('/path/to/file.txt')
|
||||
@ -23,7 +13,8 @@ it('should correctly retrieve basename', () => {
|
||||
it('should correctly identify subdirectories', () => {
|
||||
const app = new App()
|
||||
const basePath = process.platform === 'win32' ? 'C:\\path\\to' : '/path/to'
|
||||
const subPath = process.platform === 'win32' ? 'C:\\path\\to\\subdir' : '/path/to/subdir'
|
||||
const subPath =
|
||||
process.platform === 'win32' ? 'C:\\path\\to\\subdir' : '/path/to/subdir'
|
||||
const result = app.isSubdirectory(basePath, subPath)
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
@ -31,7 +22,8 @@ it('should correctly identify subdirectories', () => {
|
||||
it('should correctly join multiple paths', () => {
|
||||
const app = new App()
|
||||
const result = app.joinPath(['path', 'to', 'file'])
|
||||
const expectedPath = process.platform === 'win32' ? 'path\\to\\file' : 'path/to/file'
|
||||
const expectedPath =
|
||||
process.platform === 'win32' ? 'path\\to\\file' : 'path/to/file'
|
||||
expect(result).toBe(expectedPath)
|
||||
})
|
||||
|
||||
@ -52,5 +44,7 @@ it('should retrieve the directory name from a file path (Unix/Windows)', async (
|
||||
it('should retrieve the directory name when using file protocol', async () => {
|
||||
const app = new App()
|
||||
const path = 'file:/models/file.txt'
|
||||
expect(await app.dirName(path)).toBe(process.platform === 'win32' ? 'app\\models' : 'app/models')
|
||||
expect(await app.dirName(path)).toBe(
|
||||
process.platform === 'win32' ? 'app\\models' : 'app/models'
|
||||
)
|
||||
})
|
||||
|
||||
@ -44,11 +44,8 @@ export class App implements Processor {
|
||||
/**
|
||||
* Checks if the given path is a subdirectory of the given directory.
|
||||
*
|
||||
* @param _event - The IPC event object.
|
||||
* @param from - The path to check.
|
||||
* @param to - The directory to check against.
|
||||
*
|
||||
* @returns {Promise<boolean>} - A promise that resolves with the result.
|
||||
*/
|
||||
isSubdirectory(from: any, to: any) {
|
||||
const rel = relative(from, to)
|
||||
@ -79,26 +76,4 @@ export class App implements Processor {
|
||||
async updateAppConfiguration(args: any) {
|
||||
await updateAppConfiguration(args)
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Jan API Server.
|
||||
*/
|
||||
async startServer(args?: any) {
|
||||
const { startServer } = require('@janhq/server')
|
||||
return startServer({
|
||||
host: args?.host,
|
||||
port: args?.port,
|
||||
isCorsEnabled: args?.isCorsEnabled,
|
||||
isVerboseEnabled: args?.isVerboseEnabled,
|
||||
prefix: args?.prefix,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop Jan API Server.
|
||||
*/
|
||||
stopServer() {
|
||||
const { stopServer } = require('@janhq/server')
|
||||
return stopServer()
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,10 @@ export default class Extension {
|
||||
* @type {string}
|
||||
*/
|
||||
get specifier() {
|
||||
return this.origin + (this.installOptions.version ? '@' + this.installOptions.version : '')
|
||||
return (
|
||||
this.origin +
|
||||
(this.installOptions.version ? '@' + this.installOptions.version : '')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,8 +78,10 @@ export default class Extension {
|
||||
async getManifest() {
|
||||
// Get the package's manifest (package.json object)
|
||||
try {
|
||||
await import('pacote').then((pacote) => {
|
||||
return pacote.manifest(this.specifier, this.installOptions).then((mnf) => {
|
||||
const pacote = require('pacote')
|
||||
return pacote
|
||||
.manifest(this.specifier, this.installOptions)
|
||||
.then((mnf: any) => {
|
||||
// set the Package properties based on the it's manifest
|
||||
this.name = mnf.name
|
||||
this.productName = mnf.productName as string | undefined
|
||||
@ -84,9 +89,10 @@ export default class Extension {
|
||||
this.main = mnf.main
|
||||
this.description = mnf.description
|
||||
})
|
||||
})
|
||||
} catch (error) {
|
||||
throw new Error(`Package ${this.origin} does not contain a valid manifest: ${error}`)
|
||||
throw new Error(
|
||||
`Package ${this.origin} does not contain a valid manifest: ${error}`
|
||||
)
|
||||
}
|
||||
|
||||
return true
|
||||
@ -103,10 +109,13 @@ export default class Extension {
|
||||
await this.getManifest()
|
||||
|
||||
// Install the package in a child folder of the given folder
|
||||
const pacote = await import('pacote')
|
||||
const pacote = require('pacote')
|
||||
await pacote.extract(
|
||||
this.specifier,
|
||||
join(ExtensionManager.instance.getExtensionsPath() ?? '', this.name ?? ''),
|
||||
join(
|
||||
ExtensionManager.instance.getExtensionsPath() ?? '',
|
||||
this.name ?? ''
|
||||
),
|
||||
this.installOptions
|
||||
)
|
||||
|
||||
@ -169,13 +178,12 @@ export default class Extension {
|
||||
* @returns the latest available version if a new version is available or false if not.
|
||||
*/
|
||||
async isUpdateAvailable() {
|
||||
return import('pacote').then((pacote) => {
|
||||
const pacote = require('pacote')
|
||||
if (this.origin) {
|
||||
return pacote.manifest(this.origin).then((mnf) => {
|
||||
return pacote.manifest(this.origin).then((mnf: any) => {
|
||||
return mnf.version !== this.version ? mnf.version : false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -27,7 +27,10 @@ export enum NativeRoute {
|
||||
|
||||
quickAskSizeUpdated = 'quickAskSizeUpdated',
|
||||
ackDeepLink = 'ackDeepLink',
|
||||
factoryReset = 'factoryReset'
|
||||
factoryReset = 'factoryReset',
|
||||
|
||||
startServer = 'startServer',
|
||||
stopServer = 'stopServer',
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,8 +44,6 @@ export enum AppRoute {
|
||||
dirName = 'dirName',
|
||||
isSubdirectory = 'isSubdirectory',
|
||||
baseName = 'baseName',
|
||||
startServer = 'startServer',
|
||||
stopServer = 'stopServer',
|
||||
log = 'log',
|
||||
systemInformation = 'systemInformation',
|
||||
showToast = 'showToast',
|
||||
|
||||
28
core/src/types/engine/index.ts
Normal file
28
core/src/types/engine/index.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { InferenceEngine } from '../../types'
|
||||
|
||||
export type Engines = {
|
||||
[key in InferenceEngine]: EngineVariant[]
|
||||
}
|
||||
|
||||
export type EngineVariant = {
|
||||
engine: InferenceEngine
|
||||
name: string
|
||||
version: string
|
||||
}
|
||||
|
||||
export type DefaultEngineVariant = {
|
||||
engine: InferenceEngine
|
||||
variant: string
|
||||
version: string
|
||||
}
|
||||
|
||||
export type EngineReleased = {
|
||||
created_at: string
|
||||
download_count: number
|
||||
name: string
|
||||
size: number
|
||||
}
|
||||
|
||||
export enum EngineEvent {
|
||||
OnEngineUpdate = 'OnEngineUpdate',
|
||||
}
|
||||
@ -10,3 +10,4 @@ export * from './huggingface'
|
||||
export * from './miscellaneous'
|
||||
export * from './api'
|
||||
export * from './setting'
|
||||
export * from './engine'
|
||||
|
||||
@ -11,11 +11,10 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"declarationDir": "dist/types",
|
||||
"outDir": "dist/lib",
|
||||
"outDir": "dist",
|
||||
"importHelpers": true,
|
||||
"types": ["@types/jest"],
|
||||
"resolveJsonModule": true
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["**/*.test.ts"]
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
||||
|
||||
@ -58,5 +58,5 @@
|
||||
"prettier": "^3.2.5",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
|
||||
0
docs/yarn.lock
Normal file
0
docs/yarn.lock
Normal file
@ -277,4 +277,39 @@ export function handleAppIPCs() {
|
||||
ModuleManager.instance.clearImportedModules()
|
||||
return createUserSpace().then(migrate).then(setupExtensions)
|
||||
})
|
||||
|
||||
/**
|
||||
* Handles the "startServer" IPC message to start the Jan API server.
|
||||
* Initializes and starts server with provided configuration options.
|
||||
* @param _event - The IPC event object.
|
||||
* @param args - Configuration object containing host, port, CORS settings etc.
|
||||
* @returns Promise that resolves when server starts successfully
|
||||
*/
|
||||
ipcMain.handle(
|
||||
NativeRoute.startServer,
|
||||
async (_event, args): Promise<void> => {
|
||||
const { startServer } = require('@janhq/server')
|
||||
return startServer({
|
||||
host: args?.host,
|
||||
port: args?.port,
|
||||
isCorsEnabled: args?.isCorsEnabled,
|
||||
isVerboseEnabled: args?.isVerboseEnabled,
|
||||
prefix: args?.prefix,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* Handles the "stopServer" IPC message to stop the Jan API server.
|
||||
* Gracefully shuts down the server instance.
|
||||
* @param _event - The IPC event object
|
||||
* @returns Promise that resolves when server stops successfully
|
||||
*/
|
||||
ipcMain.handle(NativeRoute.stopServer, async (_event): Promise<void> => {
|
||||
/**
|
||||
* Stop Jan API Server.
|
||||
*/
|
||||
const { stopServer } = require('@janhq/server')
|
||||
return stopServer()
|
||||
})
|
||||
}
|
||||
|
||||
@ -78,9 +78,11 @@
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext \".js,.jsx,.ts,.tsx\"",
|
||||
"test:e2e": "playwright test --workers=1",
|
||||
"test:e2e": "DEBUG=pw:browser xvfb-maybe -- playwright test --workers=1",
|
||||
"copy:assets": "rimraf --glob \"./pre-install/*.tgz\" && cpx \"../pre-install/*.tgz\" \"./pre-install\"",
|
||||
"dev": "yarn copy:assets && tsc -p . && electron .",
|
||||
"version-patch": "jq '.version' package.json | tr -d '\"' > .version.bak && jq --arg ver \"0.1.$(date +%s)\" '.version = $ver' package.json > package.tmp && mv package.tmp package.json",
|
||||
"version-restore": "jq --arg ver $(cat .version.bak) '.version = $ver' package.json > package.tmp && mv package.tmp package.json && rm .version.bak",
|
||||
"dev": "yarn copy:assets && tsc -p . && yarn version-patch && electron . && yarn version-restore",
|
||||
"compile": "tsc -p .",
|
||||
"start": "electron .",
|
||||
"build": "yarn copy:assets && run-script-os",
|
||||
@ -98,22 +100,23 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@alumna/reflect": "^1.1.3",
|
||||
"@janhq/core": "link:./core",
|
||||
"@janhq/server": "link:./server",
|
||||
"@janhq/core": "link:../core",
|
||||
"@janhq/server": "link:../server",
|
||||
"@kirillvakalov/nut-tree__nut-js": "4.2.1-2",
|
||||
"@npmcli/arborist": "^7.1.0",
|
||||
"electron-store": "^8.1.0",
|
||||
"electron-updater": "^6.1.7",
|
||||
"fs-extra": "^11.2.0",
|
||||
"node-fetch": "2",
|
||||
"pacote": "^17.0.4",
|
||||
"pacote": "^21.0.0",
|
||||
"request": "^2.88.2",
|
||||
"request-progress": "^3.0.0",
|
||||
"ulidx": "^2.3.0",
|
||||
"@kirillvakalov/nut-tree__nut-js": "4.2.1-2"
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "^2.5.0",
|
||||
"@playwright/test": "^1.38.1",
|
||||
"@reportportal/agent-js-playwright": "^5.1.7",
|
||||
"@types/npmcli__arborist": "^5.6.4",
|
||||
"@types/pacote": "^11.1.7",
|
||||
"@types/request": "^2.48.12",
|
||||
@ -129,9 +132,10 @@
|
||||
"rimraf": "^5.0.5",
|
||||
"run-script-os": "^1.1.6",
|
||||
"typescript": "^5.3.3",
|
||||
"@reportportal/agent-js-playwright": "^5.1.7"
|
||||
"xvfb-maybe": "^0.2.1"
|
||||
},
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export async function setupElectron() {
|
||||
expect(appInfo).toBeTruthy()
|
||||
|
||||
electronApp = await electron.launch({
|
||||
args: [appInfo.main], // main file from package.json
|
||||
args: [appInfo.main, '--no-sandbox'], // main file from package.json
|
||||
executablePath: appInfo.executable, // path to the Electron executable
|
||||
// recordVideo: { dir: Constants.VIDEO_DIR }, // Specify the directory for video recordings
|
||||
})
|
||||
|
||||
3
extensions/.yarnrc.yml
Normal file
3
extensions/.yarnrc.yml
Normal file
@ -0,0 +1,3 @@
|
||||
nmHoistingLimits: workspaces
|
||||
nodeLinker: node-modules
|
||||
checksumBehavior: update
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@janhq/assistant-extension",
|
||||
"productName": "Jan Assistant",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description": "This extension enables assistants, including Jan, a default assistant that can call all downloaded models",
|
||||
"main": "dist/index.js",
|
||||
"node": "dist/node/index.js",
|
||||
@ -9,33 +9,28 @@
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"clean:modules": "rimraf node_modules/pdf-parse/test && cd node_modules/pdf-parse/lib/pdf.js && rimraf v1.9.426 v1.10.88 v2.0.550",
|
||||
"build-universal-hnswlib": "cd node_modules/hnswlib-node && arch -x86_64 npx node-gyp rebuild --arch=x64 && mv build/Release/addon.node ./addon-amd64.node && node-gyp rebuild --arch=arm64 && mv build/Release/addon.node ./addon-arm64.node && lipo -create -output build/Release/addon.node ./addon-arm64.node ./addon-amd64.node && rm ./addon-arm64.node && rm ./addon-amd64.node",
|
||||
"build": "yarn clean:modules && tsc --module commonjs && rollup -c rollup.config.ts",
|
||||
"build:publish:linux": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:darwin": "rimraf *.tgz --glob && yarn build-universal-hnswlib && yarn build && ../../.github/scripts/auto-sign.sh && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:win32": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish": "run-script-os"
|
||||
"build-universal-hnswlib": "[ \"$IS_TEST\" = \"true\" ] && echo \"Skip universal build\" || (cd node_modules/hnswlib-node && arch -x86_64 npx node-gyp rebuild --arch=x64 && mv build/Release/addon.node ./addon-amd64.node && node-gyp rebuild --arch=arm64 && mv build/Release/addon.node ./addon-arm64.node && lipo -create -output build/Release/addon.node ./addon-arm64.node ./addon-amd64.node && rm ./addon-arm64.node && rm ./addon-amd64.node)",
|
||||
"build": "yarn clean:modules && rolldown -c rolldown.config.mjs",
|
||||
"build:publish:linux": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:darwin": "rimraf *.tgz --glob || true && yarn build-universal-hnswlib && yarn build && ../../.github/scripts/auto-sign.sh && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:win32": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish": "run-script-os",
|
||||
"build:dev": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@types/pdf-parse": "^1.1.4",
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.38.5",
|
||||
"rollup-plugin-define": "^1.0.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"rollup-plugin-typescript2": "^0.36.0",
|
||||
"typescript": "^5.3.3",
|
||||
"run-script-os": "^1.1.6"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"run-script-os": "^1.1.6",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"@langchain/community": "0.0.13",
|
||||
"hnswlib-node": "^1.4.2",
|
||||
"langchain": "^0.0.214",
|
||||
"node-gyp": "^11.0.0",
|
||||
"pdf-parse": "^1.1.1",
|
||||
"ts-loader": "^9.5.0"
|
||||
},
|
||||
@ -47,5 +42,9 @@
|
||||
"bundleDependencies": [
|
||||
"@janhq/core",
|
||||
"hnswlib-node"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
31
extensions/assistant-extension/rolldown.config.mjs
Normal file
31
extensions/assistant-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,31 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
NODE: JSON.stringify(`${pkgJson.name}/${pkgJson.node}`),
|
||||
VERSION: JSON.stringify(pkgJson.version),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'src/node/index.ts',
|
||||
external: ['@janhq/core/node', 'path', 'hnswlib-node'],
|
||||
output: {
|
||||
format: 'cjs',
|
||||
file: 'dist/node/index.js',
|
||||
sourcemap: false,
|
||||
inlineDynamicImports: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts'],
|
||||
},
|
||||
platform: 'node',
|
||||
},
|
||||
])
|
||||
@ -1,73 +0,0 @@
|
||||
import resolve from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import sourceMaps from 'rollup-plugin-sourcemaps'
|
||||
import typescript from 'rollup-plugin-typescript2'
|
||||
import json from '@rollup/plugin-json'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
|
||||
const packageJson = require('./package.json')
|
||||
|
||||
export default [
|
||||
{
|
||||
input: `src/index.ts`,
|
||||
output: [{ file: packageJson.main, format: 'es', sourcemap: true }],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: [],
|
||||
watch: {
|
||||
include: 'src/**',
|
||||
},
|
||||
plugins: [
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
NODE: JSON.stringify(`${packageJson.name}/${packageJson.node}`),
|
||||
VERSION: JSON.stringify(packageJson.version),
|
||||
}),
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({ useTsconfigDeclarationDir: true }),
|
||||
// Compile TypeScript files
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs(),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
resolve({
|
||||
extensions: ['.js', '.ts', '.svelte'],
|
||||
browser: true,
|
||||
}),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: `src/node/index.ts`,
|
||||
output: [{ dir: 'dist/node', format: 'cjs', sourcemap: false }],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: ['@janhq/core/node', 'path', 'hnswlib-node'],
|
||||
watch: {
|
||||
include: 'src/node/**',
|
||||
},
|
||||
// inlineDynamicImports: true,
|
||||
plugins: [
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({ useTsconfigDeclarationDir: true }),
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs({
|
||||
ignoreDynamicRequires: true,
|
||||
}),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
resolve({
|
||||
extensions: ['.ts', '.js', '.json'],
|
||||
}),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
// sourceMaps(),
|
||||
],
|
||||
},
|
||||
]
|
||||
@ -1,4 +1,4 @@
|
||||
import { getJanDataFolderPath, normalizeFilePath } from '@janhq/core/node'
|
||||
import { getJanDataFolderPath } from '@janhq/core/node'
|
||||
import { retrieval } from './retrieval'
|
||||
import path from 'path'
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"target": "ES2015",
|
||||
"module": "ES2020",
|
||||
"lib": ["es2015", "es2016", "es2017", "dom"],
|
||||
"strict": true,
|
||||
"target": "es2016",
|
||||
"module": "ES6",
|
||||
"esModuleInterop": true,
|
||||
"strict": false,
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
@ -18,12 +18,12 @@
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4"
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"ky": "^1.7.2",
|
||||
"p-queue": "^8.0.1"
|
||||
},
|
||||
@ -35,5 +35,9 @@
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"bundleDependencies": []
|
||||
"bundleDependencies": [],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
14
extensions/conversational-extension/rolldown.config.mjs
Normal file
14
extensions/conversational-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,14 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||
SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||
},
|
||||
})
|
||||
@ -1,5 +1,3 @@
|
||||
export {}
|
||||
declare global {
|
||||
declare const API_URL: string
|
||||
declare const SOCKET_URL: string
|
||||
|
||||
@ -11,4 +9,3 @@ declare global {
|
||||
core?: Core | undefined
|
||||
electronAPI?: any | undefined
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||
SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
// Do not minify the output, otherwise it breaks the class registration
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
5
extensions/engine-management-extension/jest.config.js
Normal file
5
extensions/engine-management-extension/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
}
|
||||
44
extensions/engine-management-extension/package.json
Normal file
44
extensions/engine-management-extension/package.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@janhq/engine-management-extension",
|
||||
"productName": "Engine Management",
|
||||
"version": "1.0.0",
|
||||
"description": "Extension for managing engines and their configurations",
|
||||
"main": "dist/index.js",
|
||||
"node": "dist/node/index.cjs.js",
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && ../../.github/scripts/auto-sign.sh && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rolldown": "^1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"cpu-instructions": "^0.0.13",
|
||||
"ky": "^1.7.2",
|
||||
"p-queue": "^8.0.1"
|
||||
},
|
||||
"bundledDependencies": [
|
||||
"cpu-instructions",
|
||||
"@janhq/core"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist/*",
|
||||
"package.json",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
40
extensions/engine-management-extension/rolldown.config.mjs
Normal file
40
extensions/engine-management-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,40 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
define: {
|
||||
NODE: JSON.stringify(`${pkgJson.name}/${pkgJson.node}`),
|
||||
API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||
SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.42'),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'src/node/index.ts',
|
||||
external: ['@janhq/core/node'],
|
||||
output: {
|
||||
format: 'cjs',
|
||||
file: 'dist/node/index.cjs.js',
|
||||
},
|
||||
define: {
|
||||
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.42'),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'src/node/cpuInfo.ts',
|
||||
output: {
|
||||
format: 'cjs',
|
||||
file: 'dist/node/cpuInfo.js',
|
||||
},
|
||||
external: ['cpu-instructions'],
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', '.svg'],
|
||||
},
|
||||
},
|
||||
])
|
||||
13
extensions/engine-management-extension/src/@types/global.d.ts
vendored
Normal file
13
extensions/engine-management-extension/src/@types/global.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
declare const API_URL: string
|
||||
declare const CORTEX_ENGINE_VERSION: string
|
||||
declare const SOCKET_URL: string
|
||||
declare const NODE: string
|
||||
|
||||
interface Core {
|
||||
api: APIFunctions
|
||||
events: EventEmitter
|
||||
}
|
||||
interface Window {
|
||||
core?: Core | undefined
|
||||
electronAPI?: any | undefined
|
||||
}
|
||||
10
extensions/engine-management-extension/src/error.ts
Normal file
10
extensions/engine-management-extension/src/error.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Custom Engine Error
|
||||
*/
|
||||
export class EngineError extends Error {
|
||||
message: string
|
||||
constructor(message: string) {
|
||||
super()
|
||||
this.message = message
|
||||
}
|
||||
}
|
||||
219
extensions/engine-management-extension/src/index.ts
Normal file
219
extensions/engine-management-extension/src/index.ts
Normal file
@ -0,0 +1,219 @@
|
||||
import {
|
||||
EngineManagementExtension,
|
||||
InferenceEngine,
|
||||
DefaultEngineVariant,
|
||||
Engines,
|
||||
EngineVariant,
|
||||
EngineReleased,
|
||||
executeOnMain,
|
||||
systemInformation,
|
||||
} from '@janhq/core'
|
||||
import ky, { HTTPError } from 'ky'
|
||||
import PQueue from 'p-queue'
|
||||
import { EngineError } from './error'
|
||||
|
||||
/**
|
||||
* JSONEngineManagementExtension is a EngineManagementExtension implementation that provides
|
||||
* functionality for managing engines.
|
||||
*/
|
||||
export default class JSONEngineManagementExtension extends EngineManagementExtension {
|
||||
queue = new PQueue({ concurrency: 1 })
|
||||
|
||||
/**
|
||||
* Called when the extension is loaded.
|
||||
*/
|
||||
async onLoad() {
|
||||
// Symlink Engines Directory
|
||||
await executeOnMain(NODE, 'symlinkEngines')
|
||||
// Run Healthcheck
|
||||
this.queue.add(() => this.healthz())
|
||||
try {
|
||||
const variant = await this.getDefaultEngineVariant(
|
||||
InferenceEngine.cortex_llamacpp
|
||||
)
|
||||
// Check whether should use bundled version or installed version
|
||||
// Only use larger version
|
||||
if (this.compareVersions(CORTEX_ENGINE_VERSION, variant.version) > 0) {
|
||||
throw new EngineError(
|
||||
'Default engine version is smaller than bundled version'
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
(error instanceof HTTPError && error.response.status === 400) ||
|
||||
error instanceof EngineError
|
||||
) {
|
||||
const systemInfo = await systemInformation()
|
||||
const variant = await executeOnMain(
|
||||
NODE,
|
||||
'engineVariant',
|
||||
systemInfo.gpuSetting
|
||||
)
|
||||
await this.setDefaultEngineVariant(InferenceEngine.cortex_llamacpp, {
|
||||
variant: variant,
|
||||
version: `${CORTEX_ENGINE_VERSION}`,
|
||||
})
|
||||
} else {
|
||||
console.error('An unexpected error occurred:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the extension is unloaded.
|
||||
*/
|
||||
onUnload() {}
|
||||
|
||||
/**
|
||||
* @returns A Promise that resolves to an object of list engines.
|
||||
*/
|
||||
async getEngines(): Promise<Engines> {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.get(`${API_URL}/v1/engines`)
|
||||
.json<Engines>()
|
||||
.then((e) => e)
|
||||
) as Promise<Engines>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to an array of installed engine.
|
||||
*/
|
||||
async getInstalledEngines(name: InferenceEngine): Promise<EngineVariant[]> {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.get(`${API_URL}/v1/engines/${name}`)
|
||||
.json<EngineVariant[]>()
|
||||
.then((e) => e)
|
||||
) as Promise<EngineVariant[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @param version - Version of the engine.
|
||||
* @param platform - Optional to sort by operating system. macOS, linux, windows.
|
||||
* @returns A Promise that resolves to an array of latest released engine by version.
|
||||
*/
|
||||
async getReleasedEnginesByVersion(
|
||||
name: InferenceEngine,
|
||||
version: string,
|
||||
platform?: string
|
||||
) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.get(`${API_URL}/v1/engines/${name}/releases/${version}`)
|
||||
.json<EngineReleased[]>()
|
||||
.then((e) =>
|
||||
platform ? e.filter((r) => r.name.includes(platform)) : e
|
||||
)
|
||||
) as Promise<EngineReleased[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @param platform - Optional to sort by operating system. macOS, linux, windows.
|
||||
* @returns A Promise that resolves to an array of latest released engine by version.
|
||||
*/
|
||||
async getLatestReleasedEngine(name: InferenceEngine, platform?: string) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.get(`${API_URL}/v1/engines/${name}/releases/latest`)
|
||||
.json<EngineReleased[]>()
|
||||
.then((e) =>
|
||||
platform ? e.filter((r) => r.name.includes(platform)) : e
|
||||
)
|
||||
) as Promise<EngineReleased[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to intall of engine.
|
||||
*/
|
||||
async installEngine(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version?: string }
|
||||
) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.post(`${API_URL}/v1/engines/${name}/install`, { json: engineConfig })
|
||||
.then((e) => e)
|
||||
) as Promise<{ messages: string }>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to unintall of engine.
|
||||
*/
|
||||
async uninstallEngine(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version: string }
|
||||
) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.delete(`${API_URL}/v1/engines/${name}/install`, { json: engineConfig })
|
||||
.then((e) => e)
|
||||
) as Promise<{ messages: string }>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - Inference engine name.
|
||||
* @returns A Promise that resolves to an object of default engine.
|
||||
*/
|
||||
async getDefaultEngineVariant(name: InferenceEngine) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.get(`${API_URL}/v1/engines/${name}/default`)
|
||||
.json<{ messages: string }>()
|
||||
.then((e) => e)
|
||||
) as Promise<DefaultEngineVariant>
|
||||
}
|
||||
|
||||
/**
|
||||
* @body variant - string
|
||||
* @body version - string
|
||||
* @returns A Promise that resolves to set default engine.
|
||||
*/
|
||||
async setDefaultEngineVariant(
|
||||
name: InferenceEngine,
|
||||
engineConfig: { variant: string; version: string }
|
||||
) {
|
||||
return this.queue.add(() =>
|
||||
ky
|
||||
.post(`${API_URL}/v1/engines/${name}/default`, { json: engineConfig })
|
||||
.then((e) => e)
|
||||
) as Promise<{ messages: string }>
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns A Promise that resolves to update engine.
|
||||
*/
|
||||
async updateEngine(name: InferenceEngine) {
|
||||
return this.queue.add(() =>
|
||||
ky.post(`${API_URL}/v1/engines/${name}/update`).then((e) => e)
|
||||
) as Promise<{ messages: string }>
|
||||
}
|
||||
|
||||
/**
|
||||
* Do health check on cortex.cpp
|
||||
* @returns
|
||||
*/
|
||||
async healthz(): Promise<void> {
|
||||
return ky
|
||||
.get(`${API_URL}/healthz`, {
|
||||
retry: { limit: 20, delay: () => 500, methods: ['get'] },
|
||||
})
|
||||
.then(() => {})
|
||||
}
|
||||
|
||||
private compareVersions(version1: string, version2: string): number {
|
||||
const parseVersion = (version: string) => version.split('.').map(Number)
|
||||
|
||||
const [major1, minor1, patch1] = parseVersion(version1.replace(/^v/, ''))
|
||||
const [major2, minor2, patch2] = parseVersion(version2.replace(/^v/, ''))
|
||||
|
||||
if (major1 !== major2) return major1 - major2
|
||||
if (minor1 !== minor2) return minor1 - minor2
|
||||
return patch1 - patch2
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from '@jest/globals'
|
||||
import { engineVariant, executableCortexFile } from './execute'
|
||||
import engine from './index'
|
||||
import { GpuSetting } from '@janhq/core/node'
|
||||
import { cpuInfo } from 'cpu-instructions'
|
||||
import { fork } from 'child_process'
|
||||
@ -62,20 +62,9 @@ describe('test executable cortex file', () => {
|
||||
Object.defineProperty(process, 'arch', {
|
||||
value: 'arm64',
|
||||
})
|
||||
expect(executableCortexFile(testSettings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath:
|
||||
originalPlatform === 'darwin'
|
||||
? expect.stringContaining(`cortex-server`)
|
||||
: expect.anything(),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
|
||||
mockFork.mockReturnValue(mockProcess)
|
||||
expect(engineVariant(testSettings)).resolves.toEqual('mac-arm64')
|
||||
expect(engine.engineVariant(testSettings)).resolves.toEqual('mac-arm64')
|
||||
})
|
||||
|
||||
it('executes on MacOS', () => {
|
||||
@ -99,18 +88,7 @@ describe('test executable cortex file', () => {
|
||||
value: 'x64',
|
||||
})
|
||||
|
||||
expect(executableCortexFile(testSettings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath:
|
||||
originalPlatform === 'darwin'
|
||||
? expect.stringContaining(`cortex-server`)
|
||||
: expect.anything(),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(testSettings)).resolves.toEqual('mac-amd64')
|
||||
expect(engine.engineVariant(testSettings)).resolves.toEqual('mac-amd64')
|
||||
})
|
||||
|
||||
it('executes on Windows CPU', () => {
|
||||
@ -131,15 +109,7 @@ describe('test executable cortex file', () => {
|
||||
}
|
||||
mockFork.mockReturnValue(mockProcess)
|
||||
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server.exe`),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
expect(engineVariant()).resolves.toEqual('windows-amd64-avx')
|
||||
expect(engine.engineVariant()).resolves.toEqual('windows-amd64-avx')
|
||||
})
|
||||
|
||||
it('executes on Windows Cuda 11', () => {
|
||||
@ -176,15 +146,8 @@ describe('test executable cortex file', () => {
|
||||
send: jest.fn(),
|
||||
}
|
||||
mockFork.mockReturnValue(mockProcess)
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server.exe`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
'windows-amd64-avx2-cuda-11-7'
|
||||
)
|
||||
})
|
||||
@ -221,15 +184,8 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server.exe`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
'windows-amd64-noavx-cuda-12-0'
|
||||
)
|
||||
mockFork.mockReturnValue({
|
||||
@ -240,7 +196,7 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
'windows-amd64-avx2-cuda-12-0'
|
||||
)
|
||||
})
|
||||
@ -261,15 +217,8 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
expect(engineVariant()).resolves.toEqual('linux-amd64-noavx')
|
||||
|
||||
expect(engine.engineVariant()).resolves.toEqual('linux-amd64-noavx')
|
||||
})
|
||||
|
||||
it('executes on Linux Cuda 11', () => {
|
||||
@ -306,15 +255,9 @@ describe('test executable cortex file', () => {
|
||||
send: jest.fn(),
|
||||
})
|
||||
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
expect(engine.engineVariant(settings)).resolves.toBe(
|
||||
'linux-amd64-avx2-cuda-11-7'
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toBe('linux-amd64-avx2-cuda-11-7')
|
||||
})
|
||||
|
||||
it('executes on Linux Cuda 12', () => {
|
||||
@ -349,15 +292,8 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
'linux-amd64-avx2-cuda-12-0'
|
||||
)
|
||||
})
|
||||
@ -383,16 +319,7 @@ describe('test executable cortex file', () => {
|
||||
send: jest.fn(),
|
||||
})
|
||||
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
`linux-amd64-${instruction}`
|
||||
)
|
||||
})
|
||||
@ -416,15 +343,7 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server.exe`),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
`windows-amd64-${instruction}`
|
||||
)
|
||||
})
|
||||
@ -465,15 +384,7 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server.exe`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
`windows-amd64-${instruction === 'avx512' || instruction === 'avx2' ? 'avx2' : 'noavx'}-cuda-12-0`
|
||||
)
|
||||
})
|
||||
@ -514,15 +425,7 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
`linux-amd64-${instruction === 'avx512' || instruction === 'avx2' ? 'avx2' : 'noavx'}-cuda-12-0`
|
||||
)
|
||||
})
|
||||
@ -564,50 +467,8 @@ describe('test executable cortex file', () => {
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath: expect.stringContaining(`cortex-server`),
|
||||
cudaVisibleDevices: '0',
|
||||
vkVisibleDevices: '0',
|
||||
})
|
||||
)
|
||||
expect(engineVariant(settings)).resolves.toEqual(`linux-amd64-vulkan`)
|
||||
})
|
||||
})
|
||||
|
||||
// Generate test for different cpu instructions on MacOS
|
||||
it(`executes on MacOS with different instructions`, () => {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: 'darwin',
|
||||
})
|
||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
||||
cpuInstructions.forEach(() => {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: 'darwin',
|
||||
})
|
||||
const settings: GpuSetting = {
|
||||
...testSettings,
|
||||
run_mode: 'cpu',
|
||||
}
|
||||
mockFork.mockReturnValue({
|
||||
on: jest.fn((event, callback) => {
|
||||
if (event === 'message') {
|
||||
callback('noavx')
|
||||
}
|
||||
}),
|
||||
send: jest.fn(),
|
||||
})
|
||||
expect(executableCortexFile(settings)).toEqual(
|
||||
expect.objectContaining({
|
||||
enginePath: expect.stringContaining('shared'),
|
||||
executablePath:
|
||||
originalPlatform === 'darwin'
|
||||
? expect.stringContaining(`cortex-server`)
|
||||
: expect.anything(),
|
||||
cudaVisibleDevices: '',
|
||||
vkVisibleDevices: '',
|
||||
})
|
||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
||||
`linux-amd64-vulkan`
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -1,13 +1,13 @@
|
||||
import * as path from 'path'
|
||||
import { GpuSetting, appResourcePath, log } from '@janhq/core/node'
|
||||
import {
|
||||
appResourcePath,
|
||||
getJanDataFolderPath,
|
||||
GpuSetting,
|
||||
log,
|
||||
} from '@janhq/core/node'
|
||||
import { fork } from 'child_process'
|
||||
import { mkdir, readdir, symlink } from 'fs/promises'
|
||||
|
||||
export interface CortexExecutableOptions {
|
||||
enginePath: string
|
||||
executablePath: string
|
||||
cudaVisibleDevices: string
|
||||
vkVisibleDevices: string
|
||||
}
|
||||
/**
|
||||
* The GPU runMode that will be set - either 'vulkan', 'cuda', or empty for cpu.
|
||||
* @param settings
|
||||
@ -37,14 +37,6 @@ const os = (): string => {
|
||||
: 'linux-amd64'
|
||||
}
|
||||
|
||||
/**
|
||||
* The cortex.cpp extension based on the current platform.
|
||||
* @returns .exe if on Windows, otherwise an empty string.
|
||||
*/
|
||||
const extension = (): '.exe' | '' => {
|
||||
return process.platform === 'win32' ? '.exe' : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* The CUDA version that will be set - either '11-7' or '12-0'.
|
||||
* @param settings
|
||||
@ -89,30 +81,10 @@ const cpuInstructions = async (): Promise<string> => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The executable options for the cortex.cpp extension.
|
||||
*/
|
||||
export const executableCortexFile = (
|
||||
gpuSetting?: GpuSetting
|
||||
): CortexExecutableOptions => {
|
||||
let cudaVisibleDevices = gpuSetting?.gpus_in_use.join(',') ?? ''
|
||||
let vkVisibleDevices = gpuSetting?.gpus_in_use.join(',') ?? ''
|
||||
let binaryName = `cortex-server${extension()}`
|
||||
const binPath = path.join(__dirname, '..', 'bin')
|
||||
return {
|
||||
enginePath: path.join(appResourcePath(), 'shared'),
|
||||
executablePath: path.join(binPath, binaryName),
|
||||
cudaVisibleDevices,
|
||||
vkVisibleDevices,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find which variant to run based on the current platform.
|
||||
*/
|
||||
export const engineVariant = async (
|
||||
gpuSetting?: GpuSetting
|
||||
): Promise<string> => {
|
||||
const engineVariant = async (gpuSetting?: GpuSetting): Promise<string> => {
|
||||
const cpuInstruction = await cpuInstructions()
|
||||
log(`[CORTEX]: CPU instruction: ${cpuInstruction}`)
|
||||
let engineVariant = [
|
||||
@ -135,3 +107,45 @@ export const engineVariant = async (
|
||||
log(`[CORTEX]: Engine variant: ${engineVariant}`)
|
||||
return engineVariant
|
||||
}
|
||||
|
||||
/**
|
||||
* Create symlink to each variant for the default bundled version
|
||||
*/
|
||||
const symlinkEngines = async () => {
|
||||
const sourceEnginePath = path.join(
|
||||
appResourcePath(),
|
||||
'shared',
|
||||
'engines',
|
||||
'cortex.llamacpp'
|
||||
)
|
||||
const symlinkEnginePath = path.join(
|
||||
getJanDataFolderPath(),
|
||||
'engines',
|
||||
'cortex.llamacpp'
|
||||
)
|
||||
const variantFolders = await readdir(sourceEnginePath)
|
||||
for (const variant of variantFolders) {
|
||||
const targetVariantPath = path.join(
|
||||
sourceEnginePath,
|
||||
variant,
|
||||
CORTEX_ENGINE_VERSION
|
||||
)
|
||||
const symlinkVariantPath = path.join(
|
||||
symlinkEnginePath,
|
||||
variant,
|
||||
CORTEX_ENGINE_VERSION
|
||||
)
|
||||
|
||||
await mkdir(path.join(symlinkEnginePath, variant), {
|
||||
recursive: true,
|
||||
}).catch(console.error)
|
||||
|
||||
await symlink(targetVariantPath, symlinkVariantPath).catch(console.error)
|
||||
console.log(`Symlink created: ${targetVariantPath} -> ${symlinkEnginePath}`)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
engineVariant,
|
||||
symlinkEngines,
|
||||
}
|
||||
15
extensions/engine-management-extension/tsconfig.json
Normal file
15
extensions/engine-management-extension/tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "ES6",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": false,
|
||||
"skipLibCheck": true,
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["src/**/*.test.ts", "rolldown.config.mjs"]
|
||||
}
|
||||
@ -4,29 +4,23 @@
|
||||
"version": "1.0.3",
|
||||
"description": "This extension enables Anthropic chat completion API calls",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/module.js",
|
||||
"engine": "anthropic",
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"test": "jest test",
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"sync:core": "cd ../.. && yarn build:core && cd extensions && rm yarn.lock && cd inference-anthropic-extension && yarn && yarn build:publish"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -40,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-anthropic-extension/rolldown.config.mjs
Normal file
18
extensions/inference-anthropic-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-anthropic-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-anthropic-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -10,9 +10,6 @@ import { RemoteOAIEngine } from '@janhq/core'
|
||||
import { PayloadType } from '@janhq/core'
|
||||
import { ChatCompletionRole } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
export enum Settings {
|
||||
apiKey = 'anthropic-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,9 +9,8 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"sync:core": "cd ../.. && yarn build:core && cd extensions && rm yarn.lock && cd inference-cohere-extension && yarn && yarn build:publish"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
@ -20,12 +19,12 @@
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -39,5 +38,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-cohere-extension/rolldown.config.mjs
Normal file
18
extensions/inference-cohere-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-cohere-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-cohere-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -10,9 +10,6 @@ import { RemoteOAIEngine } from '@janhq/core'
|
||||
import { PayloadType } from '@janhq/core'
|
||||
import { ChatCompletionRole } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'cohere-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -1 +1 @@
|
||||
1.0.6
|
||||
1.0.7
|
||||
|
||||
@ -30,8 +30,6 @@ if [ "$OS_TYPE" == "Linux" ]; then
|
||||
download "${ENGINE_DOWNLOAD_URL}-linux-amd64-vulkan.tar.gz" -e --strip 1 -o "${SHARED_PATH}/engines/cortex.llamacpp/linux-amd64-vulkan/v${ENGINE_VERSION}" 1
|
||||
download "${CUDA_DOWNLOAD_URL}/cuda-12-0-linux-amd64.tar.gz" -e --strip 1 -o "${SHARED_PATH}" 1
|
||||
download "${CUDA_DOWNLOAD_URL}/cuda-11-7-linux-amd64.tar.gz" -e --strip 1 -o "${SHARED_PATH}" 1
|
||||
mkdir -p "${SHARED_PATH}/engines/cortex.llamacpp/deps"
|
||||
touch "${SHARED_PATH}/engines/cortex.llamacpp/deps/keep"
|
||||
|
||||
elif [ "$OS_TYPE" == "Darwin" ]; then
|
||||
# macOS downloads
|
||||
|
||||
@ -9,12 +9,12 @@
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "tsc --module commonjs && rollup -c rollup.config.ts",
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"downloadcortex:linux:darwin": "./download.sh",
|
||||
"downloadcortex:win32": "download.bat",
|
||||
"downloadcortex": "run-script-os",
|
||||
"build:publish:darwin": "rimraf *.tgz --glob && yarn build && npm run downloadcortex && ../../.github/scripts/auto-sign.sh && cpx \"bin/**\" \"dist/bin\" && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:win32:linux": "rimraf *.tgz --glob && yarn build && npm run downloadcortex && cpx \"bin/**\" \"dist/bin\" && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:darwin": "rimraf *.tgz --glob || true && yarn build && yarn downloadcortex && ../../.github/scripts/auto-sign.sh && cpx \"bin/**\" \"dist/bin\" && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish:win32:linux": "rimraf *.tgz --glob || true && yarn build && yarn downloadcortex && cpx \"bin/**\" \"dist/bin\" && npm pack && cpx *.tgz ../../pre-install",
|
||||
"build:publish": "run-script-os"
|
||||
},
|
||||
"exports": {
|
||||
@ -22,12 +22,7 @@
|
||||
"./main": "./dist/node/index.cjs.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-typescript": "^7.24.1",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@types/decompress": "^4.2.7",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20.11.4",
|
||||
@ -37,17 +32,13 @@
|
||||
"download-cli": "^1.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.38.5",
|
||||
"rollup-plugin-define": "^1.0.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"rollup-plugin-typescript2": "^0.36.0",
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"run-script-os": "^1.1.6",
|
||||
"ts-jest": "^29.1.2",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"cpu-instructions": "^0.0.13",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"decompress": "^4.2.1",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ky": "^1.7.2",
|
||||
@ -69,7 +60,10 @@
|
||||
"tcp-port-used",
|
||||
"fetch-retry",
|
||||
"@janhq/core",
|
||||
"decompress",
|
||||
"cpu-instructions"
|
||||
]
|
||||
"decompress"
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
131
extensions/inference-cortex-extension/rolldown.config.mjs
Normal file
131
extensions/inference-cortex-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,131 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import packageJson from './package.json' with { type: 'json' }
|
||||
import defaultSettingJson from './resources/default_settings.json' with { type: 'json' }
|
||||
import bakllavaJson from './resources/models/bakllava-1/model.json' with { type: 'json' }
|
||||
import codeninja7bJson from './resources/models/codeninja-1.0-7b/model.json' with { type: 'json' }
|
||||
import commandr34bJson from './resources/models/command-r-34b/model.json' with { type: 'json' }
|
||||
import deepseekCoder13bJson from './resources/models/deepseek-coder-1.3b/model.json' with { type: 'json' }
|
||||
import deepseekCoder34bJson from './resources/models/deepseek-coder-34b/model.json' with { type: 'json' }
|
||||
import gemma112bJson from './resources/models/gemma-1.1-2b/model.json' with { type: 'json' }
|
||||
import gemma117bJson from './resources/models/gemma-1.1-7b/model.json' with { type: 'json' }
|
||||
import llama2Chat70bJson from './resources/models/llama2-chat-70b/model.json' with { type: 'json' }
|
||||
import llama2Chat7bJson from './resources/models/llama2-chat-7b/model.json' with { type: 'json' }
|
||||
import llamacorn1bJson from './resources/models/llamacorn-1.1b/model.json' with { type: 'json' }
|
||||
import llava13bJson from './resources/models/llava-13b/model.json' with { type: 'json' }
|
||||
import llava7bJson from './resources/models/llava-7b/model.json' with { type: 'json' }
|
||||
import mistralIns7bq4Json from './resources/models/mistral-ins-7b-q4/model.json' with { type: 'json' }
|
||||
import mixtral8x7bInstructJson from './resources/models/mixtral-8x7b-instruct/model.json' with { type: 'json' }
|
||||
import noromaid7bJson from './resources/models/noromaid-7b/model.json' with { type: 'json' }
|
||||
import openchat357bJson from './resources/models/openchat-3.5-7b/model.json' with { type: 'json' }
|
||||
import phi3bJson from './resources/models/phi3-3.8b/model.json' with { type: 'json' }
|
||||
import phind34bJson from './resources/models/phind-34b/model.json' with { type: 'json' }
|
||||
import qwen7bJson from './resources/models/qwen-7b/model.json' with { type: 'json' }
|
||||
import stableZephyr3bJson from './resources/models/stable-zephyr-3b/model.json' with { type: 'json' }
|
||||
import stealthv127bJson from './resources/models/stealth-v1.2-7b/model.json' with { type: 'json' }
|
||||
import tinyllama11bJson from './resources/models/tinyllama-1.1b/model.json' with { type: 'json' }
|
||||
import trinityv127bJson from './resources/models/trinity-v1.2-7b/model.json' with { type: 'json' }
|
||||
import vistral7bJson from './resources/models/vistral-7b/model.json' with { type: 'json' }
|
||||
import wizardcoder13bJson from './resources/models/wizardcoder-13b/model.json' with { type: 'json' }
|
||||
import yi34bJson from './resources/models/yi-34b/model.json' with { type: 'json' }
|
||||
import llama3Json from './resources/models/llama3-8b-instruct/model.json' with { type: 'json' }
|
||||
import llama3Hermes8bJson from './resources/models/llama3-hermes-8b/model.json' with { type: 'json' }
|
||||
import aya8bJson from './resources/models/aya-23-8b/model.json' with { type: 'json' }
|
||||
import aya35bJson from './resources/models/aya-23-35b/model.json' with { type: 'json' }
|
||||
import phimediumJson from './resources/models/phi3-medium/model.json' with { type: 'json' }
|
||||
import codestralJson from './resources/models/codestral-22b/model.json' with { type: 'json' }
|
||||
import qwen2Json from './resources/models/qwen2-7b/model.json' with { type: 'json' }
|
||||
import llama318bJson from './resources/models/llama3.1-8b-instruct/model.json' with { type: 'json' }
|
||||
import llama3170bJson from './resources/models/llama3.1-70b-instruct/model.json' with { type: 'json' }
|
||||
import gemma22bJson from './resources/models/gemma-2-2b/model.json' with { type: 'json' }
|
||||
import gemma29bJson from './resources/models/gemma-2-9b/model.json' with { type: 'json' }
|
||||
import gemma227bJson from './resources/models/gemma-2-27b/model.json' with { type: 'json' }
|
||||
import llama321bJson from './resources/models/llama3.2-1b-instruct/model.json' with { type: 'json' }
|
||||
import llama323bJson from './resources/models/llama3.2-3b-instruct/model.json' with { type: 'json' }
|
||||
import qwen257bJson from './resources/models/qwen2.5-7b-instruct/model.json' with { type: 'json' }
|
||||
import qwen25coder7bJson from './resources/models/qwen2.5-coder-7b-instruct/model.json' with { type: 'json' }
|
||||
import qwen25coder14bJson from './resources/models/qwen2.5-coder-14b-instruct/model.json' with { type: 'json' }
|
||||
import qwen25coder32bJson from './resources/models/qwen2.5-coder-32b-instruct/model.json' with { type: 'json' }
|
||||
import qwen2514bJson from './resources/models/qwen2.5-14b-instruct/model.json' with { type: 'json' }
|
||||
import qwen2532bJson from './resources/models/qwen2.5-32b-instruct/model.json' with { type: 'json' }
|
||||
import qwen2572bJson from './resources/models/qwen2.5-72b-instruct/model.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify([
|
||||
bakllavaJson,
|
||||
codeninja7bJson,
|
||||
commandr34bJson,
|
||||
deepseekCoder13bJson,
|
||||
deepseekCoder34bJson,
|
||||
gemma112bJson,
|
||||
gemma117bJson,
|
||||
llama2Chat70bJson,
|
||||
llama2Chat7bJson,
|
||||
llamacorn1bJson,
|
||||
llava13bJson,
|
||||
llava7bJson,
|
||||
mistralIns7bq4Json,
|
||||
mixtral8x7bInstructJson,
|
||||
noromaid7bJson,
|
||||
openchat357bJson,
|
||||
phi3bJson,
|
||||
phind34bJson,
|
||||
qwen7bJson,
|
||||
stableZephyr3bJson,
|
||||
stealthv127bJson,
|
||||
tinyllama11bJson,
|
||||
trinityv127bJson,
|
||||
vistral7bJson,
|
||||
wizardcoder13bJson,
|
||||
yi34bJson,
|
||||
llama3Json,
|
||||
llama3Hermes8bJson,
|
||||
phimediumJson,
|
||||
aya8bJson,
|
||||
aya35bJson,
|
||||
codestralJson,
|
||||
qwen2Json,
|
||||
llama318bJson,
|
||||
llama3170bJson,
|
||||
gemma22bJson,
|
||||
gemma29bJson,
|
||||
gemma227bJson,
|
||||
llama321bJson,
|
||||
llama323bJson,
|
||||
qwen257bJson,
|
||||
qwen25coder7bJson,
|
||||
qwen25coder14bJson,
|
||||
qwen25coder32bJson,
|
||||
qwen2514bJson,
|
||||
qwen2532bJson,
|
||||
qwen2572bJson,
|
||||
]),
|
||||
NODE: JSON.stringify(`${packageJson.name}/${packageJson.node}`),
|
||||
SETTINGS: JSON.stringify(defaultSettingJson),
|
||||
CORTEX_API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||
CORTEX_SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.42'),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'src/node/index.ts',
|
||||
external: ['@janhq/core/node', 'cpu-instructions'],
|
||||
output: {
|
||||
format: 'cjs',
|
||||
file: 'dist/node/index.cjs.js',
|
||||
sourcemap: false,
|
||||
inlineDynamicImports: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.json'],
|
||||
},
|
||||
platform: 'node',
|
||||
},
|
||||
])
|
||||
@ -1,177 +0,0 @@
|
||||
import resolve from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import sourceMaps from 'rollup-plugin-sourcemaps'
|
||||
import typescript from 'rollup-plugin-typescript2'
|
||||
import json from '@rollup/plugin-json'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
const packageJson = require('./package.json')
|
||||
const defaultSettingJson = require('./resources/default_settings.json')
|
||||
|
||||
const bakllavaJson = require('./resources/models/bakllava-1/model.json')
|
||||
const codeninja7bJson = require('./resources/models/codeninja-1.0-7b/model.json')
|
||||
const commandr34bJson = require('./resources/models/command-r-34b/model.json')
|
||||
const deepseekCoder13bJson = require('./resources/models/deepseek-coder-1.3b/model.json')
|
||||
const deepseekCoder34bJson = require('./resources/models/deepseek-coder-34b/model.json')
|
||||
const gemma112bJson = require('./resources/models/gemma-1.1-2b/model.json')
|
||||
const gemma117bJson = require('./resources/models/gemma-1.1-7b/model.json')
|
||||
const llama2Chat70bJson = require('./resources/models/llama2-chat-70b/model.json')
|
||||
const llama2Chat7bJson = require('./resources/models/llama2-chat-7b/model.json')
|
||||
const llamacorn1bJson = require('./resources/models/llamacorn-1.1b/model.json')
|
||||
const llava13bJson = require('./resources/models/llava-13b/model.json')
|
||||
const llava7bJson = require('./resources/models/llava-7b/model.json')
|
||||
const mistralIns7bq4Json = require('./resources/models/mistral-ins-7b-q4/model.json')
|
||||
const mixtral8x7bInstructJson = require('./resources/models/mixtral-8x7b-instruct/model.json')
|
||||
const noromaid7bJson = require('./resources/models/noromaid-7b/model.json')
|
||||
const openchat357bJson = require('./resources/models/openchat-3.5-7b/model.json')
|
||||
const phi3bJson = require('./resources/models/phi3-3.8b/model.json')
|
||||
const phind34bJson = require('./resources/models/phind-34b/model.json')
|
||||
const qwen7bJson = require('./resources/models/qwen-7b/model.json')
|
||||
const stableZephyr3bJson = require('./resources/models/stable-zephyr-3b/model.json')
|
||||
const stealthv127bJson = require('./resources/models/stealth-v1.2-7b/model.json')
|
||||
const tinyllama11bJson = require('./resources/models/tinyllama-1.1b/model.json')
|
||||
const trinityv127bJson = require('./resources/models/trinity-v1.2-7b/model.json')
|
||||
const vistral7bJson = require('./resources/models/vistral-7b/model.json')
|
||||
const wizardcoder13bJson = require('./resources/models/wizardcoder-13b/model.json')
|
||||
const yi34bJson = require('./resources/models/yi-34b/model.json')
|
||||
const llama3Json = require('./resources/models/llama3-8b-instruct/model.json')
|
||||
const llama3Hermes8bJson = require('./resources/models/llama3-hermes-8b/model.json')
|
||||
const aya8bJson = require('./resources/models/aya-23-8b/model.json')
|
||||
const aya35bJson = require('./resources/models/aya-23-35b/model.json')
|
||||
const phimediumJson = require('./resources/models/phi3-medium/model.json')
|
||||
const codestralJson = require('./resources/models/codestral-22b/model.json')
|
||||
const qwen2Json = require('./resources/models/qwen2-7b/model.json')
|
||||
const llama318bJson = require('./resources/models/llama3.1-8b-instruct/model.json')
|
||||
const llama3170bJson = require('./resources/models/llama3.1-70b-instruct/model.json')
|
||||
const gemma22bJson = require('./resources/models/gemma-2-2b/model.json')
|
||||
const gemma29bJson = require('./resources/models/gemma-2-9b/model.json')
|
||||
const gemma227bJson = require('./resources/models/gemma-2-27b/model.json')
|
||||
const llama321bJson = require('./resources/models/llama3.2-1b-instruct/model.json')
|
||||
const llama323bJson = require('./resources/models/llama3.2-3b-instruct/model.json')
|
||||
const qwen257bJson = require('./resources/models/qwen2.5-7b-instruct/model.json')
|
||||
const qwen25coder7bJson = require('./resources/models/qwen2.5-coder-7b-instruct/model.json')
|
||||
const qwen25coder14bJson = require('./resources/models/qwen2.5-coder-14b-instruct/model.json')
|
||||
const qwen25coder32bJson = require('./resources/models/qwen2.5-coder-32b-instruct/model.json')
|
||||
const qwen2514bJson = require('./resources/models/qwen2.5-14b-instruct/model.json')
|
||||
const qwen2532bJson = require('./resources/models/qwen2.5-32b-instruct/model.json')
|
||||
const qwen2572bJson = require('./resources/models/qwen2.5-72b-instruct/model.json')
|
||||
|
||||
export default [
|
||||
{
|
||||
input: `src/index.ts`,
|
||||
output: [{ file: packageJson.main, format: 'es', sourcemap: true }],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: [],
|
||||
watch: {
|
||||
include: 'src/**',
|
||||
},
|
||||
plugins: [
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
MODELS: JSON.stringify([
|
||||
bakllavaJson,
|
||||
codeninja7bJson,
|
||||
commandr34bJson,
|
||||
deepseekCoder13bJson,
|
||||
deepseekCoder34bJson,
|
||||
gemma112bJson,
|
||||
gemma117bJson,
|
||||
llama2Chat70bJson,
|
||||
llama2Chat7bJson,
|
||||
llamacorn1bJson,
|
||||
llava13bJson,
|
||||
llava7bJson,
|
||||
mistralIns7bq4Json,
|
||||
mixtral8x7bInstructJson,
|
||||
noromaid7bJson,
|
||||
openchat357bJson,
|
||||
phi3bJson,
|
||||
phind34bJson,
|
||||
qwen7bJson,
|
||||
stableZephyr3bJson,
|
||||
stealthv127bJson,
|
||||
tinyllama11bJson,
|
||||
trinityv127bJson,
|
||||
vistral7bJson,
|
||||
wizardcoder13bJson,
|
||||
yi34bJson,
|
||||
llama3Json,
|
||||
llama3Hermes8bJson,
|
||||
phimediumJson,
|
||||
aya8bJson,
|
||||
aya35bJson,
|
||||
codestralJson,
|
||||
qwen2Json,
|
||||
llama318bJson,
|
||||
llama3170bJson,
|
||||
gemma22bJson,
|
||||
gemma29bJson,
|
||||
gemma227bJson,
|
||||
llama321bJson,
|
||||
llama323bJson,
|
||||
qwen257bJson,
|
||||
qwen25coder7bJson,
|
||||
qwen25coder14bJson,
|
||||
qwen25coder32bJson,
|
||||
qwen2514bJson,
|
||||
qwen2532bJson,
|
||||
qwen2572bJson,
|
||||
]),
|
||||
NODE: JSON.stringify(`${packageJson.name}/${packageJson.node}`),
|
||||
SETTINGS: JSON.stringify(defaultSettingJson),
|
||||
CORTEX_API_URL: JSON.stringify('http://127.0.0.1:39291'),
|
||||
CORTEX_SOCKET_URL: JSON.stringify('ws://127.0.0.1:39291'),
|
||||
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.42'),
|
||||
}),
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({
|
||||
useTsconfigDeclarationDir: true,
|
||||
exclude: ['**/__tests__', '**/*.test.ts'],
|
||||
}),
|
||||
// Compile TypeScript files
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs(),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
resolve({
|
||||
extensions: ['.js', '.ts', '.svelte'],
|
||||
browser: true,
|
||||
}),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: `src/node/index.ts`,
|
||||
output: [
|
||||
{ file: 'dist/node/index.cjs.js', format: 'cjs', sourcemap: true },
|
||||
],
|
||||
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
|
||||
external: ['@janhq/core/node', 'cpu-instructions'],
|
||||
watch: {
|
||||
include: 'src/node/**',
|
||||
},
|
||||
plugins: [
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({
|
||||
useTsconfigDeclarationDir: true,
|
||||
exclude: ['**/__tests__', '**/*.test.ts'],
|
||||
}),
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs(),
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
resolve({
|
||||
extensions: ['.ts', '.js', '.json'],
|
||||
}),
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps(),
|
||||
],
|
||||
},
|
||||
]
|
||||
@ -2,14 +2,5 @@ declare const NODE: string
|
||||
declare const CORTEX_API_URL: string
|
||||
declare const CORTEX_SOCKET_URL: string
|
||||
declare const CORTEX_ENGINE_VERSION: string
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
/**
|
||||
* The response from the initModel function.
|
||||
* @property error - An error message if the model fails to load.
|
||||
*/
|
||||
interface ModelOperationResponse {
|
||||
error?: any
|
||||
modelFile?: string
|
||||
}
|
||||
declare const SETTINGS: object[]
|
||||
declare const MODELS: object[]
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', { targets: { node: 'current' } }],
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
}
|
||||
@ -9,6 +9,7 @@
|
||||
import {
|
||||
Model,
|
||||
executeOnMain,
|
||||
EngineEvent,
|
||||
systemInformation,
|
||||
joinPath,
|
||||
LocalOAIEngine,
|
||||
@ -18,9 +19,7 @@ import {
|
||||
fs,
|
||||
events,
|
||||
ModelEvent,
|
||||
SystemInformation,
|
||||
dirName,
|
||||
AppConfigurationEventName,
|
||||
} from '@janhq/core'
|
||||
import PQueue from 'p-queue'
|
||||
import ky from 'ky'
|
||||
@ -112,21 +111,11 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
const systemInfo = await systemInformation()
|
||||
this.queue.add(() => executeOnMain(NODE, 'run', systemInfo))
|
||||
this.queue.add(() => this.healthz())
|
||||
this.queue.add(() => this.setDefaultEngine(systemInfo))
|
||||
this.subscribeToEvents()
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
this.clean()
|
||||
})
|
||||
|
||||
const currentMode = systemInfo.gpuSetting?.run_mode
|
||||
|
||||
events.on(AppConfigurationEventName.OnConfigurationUpdate, async () => {
|
||||
const systemInfo = await systemInformation()
|
||||
// Update run mode on settings update
|
||||
if (systemInfo.gpuSetting?.run_mode !== currentMode)
|
||||
this.queue.add(() => this.setDefaultEngine(systemInfo))
|
||||
})
|
||||
}
|
||||
|
||||
async onUnload() {
|
||||
@ -236,7 +225,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
* Do health check on cortex.cpp
|
||||
* @returns
|
||||
*/
|
||||
private healthz(): Promise<void> {
|
||||
private async healthz(): Promise<void> {
|
||||
return ky
|
||||
.get(`${CORTEX_API_URL}/healthz`, {
|
||||
retry: {
|
||||
@ -248,36 +237,11 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
.then(() => {})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default engine variant on launch
|
||||
*/
|
||||
private async setDefaultEngine(systemInfo: SystemInformation) {
|
||||
const variant = await executeOnMain(
|
||||
NODE,
|
||||
'engineVariant',
|
||||
systemInfo.gpuSetting
|
||||
)
|
||||
return (
|
||||
ky
|
||||
// Fallback support for legacy API
|
||||
.post(
|
||||
`${CORTEX_API_URL}/v1/engines/${InferenceEngine.cortex_llamacpp}/default?version=${CORTEX_ENGINE_VERSION}&variant=${variant}`,
|
||||
{
|
||||
json: {
|
||||
version: CORTEX_ENGINE_VERSION,
|
||||
variant,
|
||||
},
|
||||
}
|
||||
)
|
||||
.then(() => {})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean cortex processes
|
||||
* @returns
|
||||
*/
|
||||
private clean(): Promise<any> {
|
||||
private async clean(): Promise<any> {
|
||||
return ky
|
||||
.delete(`${CORTEX_API_URL}/processmanager/destroy`, {
|
||||
timeout: 2000, // maximum 2 seconds
|
||||
@ -301,6 +265,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
|
||||
this.socket.addEventListener('message', (event) => {
|
||||
const data = JSON.parse(event.data)
|
||||
|
||||
const transferred = data.task.items.reduce(
|
||||
(acc: number, cur: any) => acc + cur.downloadedBytes,
|
||||
0
|
||||
@ -320,9 +285,17 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
transferred: transferred,
|
||||
total: total,
|
||||
},
|
||||
downloadType: data.task.type,
|
||||
}
|
||||
)
|
||||
// Update models list from Hub
|
||||
|
||||
if (data.task.type === 'Engine') {
|
||||
events.emit(EngineEvent.OnEngineUpdate, {
|
||||
type: DownloadTypes[data.type as keyof typeof DownloadTypes],
|
||||
percent: percent,
|
||||
id: data.task.id,
|
||||
})
|
||||
} else {
|
||||
if (data.type === DownloadTypes.DownloadSuccess) {
|
||||
// Delay for the state update from cortex.cpp
|
||||
// Just to be sure
|
||||
@ -332,6 +305,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
@ -54,17 +54,6 @@ jest.mock('child_process', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
jest.mock('./execute', () => ({
|
||||
executableCortexFile: () => {
|
||||
return {
|
||||
enginePath: 'enginePath',
|
||||
executablePath: 'executablePath',
|
||||
cudaVisibleDevices: 'cudaVisibleDevices',
|
||||
vkVisibleDevices: 'vkVisibleDevices',
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
import index from './index'
|
||||
|
||||
describe('dispose', () => {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import path from 'path'
|
||||
import { getJanDataFolderPath, log, SystemInformation } from '@janhq/core/node'
|
||||
import { engineVariant, executableCortexFile } from './execute'
|
||||
import { ProcessWatchdog } from './watchdog'
|
||||
|
||||
// The HOST address to use for the Nitro subprocess
|
||||
@ -15,21 +14,12 @@ function run(systemInfo?: SystemInformation): Promise<any> {
|
||||
log(`[CORTEX]:: Spawning cortex subprocess...`)
|
||||
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
let executableOptions = executableCortexFile(
|
||||
// If ngl is not set or equal to 0, run on CPU with correct instructions
|
||||
systemInfo?.gpuSetting
|
||||
? {
|
||||
...systemInfo.gpuSetting,
|
||||
run_mode: systemInfo.gpuSetting.run_mode,
|
||||
}
|
||||
: undefined
|
||||
)
|
||||
|
||||
let gpuVisibleDevices = systemInfo?.gpuSetting?.gpus_in_use.join(',') ?? ''
|
||||
let binaryName = `cortex-server${process.platform === 'win32' ? '.exe' : ''}`
|
||||
const binPath = path.join(__dirname, '..', 'bin')
|
||||
const executablePath = path.join(binPath, binaryName)
|
||||
// Execute the binary
|
||||
log(`[CORTEX]:: Spawn cortex at path: ${executableOptions.executablePath}`)
|
||||
log(`[CORTEX]:: Cortex engine path: ${executableOptions.enginePath}`)
|
||||
|
||||
addEnvPaths(executableOptions.enginePath)
|
||||
log(`[CORTEX]:: Spawn cortex at path: ${executablePath}`)
|
||||
|
||||
const dataFolderPath = getJanDataFolderPath()
|
||||
if (watchdog) {
|
||||
@ -37,7 +27,7 @@ function run(systemInfo?: SystemInformation): Promise<any> {
|
||||
}
|
||||
|
||||
watchdog = new ProcessWatchdog(
|
||||
executableOptions.executablePath,
|
||||
executablePath,
|
||||
[
|
||||
'--start-server',
|
||||
'--port',
|
||||
@ -48,14 +38,12 @@ function run(systemInfo?: SystemInformation): Promise<any> {
|
||||
dataFolderPath,
|
||||
],
|
||||
{
|
||||
cwd: executableOptions.enginePath,
|
||||
env: {
|
||||
...process.env,
|
||||
ENGINE_PATH: executableOptions.enginePath,
|
||||
CUDA_VISIBLE_DEVICES: executableOptions.cudaVisibleDevices,
|
||||
CUDA_VISIBLE_DEVICES: gpuVisibleDevices,
|
||||
// Vulkan - Support 1 device at a time for now
|
||||
...(executableOptions.vkVisibleDevices?.length > 0 && {
|
||||
GGML_VULKAN_DEVICE: executableOptions.vkVisibleDevices[0],
|
||||
...(gpuVisibleDevices?.length > 0 && {
|
||||
GGML_VK_VISIBLE_DEVICES: gpuVisibleDevices,
|
||||
}),
|
||||
},
|
||||
}
|
||||
@ -96,5 +84,4 @@ export interface CortexProcessInfo {
|
||||
export default {
|
||||
run,
|
||||
dispose,
|
||||
engineVariant,
|
||||
}
|
||||
|
||||
@ -5,11 +5,7 @@
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"declarationDir": "dist/types",
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist",
|
||||
"importHelpers": true,
|
||||
"typeRoots": ["node_modules/@types"]
|
||||
|
||||
@ -4,26 +4,23 @@
|
||||
"version": "1.0.1",
|
||||
"description": "This extension enables fast Groq chat completion API calls",
|
||||
"main": "dist/index.js",
|
||||
"engine": "groq",
|
||||
"module": "dist/module.js",
|
||||
"author": "Carsen Klock & Jan",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && npm run build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -37,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-groq-extension/rolldown.config.mjs
Normal file
18
extensions/inference-groq-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-groq-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-groq-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -6,10 +6,7 @@
|
||||
* @module inference-groq-extension/src/index
|
||||
*/
|
||||
|
||||
import { RemoteOAIEngine, SettingComponentProps } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'groq-api-key',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
MODULE: JSON.stringify(`${packageJson.name}/${packageJson.module}`),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,22 +9,18 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -38,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-martian-extension/rolldown.config.mjs
Normal file
18
extensions/inference-martian-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-martian-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-martian-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -6,10 +6,7 @@
|
||||
* @module inference-martian-extension/src/index
|
||||
*/
|
||||
|
||||
import { RemoteOAIEngine, SettingComponentProps } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'martian-api-key',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,24 +9,19 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"path-browserify": "^1.0.1",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -39,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-mistral-extension/rolldown.config.mjs
Normal file
18
extensions/inference-mistral-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-mistral-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-mistral-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -8,9 +8,6 @@
|
||||
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'mistral-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
fallback: {
|
||||
path: require.resolve('path-browserify'),
|
||||
},
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,24 +9,19 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"path-browserify": "^1.0.1",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -39,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-nvidia-extension/rolldown.config.mjs
Normal file
18
extensions/inference-nvidia-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-nvidia-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-nvidia-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -8,9 +8,6 @@
|
||||
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'nvidia-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
fallback: {
|
||||
path: require.resolve('path-browserify'),
|
||||
},
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,22 +9,18 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -38,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
18
extensions/inference-openai-extension/rolldown.config.mjs
Normal file
18
extensions/inference-openai-extension/rolldown.config.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-openai-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-openai-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -8,9 +8,6 @@
|
||||
|
||||
import { ModelRuntimeParams, PayloadType, RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
export enum Settings {
|
||||
apiKey = 'openai-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -9,23 +9,18 @@
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install",
|
||||
"sync:core": "cd ../.. && yarn build:core && cd extensions && rm yarn.lock && cd inference-openrouter-extension && yarn && yarn build:publish"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"ts-loader": "^9.5.0"
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"ulidx": "^2.3.0"
|
||||
},
|
||||
@ -39,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
import modelsJson from './resources/models.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
2
extensions/inference-openrouter-extension/src/env.d.ts
vendored
Normal file
2
extensions/inference-openrouter-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
declare const MODELS: Model[]
|
||||
@ -9,9 +9,6 @@
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
import { PayloadType } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
declare const MODELS: Array<any>
|
||||
|
||||
enum Settings {
|
||||
apiKey = 'openrouter-api-key',
|
||||
model = 'openrouter-model',
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const webpack = require('webpack')
|
||||
const packageJson = require('./package.json')
|
||||
const settingJson = require('./resources/settings.json')
|
||||
const modelsJson = require('./resources/models.json')
|
||||
|
||||
module.exports = {
|
||||
experiments: { outputModule: true },
|
||||
entry: './src/index.ts', // Adjust the entry point to match your project's main file
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
MODELS: JSON.stringify(modelsJson),
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(packageJson.engine),
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'index.js', // Adjust the output file name as needed
|
||||
library: { type: 'module' }, // Specify ESM output format
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
// Add loaders and other configuration as needed for your project
|
||||
}
|
||||
@ -4,27 +4,22 @@
|
||||
"version": "1.0.0",
|
||||
"description": "This extension enables Nvidia's TensorRT-LLM as an inference engine option",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/module.js",
|
||||
"engine": "triton_trtllm",
|
||||
"author": "Jan <service@jan.ai>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||
"build:publish": "rimraf *.tgz --glob && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./main": "./dist/module.js"
|
||||
"build": "rolldown -c rolldown.config.mjs",
|
||||
"build:publish": "rimraf *.tgz --glob || true && yarn build && npm pack && cpx *.tgz ../../pre-install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cpx": "^1.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rolldown": "1.0.0-beta.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"typescript": "5.3.3",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4"
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@janhq/core": "file:../../core",
|
||||
"@janhq/core": "../../core/package.tgz",
|
||||
"fetch-retry": "^5.0.6",
|
||||
"rxjs": "^7.8.1",
|
||||
"ulidx": "^2.3.0"
|
||||
@ -39,5 +34,9 @@
|
||||
],
|
||||
"bundleDependencies": [
|
||||
"fetch-retry"
|
||||
]
|
||||
],
|
||||
"installConfig": {
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
import { defineConfig } from 'rolldown'
|
||||
import pkgJson from './package.json' with { type: 'json' }
|
||||
import settingJson from './resources/settings.json' with { type: 'json' }
|
||||
|
||||
export default defineConfig({
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
format: 'esm',
|
||||
file: 'dist/index.js',
|
||||
},
|
||||
platform: 'browser',
|
||||
define: {
|
||||
SETTINGS: JSON.stringify(settingJson),
|
||||
ENGINE: JSON.stringify(pkgJson.engine),
|
||||
},
|
||||
})
|
||||
1
extensions/inference-triton-trtllm-extension/src/env.d.ts
vendored
Normal file
1
extensions/inference-triton-trtllm-extension/src/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare const SETTINGS: SettingComponentProps[]
|
||||
@ -6,9 +6,8 @@
|
||||
* @module inference-nvidia-triton-trt-llm-extension/src/index
|
||||
*/
|
||||
|
||||
import { RemoteOAIEngine, SettingComponentProps } from '@janhq/core'
|
||||
import { RemoteOAIEngine } from '@janhq/core'
|
||||
|
||||
declare const SETTINGS: Array<any>
|
||||
enum Settings {
|
||||
apiKey = 'tritonllm-api-key',
|
||||
chatCompletionsEndPoint = 'chat-completions-endpoint',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user