refactor: remove JS server package (#5192)
* refactor: remove js server package * chore: migrate HF token data
This commit is contained in:
parent
30acc6f493
commit
6faca3e732
@ -148,6 +148,23 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
|||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
this.clean()
|
this.clean()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Migrate configs
|
||||||
|
if (!localStorage.getItem('cortex_migration_completed')) {
|
||||||
|
const config = await this.getCortexConfig()
|
||||||
|
console.log('Start cortex.cpp migration', config)
|
||||||
|
if (config && config.huggingface_token) {
|
||||||
|
this.updateSettings([
|
||||||
|
{
|
||||||
|
key: Settings.huggingfaceToken,
|
||||||
|
controllerProps: {
|
||||||
|
value: config.huggingface_token,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
localStorage.setItem('cortex_migration_completed', 'true')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onUnload() {
|
async onUnload() {
|
||||||
@ -313,6 +330,16 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
|||||||
.catch((e) => console.debug(e))
|
.catch((e) => console.debug(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cortex config
|
||||||
|
* @param body
|
||||||
|
*/
|
||||||
|
private async getCortexConfig(): Promise<any> {
|
||||||
|
return this.apiInstance()
|
||||||
|
.then((api) => api.get('v1/configs').json())
|
||||||
|
.catch((e) => console.debug(e))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to cortex.cpp websocket events
|
* Subscribe to cortex.cpp websocket events
|
||||||
*/
|
*/
|
||||||
|
|||||||
1
server/.gitignore
vendored
1
server/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
data
|
|
||||||
6636
server/cortex.json
6636
server/cortex.json
File diff suppressed because it is too large
Load Diff
1
server/global.d.ts
vendored
1
server/global.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
declare const CORTEX_API_URL: string
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
import { log } from '@janhq/core/node'
|
|
||||||
import { FastifyBaseLogger } from 'fastify'
|
|
||||||
import { ChildLoggerOptions } from 'fastify/types/logger'
|
|
||||||
import pino from 'pino'
|
|
||||||
|
|
||||||
export class Logger implements FastifyBaseLogger {
|
|
||||||
child(
|
|
||||||
bindings: pino.Bindings,
|
|
||||||
options?: ChildLoggerOptions | undefined
|
|
||||||
): FastifyBaseLogger {
|
|
||||||
return new Logger()
|
|
||||||
}
|
|
||||||
level = 'info'
|
|
||||||
|
|
||||||
silent = () => {}
|
|
||||||
|
|
||||||
info = (obj?: any, msg?: string, ...args: any[]) => {
|
|
||||||
if (obj?.res?.raw?.statusCode || obj?.req?.url) {
|
|
||||||
log(
|
|
||||||
`[SERVER]::${JSON.stringify({
|
|
||||||
level: obj?.level,
|
|
||||||
time: obj?.time,
|
|
||||||
hostname: obj?.hostname,
|
|
||||||
reqId: obj?.req?.id ?? obj?.res?.request?.id,
|
|
||||||
res: {
|
|
||||||
statusCode: obj?.res?.raw?.statusCode,
|
|
||||||
},
|
|
||||||
req: {
|
|
||||||
method: obj?.req?.method,
|
|
||||||
url: obj?.req?.url,
|
|
||||||
path: obj?.req?.path,
|
|
||||||
hostname: obj?.req?.hostname,
|
|
||||||
remoteAddress: obj?.req?.remoteAddress,
|
|
||||||
remotePort: obj?.req?.remotePort,
|
|
||||||
},
|
|
||||||
msg,
|
|
||||||
responseTime: obj?.responseTime,
|
|
||||||
...args,
|
|
||||||
})}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error = function (message: any) {
|
|
||||||
log(`[SERVER]::${JSON.stringify(message)}`)
|
|
||||||
}
|
|
||||||
debug = function (message: any) {
|
|
||||||
log(`[SERVER]::${JSON.stringify(message)}`)
|
|
||||||
}
|
|
||||||
fatal = function (message: any) {
|
|
||||||
log(`[SERVER]::${JSON.stringify(message)}`)
|
|
||||||
}
|
|
||||||
warn = function (message: any) {
|
|
||||||
log(`[SERVER]::${JSON.stringify(message)}`)
|
|
||||||
}
|
|
||||||
trace = function (message: any) {
|
|
||||||
log(`[SERVER]::${JSON.stringify(message)}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
import { join, extname } from 'path'
|
|
||||||
import { existsSync, readdirSync, writeFileSync, mkdirSync } from 'fs'
|
|
||||||
import { init, installExtensions } from '@janhq/core/node'
|
|
||||||
|
|
||||||
export async function setup() {
|
|
||||||
/**
|
|
||||||
* Setup Jan Data Directory
|
|
||||||
*/
|
|
||||||
const appDir = process.env.JAN_DATA_DIRECTORY ?? join(__dirname, '..', 'jan')
|
|
||||||
|
|
||||||
console.debug(`Create app data directory at ${appDir}...`)
|
|
||||||
if (!existsSync(appDir)) mkdirSync(appDir)
|
|
||||||
//@ts-ignore
|
|
||||||
global.core = {
|
|
||||||
// Define appPath function for app to retrieve app path globally
|
|
||||||
appPath: () => appDir,
|
|
||||||
}
|
|
||||||
init({
|
|
||||||
extensionsPath: join(appDir, 'extensions'),
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write app configurations. See #1619
|
|
||||||
*/
|
|
||||||
console.debug('Writing config file...')
|
|
||||||
writeFileSync(
|
|
||||||
join(appDir, 'settings.json'),
|
|
||||||
JSON.stringify({
|
|
||||||
data_folder: appDir,
|
|
||||||
}),
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!existsSync(join(appDir, 'settings'))) {
|
|
||||||
console.debug('Writing nvidia config file...')
|
|
||||||
mkdirSync(join(appDir, 'settings'))
|
|
||||||
writeFileSync(
|
|
||||||
join(appDir, 'settings', 'settings.json'),
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
notify: true,
|
|
||||||
run_mode: 'cpu',
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: false,
|
|
||||||
version: '',
|
|
||||||
},
|
|
||||||
cuda: {
|
|
||||||
exist: false,
|
|
||||||
version: '',
|
|
||||||
},
|
|
||||||
gpus: [],
|
|
||||||
gpu_highest_vram: '',
|
|
||||||
gpus_in_use: [],
|
|
||||||
is_initial: true,
|
|
||||||
}),
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Install extensions
|
|
||||||
*/
|
|
||||||
|
|
||||||
console.debug('Installing extensions...')
|
|
||||||
|
|
||||||
const baseExtensionPath = join(__dirname, '../../..', 'pre-install')
|
|
||||||
const extensions = readdirSync(baseExtensionPath)
|
|
||||||
.filter((file) => extname(file) === '.tgz')
|
|
||||||
.map((file) => join(baseExtensionPath, file))
|
|
||||||
|
|
||||||
await installExtensions(extensions)
|
|
||||||
console.debug('Extensions installed')
|
|
||||||
}
|
|
||||||
180
server/index.ts
180
server/index.ts
@ -1,180 +0,0 @@
|
|||||||
import fastify from 'fastify'
|
|
||||||
import dotenv from 'dotenv'
|
|
||||||
import { log } from '@janhq/core/node'
|
|
||||||
import tcpPortUsed from 'tcp-port-used'
|
|
||||||
import { Logger } from './helpers/logger'
|
|
||||||
import CORTEX_SCHEMA from './cortex.json'
|
|
||||||
|
|
||||||
// Load environment variables
|
|
||||||
dotenv.config()
|
|
||||||
|
|
||||||
// Define default settings
|
|
||||||
const JAN_API_HOST = process.env.JAN_API_HOST || '127.0.0.1'
|
|
||||||
const JAN_API_PORT = Number.parseInt(process.env.JAN_API_PORT || '1337')
|
|
||||||
|
|
||||||
// Initialize server settings
|
|
||||||
let server: any | undefined = undefined
|
|
||||||
let hostSetting: string = JAN_API_HOST
|
|
||||||
let portSetting: number = JAN_API_PORT
|
|
||||||
let corsEnabled: boolean = true
|
|
||||||
let isVerbose: boolean = true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server configurations
|
|
||||||
* @param host - The host address for the server
|
|
||||||
* @param port - The port number for the server
|
|
||||||
* @param isCorsEnabled - Flag to enable or disable CORS
|
|
||||||
* @param isVerboseEnabled - Flag to enable or disable verbose logging
|
|
||||||
* @param schemaPath - Path to the OpenAPI schema file
|
|
||||||
* @param baseDir - Base directory for the OpenAPI schema file
|
|
||||||
*/
|
|
||||||
export interface ServerConfig {
|
|
||||||
host?: string
|
|
||||||
port?: number
|
|
||||||
isCorsEnabled?: boolean
|
|
||||||
isVerboseEnabled?: boolean
|
|
||||||
schemaPath?: string
|
|
||||||
baseDir?: string
|
|
||||||
prefix?: string
|
|
||||||
storageAdataper?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to start the server
|
|
||||||
* @param configs - Server configurations
|
|
||||||
*/
|
|
||||||
export const startServer = async (configs?: ServerConfig): Promise<boolean> => {
|
|
||||||
if (configs?.port && configs?.host) {
|
|
||||||
const inUse = await tcpPortUsed.check(Number(configs.port), configs.host)
|
|
||||||
if (inUse) {
|
|
||||||
const errorMessage = `Port ${configs.port} is already in use.`
|
|
||||||
log(errorMessage, '[SERVER]')
|
|
||||||
throw new Error(errorMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update server settings
|
|
||||||
isVerbose = configs?.isVerboseEnabled ?? true
|
|
||||||
hostSetting = configs?.host ?? JAN_API_HOST
|
|
||||||
portSetting = configs?.port ?? JAN_API_PORT
|
|
||||||
corsEnabled = configs?.isCorsEnabled ?? true
|
|
||||||
|
|
||||||
// Start the server
|
|
||||||
try {
|
|
||||||
// Log server start
|
|
||||||
if (isVerbose) log(`Debug: Starting JAN API server...`, '[SERVER]')
|
|
||||||
|
|
||||||
// Initialize Fastify server with logging
|
|
||||||
server = fastify({
|
|
||||||
loggerInstance: new Logger(),
|
|
||||||
// Set body limit to 100MB - Default is 1MB
|
|
||||||
// According to OpenAI - a batch input file can be up to 100 MB in size
|
|
||||||
// Whisper endpoints accept up to 25MB
|
|
||||||
// Vision endpoints accept up to 4MB
|
|
||||||
bodyLimit: 104_857_600,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Register CORS if enabled
|
|
||||||
if (corsEnabled) await server.register(require('@fastify/cors'), {})
|
|
||||||
|
|
||||||
CORTEX_SCHEMA.servers[0].url = configs?.prefix ?? '/v1'
|
|
||||||
// Register Swagger for API documentation
|
|
||||||
await server.register(require('@fastify/swagger'), {
|
|
||||||
mode: 'static',
|
|
||||||
specification: {
|
|
||||||
document: CORTEX_SCHEMA,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const rewriteRequestHeaders = (req: any, headers: any) => {
|
|
||||||
if (req.url.includes('/configs')) return headers
|
|
||||||
return {
|
|
||||||
...headers,
|
|
||||||
authorization: `Bearer ${process.env.appToken}`, // Add or modify Authorization header
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register Swagger UI
|
|
||||||
await server.register(require('@fastify/swagger-ui'), {
|
|
||||||
routePrefix: '/',
|
|
||||||
uiConfig: {
|
|
||||||
docExpansion: 'full',
|
|
||||||
deepLinking: false,
|
|
||||||
},
|
|
||||||
staticCSP: false,
|
|
||||||
transformSpecificationClone: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const proxy = require('@fastify/http-proxy')
|
|
||||||
server.register(proxy, {
|
|
||||||
upstream: `${CORTEX_API_URL}/v1`,
|
|
||||||
prefix: configs?.prefix ?? '/v1',
|
|
||||||
http2: false,
|
|
||||||
replyOptions: {
|
|
||||||
rewriteRequestHeaders,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
server.register(proxy, {
|
|
||||||
upstream: `${CORTEX_API_URL}/processManager`,
|
|
||||||
prefix: '/processManager',
|
|
||||||
http2: false,
|
|
||||||
replyOptions: {
|
|
||||||
rewriteRequestHeaders,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
server.register(proxy, {
|
|
||||||
upstream: `${CORTEX_API_URL}/system`,
|
|
||||||
prefix: '/system',
|
|
||||||
http2: false,
|
|
||||||
replyOptions: {
|
|
||||||
rewriteRequestHeaders,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
server.register(proxy, {
|
|
||||||
upstream: `${CORTEX_API_URL}/healthz`,
|
|
||||||
prefix: '/healthz',
|
|
||||||
http2: false,
|
|
||||||
replyOptions: {
|
|
||||||
rewriteRequestHeaders,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// Start listening for requests
|
|
||||||
await server
|
|
||||||
.listen({
|
|
||||||
port: portSetting,
|
|
||||||
host: hostSetting,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Log server listening
|
|
||||||
if (isVerbose)
|
|
||||||
log(
|
|
||||||
`Debug: JAN API listening at: http://${hostSetting}:${portSetting}`,
|
|
||||||
'[SERVER]'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return true
|
|
||||||
} catch (e) {
|
|
||||||
// Log any errors
|
|
||||||
if (isVerbose) log(`Error: ${e}`, '[SERVER]')
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to stop the server
|
|
||||||
*/
|
|
||||||
export const stopServer = async () => {
|
|
||||||
try {
|
|
||||||
// Log server stop
|
|
||||||
if (isVerbose) log(`Debug: Server stopped`, '[SERVER]')
|
|
||||||
// Stop the server
|
|
||||||
await server?.close()
|
|
||||||
} catch (e) {
|
|
||||||
// Log any errors
|
|
||||||
if (isVerbose) log(`Error: ${e}`, '[SERVER]')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@janhq/server",
|
|
||||||
"version": "0.1.3",
|
|
||||||
"main": "dist/index.js",
|
|
||||||
"author": "Jan <service@jan.ai>",
|
|
||||||
"license": "AGPL-3.0",
|
|
||||||
"homepage": "https://jan.ai",
|
|
||||||
"description": "Jan API Server proxies route all requests to cortex.cpp server with customized configurations.",
|
|
||||||
"files": [
|
|
||||||
"build/**",
|
|
||||||
"cortex.json"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"lint": "eslint . --ext \".js,.jsx,.ts,.tsx\"",
|
|
||||||
"build": "rolldown -c rolldown.config.mjs"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@fastify/cors": "^10.0.1",
|
|
||||||
"@fastify/http-proxy": "^10.0.0",
|
|
||||||
"@fastify/static": "^6.12.0",
|
|
||||||
"@fastify/swagger": "^9.4.0",
|
|
||||||
"@fastify/swagger-ui": "5.2.0",
|
|
||||||
"@janhq/core": "link:../core",
|
|
||||||
"dotenv": "^16.3.1",
|
|
||||||
"fastify": "^5.2.0",
|
|
||||||
"tcp-port-used": "^1.0.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/body-parser": "^1.19.5",
|
|
||||||
"@types/npmcli__arborist": "^5.6.4",
|
|
||||||
"@types/tcp-port-used": "^1.0.4",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
||||||
"@typescript-eslint/parser": "^6.7.3",
|
|
||||||
"eslint-plugin-react": "^7.34.0",
|
|
||||||
"rolldown": "1.0.0-beta.1",
|
|
||||||
"run-script-os": "^1.1.6",
|
|
||||||
"typescript": "^5.3.3"
|
|
||||||
},
|
|
||||||
"bundleDependencies": [
|
|
||||||
"@fastify/swagger-ui"
|
|
||||||
],
|
|
||||||
"packageManager": "yarn@4.5.3"
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
import { defineConfig } from 'rolldown'
|
|
||||||
|
|
||||||
export default defineConfig([
|
|
||||||
{
|
|
||||||
input: 'index.ts',
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
file: 'dist/index.js',
|
|
||||||
sourcemap: true,
|
|
||||||
inlineDynamicImports: true,
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.js', '.ts'],
|
|
||||||
},
|
|
||||||
external: ['@fastify/swagger-ui'],
|
|
||||||
platform: 'node',
|
|
||||||
define: {
|
|
||||||
CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
])
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"module": "commonjs",
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"strict": false,
|
|
||||||
"outDir": "./dist",
|
|
||||||
"rootDir": "./",
|
|
||||||
"noEmitOnError": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"allowJs": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"paths": { "*": ["node_modules/*"] },
|
|
||||||
"typeRoots": ["node_modules/@types"],
|
|
||||||
"ignoreDeprecations": "5.0",
|
|
||||||
"declaration": true,
|
|
||||||
"resolveJsonModule": true
|
|
||||||
},
|
|
||||||
// "sourceMap": true,
|
|
||||||
|
|
||||||
"include": ["./**/*.ts"],
|
|
||||||
"exclude": ["core", "build", "dist", "tests", "node_modules", "extensions"]
|
|
||||||
}
|
|
||||||
@ -50,9 +50,11 @@ export const useModelProvider = create<ModelProviderState>()(
|
|||||||
...provider,
|
...provider,
|
||||||
models: mergedModels,
|
models: mergedModels,
|
||||||
settings: provider.settings.map((setting) => {
|
settings: provider.settings.map((setting) => {
|
||||||
const existingSetting = existingProvider?.settings?.find(
|
const existingSetting = provider.persist
|
||||||
(x) => x.key === setting.key
|
? undefined
|
||||||
)
|
: existingProvider?.settings?.find(
|
||||||
|
(x) => x.key === setting.key
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
...setting,
|
...setting,
|
||||||
controller_props: {
|
controller_props: {
|
||||||
|
|||||||
@ -55,6 +55,7 @@ export const getProviders = async (): Promise<ModelProvider[]> => {
|
|||||||
) ?? []
|
) ?? []
|
||||||
const provider: ModelProvider = {
|
const provider: ModelProvider = {
|
||||||
active: false,
|
active: false,
|
||||||
|
persist: true,
|
||||||
provider: providerName,
|
provider: providerName,
|
||||||
base_url:
|
base_url:
|
||||||
'inferenceUrl' in value
|
'inferenceUrl' in value
|
||||||
|
|||||||
3
web-app/src/types/modelProviders.d.ts
vendored
3
web-app/src/types/modelProviders.d.ts
vendored
@ -45,6 +45,7 @@ type ProviderObject = {
|
|||||||
base_url?: string
|
base_url?: string
|
||||||
settings: ProviderSetting[]
|
settings: ProviderSetting[]
|
||||||
models: Model[]
|
models: Model[]
|
||||||
|
persist?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,4 +68,4 @@ type ProxyOptions = {
|
|||||||
verifyPeerSSL: boolean
|
verifyPeerSSL: boolean
|
||||||
verifyHostSSL: boolean
|
verifyHostSSL: boolean
|
||||||
noProxy: string
|
noProxy: string
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user