fix: engine version update - cortex version bump - update tests (#4787)

This commit is contained in:
Louis 2025-03-10 13:26:48 +07:00 committed by GitHub
parent 77717a780e
commit 455d320d35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 133 additions and 77 deletions

View File

@ -11,9 +11,11 @@ export default defineConfig([
},
define: {
NODE: JSON.stringify(`${pkgJson.name}/${pkgJson.node}`),
API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`),
API_URL: JSON.stringify(
`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}`
),
PLATFORM: JSON.stringify(process.platform),
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.49'),
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.54'),
DEFAULT_REMOTE_ENGINES: JSON.stringify(engines),
DEFAULT_REMOTE_MODELS: JSON.stringify(models),
DEFAULT_REQUEST_PAYLOAD_TRANSFORM: JSON.stringify(
@ -36,7 +38,7 @@ export default defineConfig([
file: 'dist/node/index.cjs.js',
},
define: {
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.49'),
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.54'),
},
},
])

View File

@ -286,7 +286,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
if (
!installedEngines.some(
(e) => e.name === variant.variant && e.version === variant.version
)
) || variant.version < CORTEX_ENGINE_VERSION
) {
throw new EngineError(
'Default engine is not available, use bundled version.'

View File

@ -1,8 +1,4 @@
import {
executeOnMain,
HardwareManagementExtension,
HardwareInformation,
} from '@janhq/core'
import { HardwareManagementExtension, HardwareInformation } from '@janhq/core'
import ky from 'ky'
import PQueue from 'p-queue'

View File

@ -1 +1 @@
1.0.11-rc6
1.0.11-rc7

View File

@ -2,7 +2,7 @@
set BIN_PATH=./bin
set SHARED_PATH=./../../electron/shared
set /p CORTEX_VERSION=<./bin/version.txt
set ENGINE_VERSION=0.1.49
set ENGINE_VERSION=0.1.54
@REM Download cortex.llamacpp binaries
set DOWNLOAD_URL=https://github.com/janhq/cortex.llamacpp/releases/download/v%ENGINE_VERSION%/cortex.llamacpp-%ENGINE_VERSION%-windows-amd64

View File

@ -2,7 +2,7 @@
# Read CORTEX_VERSION
CORTEX_VERSION=$(cat ./bin/version.txt)
ENGINE_VERSION=0.1.49
ENGINE_VERSION=0.1.54
CORTEX_RELEASE_URL="https://github.com/janhq/cortex.cpp/releases/download"
ENGINE_DOWNLOAD_URL="https://github.com/janhq/cortex.llamacpp/releases/download/v${ENGINE_VERSION}/cortex.llamacpp-${ENGINE_VERSION}"
CUDA_DOWNLOAD_URL="https://github.com/janhq/cortex.llamacpp/releases/download/v${ENGINE_VERSION}"

View File

@ -1,5 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

View File

@ -8,7 +8,7 @@
"author": "Jan <service@jan.ai>",
"license": "AGPL-3.0",
"scripts": {
"test": "jest",
"test": "vitest run",
"build": "rolldown -c rolldown.config.mjs",
"downloadcortex:linux:darwin": "./download.sh",
"downloadcortex:win32": "download.bat",
@ -35,17 +35,15 @@
"rolldown": "1.0.0-beta.1",
"run-script-os": "^1.1.6",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"vitest": "^3.0.8"
},
"dependencies": {
"@janhq/core": "../../core/package.tgz",
"decompress": "^4.2.1",
"fetch-retry": "^5.0.6",
"ky": "^1.7.2",
"p-queue": "^8.0.1",
"rxjs": "^7.8.1",
"tcp-port-used": "^1.0.2",
"terminate": "2.6.1",
"ulidx": "^2.3.0"
},
"engines": {

View File

@ -13,9 +13,13 @@ export default defineConfig([
define: {
NODE: JSON.stringify(`${packageJson.name}/${packageJson.node}`),
SETTINGS: JSON.stringify(defaultSettingJson),
CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`),
CORTEX_SOCKET_URL: JSON.stringify(`ws://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`),
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.49'),
CORTEX_API_URL: JSON.stringify(
`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}`
),
CORTEX_SOCKET_URL: JSON.stringify(
`ws://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}`
),
CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.54'),
},
},
{
@ -31,7 +35,9 @@ export default defineConfig([
extensions: ['.js', '.ts', '.json'],
},
define: {
CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`),
CORTEX_API_URL: JSON.stringify(
`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}`
),
},
platform: 'node',
},

View File

@ -10,15 +10,11 @@ import {
Model,
executeOnMain,
EngineEvent,
joinPath,
LocalOAIEngine,
InferenceEngine,
getJanDataFolderPath,
extractModelLoadParams,
fs,
events,
ModelEvent,
dirName,
} from '@janhq/core'
import PQueue from 'p-queue'
import ky from 'ky'

View File

@ -1,6 +1,14 @@
jest.mock('@janhq/core/node', () => ({
...jest.requireActual('@janhq/core/node'),
import { describe, it, expect, vi } from 'vitest'
// Mocks
const CORTEX_API_URL = 'http://localhost:3000'
vi.stubGlobal('CORTEX_API_URL', CORTEX_API_URL)
vi.mock('@janhq/core/node', (actual) => ({
...actual(),
getJanDataFolderPath: () => '',
appResourcePath: () => '/mock/path',
log: vi.fn(),
getSystemResourceInfo: () => {
return {
cpu: {
@ -30,25 +38,36 @@ jest.mock('@janhq/core/node', () => ({
},
}))
jest.mock('fs', () => ({
vi.mock('fs', () => ({
default: {
readdirSync: () => [],
},
}))
jest.mock('child_process', () => ({
vi.mock('./watchdog', () => {
return {
ProcessWatchdog: vi.fn().mockImplementation(() => {
return {
start: vi.fn(),
terminate: vi.fn(),
}
}),
}
})
vi.mock('child_process', () => ({
exec: () => {
return {
stdout: { on: jest.fn() },
stderr: { on: jest.fn() },
on: jest.fn(),
stdout: { on: vi.fn() },
stderr: { on: vi.fn() },
on: vi.fn(),
}
},
spawn: () => {
return {
stdout: { on: jest.fn() },
stderr: { on: jest.fn() },
on: jest.fn(),
stdout: { on: vi.fn() },
stderr: { on: vi.fn() },
on: vi.fn(),
pid: '111',
}
},
@ -56,28 +75,70 @@ jest.mock('child_process', () => ({
import index from './index'
describe('dispose', () => {
it('should dispose a model successfully on Mac', async () => {
Object.defineProperty(process, 'platform', {
value: 'darwin',
describe('Cortex extension node interface', () => {
describe('run', () => {
it('should start the cortex subprocess on macOS', async () => {
Object.defineProperty(process, 'platform', {
value: 'darwin',
})
const result = await index.run()
expect(result).toBeUndefined()
})
// Call the dispose function
const result = await index.dispose()
it('should start the cortex subprocess on Windows', async () => {
Object.defineProperty(process, 'platform', {
value: 'win32',
})
// Assert that the result is as expected
expect(result).toBeUndefined()
const result = await index.run()
expect(result).toBeUndefined()
})
it('should set the proper environment variables based on platform', async () => {
// Test for Windows
Object.defineProperty(process, 'platform', {
value: 'win32',
})
process.env.PATH = '/original/path'
await index.run()
expect(process.env.PATH).toContain('/original/path')
// Test for non-Windows (macOS/Linux)
Object.defineProperty(process, 'platform', {
value: 'darwin',
})
process.env.LD_LIBRARY_PATH = '/original/ld/path'
await index.run()
expect(process.env.LD_LIBRARY_PATH).toContain('/original/ld/path')
})
})
it('should kill the subprocess successfully on Windows', async () => {
Object.defineProperty(process, 'platform', {
value: 'win32',
describe('dispose', () => {
it('should dispose a model successfully on Mac', async () => {
Object.defineProperty(process, 'platform', {
value: 'darwin',
})
// Call the dispose function
const result = index.dispose()
// Assert that the result is as expected
expect(result).toBeUndefined()
})
// Call the killSubprocess function
const result = await index.dispose()
it('should kill the subprocess successfully on Windows', async () => {
Object.defineProperty(process, 'platform', {
value: 'win32',
})
// Assert that the result is as expected
expect(result).toBeUndefined()
// Call the dispose function
const result = index.dispose()
// Assert that the result is as expected
expect(result).toBeUndefined()
})
})
})

View File

@ -1,13 +1,7 @@
import path from 'path'
import {
appResourcePath,
getJanDataFolderPath,
log,
} from '@janhq/core/node'
import { appResourcePath, getJanDataFolderPath, log } from '@janhq/core/node'
import { ProcessWatchdog } from './watchdog'
// The HOST address to use for the Nitro subprocess
const LOCAL_PORT = CORTEX_API_URL.split(":").pop() ?? "39291"
let watchdog: ProcessWatchdog | undefined = undefined
/**
@ -37,6 +31,9 @@ function run(): Promise<any> {
watchdog.terminate()
}
// The HOST address to use for the cortex subprocess
const LOCAL_PORT = CORTEX_API_URL.split(':').pop() ?? '39291'
watchdog = new ProcessWatchdog(
executablePath,
[

View File

@ -67,13 +67,18 @@ const LocalEngineSettings = ({ engine }: { engine: InferenceEngine }) => {
RecommendEngineVariantAtom
)
const isEngineUpdated =
latestReleasedEngine &&
latestReleasedEngine.some((item) =>
item.name.includes(
defaultEngineVariant?.version.replace(/^v/, '') as string
)
const isEngineUpdated = useMemo(() => {
if (!latestReleasedEngine || !defaultEngineVariant) return false
const latestVariant = latestReleasedEngine.find((item) =>
item.name.includes(defaultEngineVariant.variant)
)
if (!latestVariant) return false
const latestVersion = latestVariant.name
.replace(defaultEngineVariant.variant, '')
.replaceAll('-', '')
const currentVersion = defaultEngineVariant.version.replace(/^v/, '')
return latestVersion <= currentVersion
}, [latestReleasedEngine, defaultEngineVariant])
const availableVariants = useMemo(
() =>

View File

@ -170,7 +170,7 @@ const ChatInput = () => {
!!fileUpload ||
(activeAssistant?.tools &&
!activeAssistant?.tools[0]?.enabled &&
!activeAssistant?.model.settings?.vision_model)
!activeAssistant?.model.settings?.mmproj)
) {
e.stopPropagation()
} else {
@ -193,7 +193,7 @@ const ChatInput = () => {
{!!fileUpload ||
(activeAssistant?.tools &&
!activeAssistant?.tools[0]?.enabled &&
!activeAssistant?.model.settings?.vision_model && (
!activeAssistant?.model.settings?.mmproj && (
<>
{!!fileUpload && (
<span>
@ -231,13 +231,13 @@ const ChatInput = () => {
<li
className={twMerge(
'text-[hsla(var(--text-secondary)] hover:bg-secondary flex w-full items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]',
activeAssistant?.model.settings?.vision_model &&
activeAssistant?.model.settings?.mmproj &&
isModelSupportRagAndTools
? 'cursor-pointer'
: 'cursor-not-allowed opacity-50'
)}
onClick={() => {
if (activeAssistant?.model.settings?.vision_model) {
if (activeAssistant?.model.settings?.mmproj) {
imageInputRef.current?.click()
setShowAttachmentMenus(false)
}

View File

@ -61,7 +61,7 @@ const ThreadCenterPanel = () => {
const activeAssistant = useAtomValue(activeAssistantAtom)
const chatWidth = useAtomValue(chatWidthAtom)
const upload = uploader()
const acceptedFormat: Accept = activeAssistant?.model.settings?.vision_model
const acceptedFormat: Accept = activeAssistant?.model.settings?.mmproj
? {
'application/pdf': ['.pdf'],
'image/jpeg': ['.jpeg'],
@ -83,7 +83,7 @@ const ThreadCenterPanel = () => {
if (
e.dataTransfer.items.length === 1 &&
((activeAssistant?.tools && activeAssistant?.tools[0]?.enabled) ||
activeAssistant?.model.settings?.vision_model)
activeAssistant?.model.settings?.mmproj)
) {
setDragOver(true)
} else if (
@ -105,7 +105,7 @@ const ThreadCenterPanel = () => {
rejectFiles.length !== 0 ||
(activeAssistant?.tools &&
!activeAssistant?.tools[0]?.enabled &&
!activeAssistant?.model.settings?.vision_model)
!activeAssistant?.model.settings?.mmproj)
)
return
const imageType = files[0]?.type.includes('image')
@ -182,7 +182,7 @@ const ThreadCenterPanel = () => {
<h6 className="font-bold">
{isDragReject
? `Currently, we only support 1 attachment at the same time with ${
activeAssistant?.model.settings?.vision_model
activeAssistant?.model.settings?.mmproj
? 'PDF, JPEG, JPG, PNG'
: 'PDF'
} format`
@ -190,7 +190,7 @@ const ThreadCenterPanel = () => {
</h6>
{!isDragReject && (
<p className="mt-2">
{activeAssistant?.model.settings?.vision_model
{activeAssistant?.model.settings?.mmproj
? 'PDF, JPEG, JPG, PNG'
: 'PDF'}
</p>