chore: migrate engine settings on update (#4719)
* chore: migrate engine settings on update * chore: queue engine migration to ensure it only execute when server is on * chore: ensure queue is empty instead of running in the queue
This commit is contained in:
parent
18e289e8f7
commit
bc2f382e64
@ -228,7 +228,7 @@ export abstract class BaseExtension implements ExtensionType {
|
|||||||
|
|
||||||
const settings = await this.getSettings()
|
const settings = await this.getSettings()
|
||||||
|
|
||||||
const updatedSettings = settings.map((setting) => {
|
let updatedSettings = settings.map((setting) => {
|
||||||
const updatedSetting = componentProps.find(
|
const updatedSetting = componentProps.find(
|
||||||
(componentProp) => componentProp.key === setting.key
|
(componentProp) => componentProp.key === setting.key
|
||||||
)
|
)
|
||||||
@ -238,13 +238,20 @@ export abstract class BaseExtension implements ExtensionType {
|
|||||||
return setting
|
return setting
|
||||||
})
|
})
|
||||||
|
|
||||||
const settingPath = await joinPath([
|
if (!updatedSettings.length) updatedSettings = componentProps as SettingComponentProps[]
|
||||||
|
|
||||||
|
const settingFolder = await joinPath([
|
||||||
await getJanDataFolderPath(),
|
await getJanDataFolderPath(),
|
||||||
this.settingFolderName,
|
this.settingFolderName,
|
||||||
this.name,
|
this.name,
|
||||||
this.settingFileName,
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
if (!(await fs.existsSync(settingFolder))) {
|
||||||
|
await fs.mkdir(settingFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingPath = await joinPath([settingFolder, this.settingFileName])
|
||||||
|
|
||||||
await fs.writeFileSync(settingPath, JSON.stringify(updatedSettings, null, 2))
|
await fs.writeFileSync(settingPath, JSON.stringify(updatedSettings, null, 2))
|
||||||
|
|
||||||
updatedSettings.forEach((setting) => {
|
updatedSettings.forEach((setting) => {
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
"author": "Jan <service@jan.ai>",
|
"author": "Jan <service@jan.ai>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "vitest run",
|
||||||
"build": "rolldown -c rolldown.config.mjs",
|
"build": "rolldown -c rolldown.config.mjs",
|
||||||
"codesign:darwin": "../../.github/scripts/auto-sign.sh",
|
"codesign:darwin": "../../.github/scripts/auto-sign.sh",
|
||||||
"codesign:win32:linux": "echo 'No codesigning required'",
|
"codesign:win32:linux": "echo 'No codesigning required'",
|
||||||
@ -25,7 +25,8 @@
|
|||||||
"rolldown": "^1.0.0-beta.1",
|
"rolldown": "^1.0.0-beta.1",
|
||||||
"run-script-os": "^1.1.6",
|
"run-script-os": "^1.1.6",
|
||||||
"ts-loader": "^9.5.0",
|
"ts-loader": "^9.5.0",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3",
|
||||||
|
"vitest": "^3.0.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@janhq/core": "../../core/package.tgz",
|
"@janhq/core": "../../core/package.tgz",
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"transform_resp": {
|
"transform_resp": {
|
||||||
"chat_completions": {
|
"chat_completions": {
|
||||||
"template": "{% if input_request.stream %} {\"object\": \"chat.completion.chunk\", \"model\": \"{{ input_request.model }}\", \"choices\": [{\"index\": 0, \"delta\": { {% if input_request.type == \"message_start\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"ping\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"content_block_delta\" %} \"role\": \"assistant\", \"content\": \"{{ input_request.delta.text }}\" {% else if input_request.type == \"content_block_stop\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"content_block_stop\" %} \"role\": \"assistant\", \"content\": null {% endif %} }, {% if input_request.type == \"content_block_stop\" %} \"finish_reason\": \"stop\" {% else %} \"finish_reason\": null {% endif %} }]} {% else %} {{tojson(input_request)}} {% endif %}"
|
"template": "{% if input_request.stream %} {\"object\": \"chat.completion.chunk\", \"model\": \"{{ input_request.model }}\", \"choices\": [{\"index\": 0, \"delta\": { {% if input_request.type == \"message_start\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"ping\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"content_block_delta\" %} \"role\": \"assistant\", \"content\": \"{{ tojson(input_request.delta.text) }}\" {% else if input_request.type == \"content_block_stop\" %} \"role\": \"assistant\", \"content\": null {% else if input_request.type == \"content_block_stop\" %} \"role\": \"assistant\", \"content\": null {% endif %} }, {% if input_request.type == \"content_block_stop\" %} \"finish_reason\": \"stop\" {% else %} \"finish_reason\": null {% endif %} }]} {% else %} {{tojson(input_request)}} {% endif %}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"explore_models_url": "https://docs.anthropic.com/en/docs/about-claude/models"
|
"explore_models_url": "https://docs.anthropic.com/en/docs/about-claude/models"
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export default defineConfig([
|
|||||||
DEFAULT_REQUEST_HEADERS_TRANSFORM: JSON.stringify(
|
DEFAULT_REQUEST_HEADERS_TRANSFORM: JSON.stringify(
|
||||||
'Authorization: Bearer {{api_key}}'
|
'Authorization: Bearer {{api_key}}'
|
||||||
),
|
),
|
||||||
|
VERSION: JSON.stringify(pkgJson.version ?? '0.0.0'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare const NODE: string
|
|||||||
declare const DEFAULT_REQUEST_PAYLOAD_TRANSFORM: string
|
declare const DEFAULT_REQUEST_PAYLOAD_TRANSFORM: string
|
||||||
declare const DEFAULT_RESPONSE_BODY_TRANSFORM: string
|
declare const DEFAULT_RESPONSE_BODY_TRANSFORM: string
|
||||||
declare const DEFAULT_REQUEST_HEADERS_TRANSFORM: string
|
declare const DEFAULT_REQUEST_HEADERS_TRANSFORM: string
|
||||||
|
declare const VERSION: string
|
||||||
|
|
||||||
declare const DEFAULT_REMOTE_ENGINES: ({
|
declare const DEFAULT_REMOTE_ENGINES: ({
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
60
extensions/engine-management-extension/src/index.test.ts
Normal file
60
extensions/engine-management-extension/src/index.test.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { describe, beforeEach, it, expect, vi } from 'vitest'
|
||||||
|
import JanEngineManagementExtension from './index'
|
||||||
|
import { Engines, InferenceEngine } from '@janhq/core'
|
||||||
|
|
||||||
|
vi.stubGlobal('API_URL', 'http://localhost:3000')
|
||||||
|
|
||||||
|
const mockEngines: Engines = [
|
||||||
|
{
|
||||||
|
name: 'variant1',
|
||||||
|
version: '1.0.0',
|
||||||
|
type: 'local',
|
||||||
|
engine: InferenceEngine.cortex_llamacpp,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
vi.stubGlobal('DEFAULT_REMOTE_ENGINES', mockEngines)
|
||||||
|
|
||||||
|
describe('migrate engine settings', () => {
|
||||||
|
let extension: JanEngineManagementExtension
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
extension = new JanEngineManagementExtension()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('engines should be migrated', async () => {
|
||||||
|
vi.stubGlobal('VERSION', '2.0.0')
|
||||||
|
|
||||||
|
vi.spyOn(extension, 'getEngines').mockResolvedValue([])
|
||||||
|
const mockUpdateEngines = vi
|
||||||
|
.spyOn(extension, 'updateEngine')
|
||||||
|
.mockReturnThis()
|
||||||
|
|
||||||
|
mockUpdateEngines.mockResolvedValue({
|
||||||
|
messages: 'OK',
|
||||||
|
})
|
||||||
|
|
||||||
|
await extension.migrate()
|
||||||
|
|
||||||
|
// Assert that the returned value is equal to the mockEngines object
|
||||||
|
expect(mockUpdateEngines).toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not migrate when extesion version is not updated', async () => {
|
||||||
|
vi.stubGlobal('VERSION', '0.0.0')
|
||||||
|
vi.spyOn(extension, 'getEngines').mockResolvedValue([])
|
||||||
|
const mockUpdateEngines = vi
|
||||||
|
.spyOn(extension, 'updateEngine')
|
||||||
|
.mockReturnThis()
|
||||||
|
|
||||||
|
mockUpdateEngines.mockResolvedValue({
|
||||||
|
messages: 'OK',
|
||||||
|
})
|
||||||
|
|
||||||
|
await extension.migrate()
|
||||||
|
|
||||||
|
// Assert that the returned value is equal to the mockEngines object
|
||||||
|
expect(mockUpdateEngines).not.toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -44,6 +44,9 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
|
|||||||
|
|
||||||
// Populate default remote engines
|
// Populate default remote engines
|
||||||
this.populateDefaultRemoteEngines()
|
this.populateDefaultRemoteEngines()
|
||||||
|
|
||||||
|
// Migrate
|
||||||
|
this.migrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -373,4 +376,36 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
|
|||||||
})
|
})
|
||||||
.catch(console.info)
|
.catch(console.info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update engine settings to the latest version
|
||||||
|
*/
|
||||||
|
migrate = async () => {
|
||||||
|
// Ensure health check is done
|
||||||
|
await this.queue.onEmpty()
|
||||||
|
|
||||||
|
const version = await this.getSetting<string>('version', '0.0.0')
|
||||||
|
const engines = await this.getEngines()
|
||||||
|
if (version < VERSION) {
|
||||||
|
|
||||||
|
console.log('Migrating engine settings...')
|
||||||
|
// Migrate engine settings
|
||||||
|
await Promise.all(
|
||||||
|
DEFAULT_REMOTE_ENGINES.map((engine) => {
|
||||||
|
const { id, ...data } = engine
|
||||||
|
|
||||||
|
data.api_key = engines[id]?.api_key
|
||||||
|
return this.updateEngine(data).catch(console.error)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await this.updateSettings([
|
||||||
|
{
|
||||||
|
key: 'version',
|
||||||
|
controllerProps: {
|
||||||
|
value: VERSION,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,378 +0,0 @@
|
|||||||
import { describe, expect, it } from '@jest/globals'
|
|
||||||
import engine from './index'
|
|
||||||
import { GpuSetting } from '@janhq/core'
|
|
||||||
import { fork } from 'child_process'
|
|
||||||
|
|
||||||
let testSettings: GpuSetting = {
|
|
||||||
run_mode: 'cpu',
|
|
||||||
vulkan: false,
|
|
||||||
cuda: {
|
|
||||||
exist: false,
|
|
||||||
version: '11',
|
|
||||||
},
|
|
||||||
gpu_highest_vram: '0',
|
|
||||||
gpus: [],
|
|
||||||
gpus_in_use: [],
|
|
||||||
is_initial: false,
|
|
||||||
notify: true,
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: false,
|
|
||||||
version: '11',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const originalPlatform = process.platform
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jest.mock('@janhq/core', () => ({
|
|
||||||
appResourcePath: () => '.',
|
|
||||||
log: jest.fn(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
describe('test executable cortex file', () => {
|
|
||||||
afterAll(function () {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: originalPlatform,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on MacOS', () => {
|
|
||||||
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'darwin',
|
|
||||||
})
|
|
||||||
Object.defineProperty(process, 'arch', {
|
|
||||||
value: 'arm64',
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
expect(engine.engineVariant(testSettings)).resolves.toEqual('mac-arm64')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on MacOS', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'darwin',
|
|
||||||
})
|
|
||||||
Object.defineProperty(process, 'arch', {
|
|
||||||
value: 'arm64',
|
|
||||||
})
|
|
||||||
|
|
||||||
const mockProcess = {
|
|
||||||
on: jest.fn((event, callback) => {
|
|
||||||
if (event === 'message') {
|
|
||||||
callback('noavx')
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
send: jest.fn(),
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.defineProperty(process, 'arch', {
|
|
||||||
value: 'x64',
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(engine.engineVariant(testSettings)).resolves.toEqual('mac-amd64')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Windows CPU', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'win32',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'cpu',
|
|
||||||
}
|
|
||||||
const mockProcess = {
|
|
||||||
on: jest.fn((event, callback) => {
|
|
||||||
if (event === 'message') {
|
|
||||||
callback('avx')
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
send: jest.fn(),
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(engine.engineVariant()).resolves.toEqual('windows-amd64-avx')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Windows Cuda 11', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'win32',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '11',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
const mockProcess = {
|
|
||||||
on: jest.fn((event, callback) => {
|
|
||||||
if (event === 'message') {
|
|
||||||
callback('avx2')
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
send: jest.fn(),
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
'windows-amd64-avx2-cuda-11-7'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Windows Cuda 12', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'win32',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
'windows-amd64-noavx-cuda-12-0'
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
'windows-amd64-avx2-cuda-12-0'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Linux CPU', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'cpu',
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(engine.engineVariant()).resolves.toEqual('linux-amd64-noavx')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Linux Cuda 11', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '11',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toBe(
|
|
||||||
'linux-amd64-avx2-cuda-11-7'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('executes on Linux Cuda 12', () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
'linux-amd64-avx2-cuda-12-0'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Generate test for different cpu instructions on Linux
|
|
||||||
it(`executes on Linux CPU with different instructions`, () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'cpu',
|
|
||||||
}
|
|
||||||
|
|
||||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
|
||||||
cpuInstructions.forEach((instruction) => {
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
`linux-amd64-${instruction}`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// Generate test for different cpu instructions on Windows
|
|
||||||
it(`executes on Windows CPU with different instructions`, () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'win32',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'cpu',
|
|
||||||
}
|
|
||||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
|
||||||
cpuInstructions.forEach((instruction) => {
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
`windows-amd64-${instruction}`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Generate test for different cpu instructions on Windows
|
|
||||||
it(`executes on Windows GPU with different instructions`, () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'win32',
|
|
||||||
})
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
|
||||||
cpuInstructions.forEach((instruction) => {
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
`windows-amd64-${instruction === 'avx512' || instruction === 'avx2' ? 'avx2' : 'noavx'}-cuda-12-0`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Generate test for different cpu instructions on Linux
|
|
||||||
it(`executes on Linux GPU with different instructions`, () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
cpuInstructions.forEach((instruction) => {
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
`linux-amd64-${instruction === 'avx512' || instruction === 'avx2' ? 'avx2' : 'noavx'}-cuda-12-0`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Generate test for different cpu instructions on Linux
|
|
||||||
it(`executes on Linux Vulkan should not have CPU instructions included`, () => {
|
|
||||||
Object.defineProperty(process, 'platform', {
|
|
||||||
value: 'linux',
|
|
||||||
})
|
|
||||||
const cpuInstructions = ['avx512', 'avx2', 'avx', 'noavx']
|
|
||||||
const settings: GpuSetting = {
|
|
||||||
...testSettings,
|
|
||||||
run_mode: 'gpu',
|
|
||||||
vulkan: true,
|
|
||||||
cuda: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
nvidia_driver: {
|
|
||||||
exist: true,
|
|
||||||
version: '12',
|
|
||||||
},
|
|
||||||
gpus_in_use: ['0'],
|
|
||||||
gpus: [
|
|
||||||
{
|
|
||||||
id: '0',
|
|
||||||
name: 'NVIDIA GeForce GTX 1080',
|
|
||||||
vram: '80000000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
cpuInstructions.forEach((instruction) => {
|
|
||||||
|
|
||||||
expect(engine.engineVariant(settings)).resolves.toEqual(
|
|
||||||
`linux-amd64-vulkan`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@janhq/model-extension",
|
"name": "@janhq/model-extension",
|
||||||
"productName": "Model Management",
|
"productName": "Model Management",
|
||||||
"version": "1.0.35",
|
"version": "1.0.36",
|
||||||
"description": "Handles model lists, their details, and settings.",
|
"description": "Handles model lists, their details, and settings.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"author": "Jan <service@jan.ai>",
|
"author": "Jan <service@jan.ai>",
|
||||||
|
|||||||
@ -438,7 +438,9 @@ export default class JanModelExtension extends ModelExtension {
|
|||||||
methods: ['get'],
|
methods: ['get'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {})
|
.then(() => {
|
||||||
|
this.queue.concurrency = Infinity
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,17 +1,3 @@
|
|||||||
NEXT_PUBLIC_ENV=development
|
NEXT_PUBLIC_ENV=development
|
||||||
NEXT_PUBLIC_WEB_URL=
|
NEXT_PUBLIC_WEB_URL=
|
||||||
NEXT_PUBLIC_DISCORD_INVITATION_URL=
|
NEXT_PUBLIC_DISCORD_INVITATION_URL=
|
||||||
NEXT_PUBLIC_DOWNLOAD_APP_IOS=
|
|
||||||
NEXT_PUBLIC_DOWNLOAD_APP_ANDROID=
|
|
||||||
NEXT_PUBLIC_GRAPHQL_ENGINE_URL=
|
|
||||||
NEXT_PUBLIC_GRAPHQL_ENGINE_WEB_SOCKET_URL=
|
|
||||||
KEYCLOAK_CLIENT_ID=
|
|
||||||
KEYCLOAK_CLIENT_SECRET=
|
|
||||||
AUTH_ISSUER=
|
|
||||||
NEXTAUTH_URL=
|
|
||||||
NEXTAUTH_SECRET=
|
|
||||||
END_SESSION_URL=
|
|
||||||
REFRESH_TOKEN_URL=
|
|
||||||
// For codegen only
|
|
||||||
HASURA_ADMIN_TOKEN=
|
|
||||||
NEXT_PUBLIC_OPENAPI_ENDPOINT=
|
|
||||||
Loading…
x
Reference in New Issue
Block a user