Skip to content

Commit

Permalink
Merge branch 'dev' into eckartal-patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
0xHieu01 authored Mar 19, 2024
2 parents a2ff664 + d734c08 commit 6815109
Show file tree
Hide file tree
Showing 264 changed files with 7,193 additions and 2,962 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/jan-electron-linter-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ on:
branches:
- main
- dev
- release/**
paths:
- "electron/**"
- .github/workflows/jan-electron-linter-and-test.yml
Expand Down Expand Up @@ -67,16 +68,17 @@ jobs:

test-on-windows:
strategy:
fail-fast: false
matrix:
antivirus-tools: ['mcafee', 'default-windows-security','bit-defender']
runs-on: windows-desktop-${{ matrix.antivirus-tools }}
steps:
- name: Clean workspace
run: |
Remove-Item -Path .\* -Force -Recurse
Remove-Item -Path "\\?\$(Get-Location)\*" -Force -Recurse
$path = "$Env:APPDATA\jan"
if (Test-Path $path) {
Remove-Item $path -Recurse -Force
Remove-Item "\\?\$path" -Recurse -Force
} else {
Write-Output "Folder does not exist."
}
Expand Down
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
<tr style="text-align:center">
<td style="text-align:center"><b>Stable (Recommended)</b></td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.8/jan-win-x64-0.4.8.exe'>
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-win-x64-0.4.9.exe'>
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
<b>jan.exe</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.8/jan-mac-x64-0.4.8.dmg'>
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-mac-x64-0.4.9.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>Intel</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.8/jan-mac-arm64-0.4.8.dmg'>
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-mac-arm64-0.4.9.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>M1/M2</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.8/jan-linux-amd64-0.4.8.deb'>
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-linux-amd64-0.4.9.deb'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.deb</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.8/jan-linux-x86_64-0.4.8.AppImage'>
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-linux-x86_64-0.4.9.AppImage'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.AppImage</b>
</a>
Expand All @@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
<tr style="text-align:center">
<td style="text-align:center"><b>Experimental (Nightly Build)</b></td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-win-x64-0.4.8-324.exe'>
<a href='https://delta.jan.ai/latest/jan-win-x64-0.4.9-336.exe'>
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
<b>jan.exe</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-mac-x64-0.4.8-324.dmg'>
<a href='https://delta.jan.ai/latest/jan-mac-x64-0.4.9-336.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>Intel</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-mac-arm64-0.4.8-324.dmg'>
<a href='https://delta.jan.ai/latest/jan-mac-arm64-0.4.9-336.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>M1/M2</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-linux-amd64-0.4.8-324.deb'>
<a href='https://delta.jan.ai/latest/jan-linux-amd64-0.4.9-336.deb'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.deb</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-linux-x86_64-0.4.8-324.AppImage'>
<a href='https://delta.jan.ai/latest/jan-linux-x86_64-0.4.9-336.AppImage'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.AppImage</b>
</a>
Expand Down Expand Up @@ -327,6 +327,7 @@ Jan builds on top of other open-source projects:
- [llama.cpp](https://github.com/ggerganov/llama.cpp)
- [LangChain](https://github.com/langchain-ai)
- [TensorRT](https://github.com/NVIDIA/TensorRT)
- [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM)

## Contact

Expand Down
2 changes: 1 addition & 1 deletion core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/node": "^12.0.2",
"@types/node": "^20.11.4",
"eslint": "8.57.0",
"eslint-plugin-jest": "^27.9.0",
"jest": "^29.7.0",
Expand Down
4 changes: 3 additions & 1 deletion core/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export enum AppRoute {
stopServer = 'stopServer',
log = 'log',
logServer = 'logServer',
systemInformations = 'systemInformations',
systemInformation = 'systemInformation',
showToast = 'showToast',
}

Expand Down Expand Up @@ -95,6 +95,8 @@ export enum FileManagerRoute {
getUserHomePath = 'getUserHomePath',
fileStat = 'fileStat',
writeBlob = 'writeBlob',
mkdir = 'mkdir',
rm = 'rm',
}

export type ApiFunction = (...args: any[]) => any
Expand Down
7 changes: 4 additions & 3 deletions core/src/core.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DownloadRequest, FileStat, NetworkConfig } from './types'
import { DownloadRequest, FileStat, NetworkConfig, SystemInformation } from './types'

/**
* Execute a extension module function in main process
Expand Down Expand Up @@ -110,7 +110,8 @@ const isSubdirectory: (from: string, to: string) => Promise<boolean> = (from: st
* Get system information
* @returns {Promise<any>} - A promise that resolves with the system information.
*/
const systemInformations: () => Promise<any> = () => global.core.api?.systemInformations()
const systemInformation: () => Promise<SystemInformation> = () =>
global.core.api?.systemInformation()

/**
* Show toast message from browser processes.
Expand Down Expand Up @@ -146,7 +147,7 @@ export {
log,
isSubdirectory,
getUserHomePath,
systemInformations,
systemInformation,
showToast,
FileStat,
}
8 changes: 8 additions & 0 deletions core/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Compatibility {
const ALL_INSTALLATION_STATE = [
'NotRequired', // not required.
'Installed', // require and installed. Good to go.
'Updatable', // require and installed but need to be updated.
'NotInstalled', // require to be installed.
'Corrupted', // require but corrupted. Need to redownload.
] as const
Expand Down Expand Up @@ -59,6 +60,13 @@ export abstract class BaseExtension implements ExtensionType {
return undefined
}

/**
* Determine if the extension is updatable.
*/
updatable(): boolean {
return false
}

/**
* Determine if the prerequisites for the extension are installed.
*
Expand Down
6 changes: 3 additions & 3 deletions core/src/extensions/ai-engines/LocalOAIEngine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { executeOnMain, getJanDataFolderPath, joinPath } from '../../core'
import { executeOnMain, getJanDataFolderPath, joinPath, systemInformation } from '../../core'
import { events } from '../../events'
import { Model, ModelEvent } from '../../types'
import { OAIEngine } from './OAIEngine'
Expand Down Expand Up @@ -30,11 +30,11 @@ export abstract class LocalOAIEngine extends OAIEngine {
if (model.engine.toString() !== this.provider) return

const modelFolder = await joinPath([await getJanDataFolderPath(), this.modelFolder, model.id])

const systemInfo = await systemInformation()
const res = await executeOnMain(this.nodeModule, this.loadModelFunctionName, {
modelFolder,
model,
})
}, systemInfo)

if (res?.error) {
events.emit(ModelEvent.OnModelFail, {
Expand Down
3 changes: 2 additions & 1 deletion core/src/extensions/monitoring.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseExtension, ExtensionTypeEnum } from '../extension'
import { GpuSetting, MonitoringInterface } from '../index'
import { GpuSetting, MonitoringInterface, OperatingSystemInfo } from '../index'

/**
* Monitoring extension for system monitoring.
Expand All @@ -16,4 +16,5 @@ export abstract class MonitoringExtension extends BaseExtension implements Monit
abstract getGpuSetting(): Promise<GpuSetting>
abstract getResourcesInfo(): Promise<any>
abstract getCurrentLoad(): Promise<any>
abstract getOsInfo(): Promise<OperatingSystemInfo>
}
7 changes: 7 additions & 0 deletions core/src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@ const readdirSync = (...args: any[]) => global.core.api?.readdirSync(...args)
*/
const mkdirSync = (...args: any[]) => global.core.api?.mkdirSync(...args)

const mkdir = (...args: any[]) => global.core.api?.mkdir(...args)

/**
* Removes a directory at the specified path.
* @returns {Promise<any>} A Promise that resolves when the directory is removed successfully.
*/
const rmdirSync = (...args: any[]) =>
global.core.api?.rmdirSync(...args, { recursive: true, force: true })

const rm = (path: string) => global.core.api?.rm(path)

/**
* Deletes a file from the local file system.
* @param {string} path - The path of the file to delete.
Expand Down Expand Up @@ -92,7 +97,9 @@ export const fs = {
existsSync,
readdirSync,
mkdirSync,
mkdir,
rmdirSync,
rm,
unlinkSync,
appendFileSync,
copyFileSync,
Expand Down
24 changes: 24 additions & 0 deletions core/src/node/api/processors/fsExt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,28 @@ export class FSExt implements Processor {
})
})
}

mkdir(path: string): Promise<void> {
return new Promise((resolve, reject) => {
fs.mkdir(path, { recursive: true }, (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}

rm(path: string): Promise<void> {
return new Promise((resolve, reject) => {
fs.rm(path, { recursive: true }, (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}
}
19 changes: 10 additions & 9 deletions core/src/node/extension/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,24 +93,25 @@ export function persistExtensions() {
*/
export async function installExtensions(extensions: any) {
const installed: Extension[] = []
for (const ext of extensions) {
// Set install options and activation based on input type
const installations = extensions.map((ext: any): Promise<void> => {
const isObject = typeof ext === 'object'
const spec = isObject ? [ext.specifier, ext] : [ext]
const activate = isObject ? ext.activate !== false : true

// Install and possibly activate extension
const extension = new Extension(...spec)
if (!extension.origin) {
continue
return Promise.resolve()
}
await extension._install()
if (activate) extension.setActive(true)
return extension._install().then(() => {
if (activate) extension.setActive(true)
// Add extension to store if needed
addExtension(extension)
installed.push(extension)
})
})

// Add extension to store if needed
addExtension(extension)
installed.push(extension)
}
await Promise.all(installations)

// Return list of all installed extensions
return installed
Expand Down
50 changes: 29 additions & 21 deletions core/src/node/helper/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,34 @@ export const getJanExtensionsPath = (): string => {
*/
export const physicalCpuCount = async (): Promise<number> => {
const platform = os.platform()
if (platform === 'linux') {
const output = await exec('lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l')
return parseInt(output.trim(), 10)
} else if (platform === 'darwin') {
const output = await exec('sysctl -n hw.physicalcpu_max')
return parseInt(output.trim(), 10)
} else if (platform === 'win32') {
const output = await exec('WMIC CPU Get NumberOfCores')
return output
.split(os.EOL)
.map((line: string) => parseInt(line))
.filter((value: number) => !isNaN(value))
.reduce((sum: number, number: number) => sum + number, 1)
} else {
const cores = os.cpus().filter((cpu: any, index: number) => {
const hasHyperthreading = cpu.model.includes('Intel')
const isOdd = index % 2 === 1
return !hasHyperthreading || isOdd
})
return cores.length
try {
if (platform === 'linux') {
const output = await exec('lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l')
return parseInt(output.trim(), 10)
} else if (platform === 'darwin') {
const output = await exec('sysctl -n hw.physicalcpu_max')
return parseInt(output.trim(), 10)
} else if (platform === 'win32') {
const output = await exec('WMIC CPU Get NumberOfCores')
return output
.split(os.EOL)
.map((line: string) => parseInt(line))
.filter((value: number) => !isNaN(value))
.reduce((sum: number, number: number) => sum + number, 1)
} else {
const cores = os.cpus().filter((cpu: any, index: number) => {
const hasHyperthreading = cpu.model.includes('Intel')
const isOdd = index % 2 === 1
return !hasHyperthreading || isOdd
})
return cores.length
}
} catch (err) {
console.warn('Failed to get physical CPU count', err)
// Divide by 2 to get rid of hyper threading
const coreCount = Math.ceil(os.cpus().length / 2)
console.debug('Using node API to get physical CPU count:', coreCount)
return coreCount
}
}

Expand All @@ -118,7 +126,7 @@ const exec = async (command: string): Promise<string> => {
}

export const getEngineConfiguration = async (engineId: string) => {
if (engineId !== 'openai') {
if (engineId !== 'openai' && engineId !== 'groq') {
return undefined
}
const directoryPath = join(getJanDataFolderPath(), 'engines')
Expand Down
2 changes: 1 addition & 1 deletion core/src/node/helper/resource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SystemResourceInfo } from '../../types'
import { physicalCpuCount } from './config'
import { log, logServer } from './log'
import { log } from './log'

export const getSystemResourceInfo = async (): Promise<SystemResourceInfo> => {
const cpu = await physicalCpuCount()
Expand Down
Loading

0 comments on commit 6815109

Please sign in to comment.