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', () => {
|
||||
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() {
|
||||
@ -313,6 +330,16 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
.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
|
||||
*/
|
||||
|
||||
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,
|
||||
models: mergedModels,
|
||||
settings: provider.settings.map((setting) => {
|
||||
const existingSetting = existingProvider?.settings?.find(
|
||||
(x) => x.key === setting.key
|
||||
)
|
||||
const existingSetting = provider.persist
|
||||
? undefined
|
||||
: existingProvider?.settings?.find(
|
||||
(x) => x.key === setting.key
|
||||
)
|
||||
return {
|
||||
...setting,
|
||||
controller_props: {
|
||||
|
||||
@ -55,6 +55,7 @@ export const getProviders = async (): Promise<ModelProvider[]> => {
|
||||
) ?? []
|
||||
const provider: ModelProvider = {
|
||||
active: false,
|
||||
persist: true,
|
||||
provider: providerName,
|
||||
base_url:
|
||||
'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
|
||||
settings: ProviderSetting[]
|
||||
models: Model[]
|
||||
persist?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,4 +68,4 @@ type ProxyOptions = {
|
||||
verifyPeerSSL: boolean
|
||||
verifyHostSSL: boolean
|
||||
noProxy: string
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user