Skip to content

Commit

Permalink
Merge pull request #4184 from janhq/dev
Browse files Browse the repository at this point in the history
Release cut 0.5.10
  • Loading branch information
louis-jan authored Dec 2, 2024
2 parents 28e32df + 852d65e commit 0401ae7
Show file tree
Hide file tree
Showing 111 changed files with 2,385 additions and 1,201 deletions.
26 changes: 26 additions & 0 deletions .github/ISSUE_TEMPLATE/roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Goal

## Tasklist

### Frontend
- [ ] link to janhq/jan epics

**Bugs**
- [ ] link to bugs

### Backend
- [ ] link to janhq/cortex.cpp epics

**Bugs**
- [ ] link to bug issues

### Infra
- [ ] link to infra issues

### Administrative / Management
- [ ] link to infra issues

### Marketing

-------
## Resources
13 changes: 0 additions & 13 deletions core/src/browser/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { joinPath } from './core'
import { openFileExplorer } from './core'
import { getJanDataFolderPath } from './core'
import { abortDownload } from './core'
import { getFileSize } from './core'
import { executeOnMain } from './core'

describe('test core apis', () => {
Expand Down Expand Up @@ -66,18 +65,6 @@ describe('test core apis', () => {
expect(result).toBe('aborted')
})

it('should get file size', async () => {
const url = 'http://example.com/file'
globalThis.core = {
api: {
getFileSize: jest.fn().mockResolvedValue(1024),
},
}
const result = await getFileSize(url)
expect(globalThis.core.api.getFileSize).toHaveBeenCalledWith(url)
expect(result).toBe(1024)
})

it('should execute function on main process', async () => {
const extension = 'testExtension'
const method = 'testMethod'
Expand Down
10 changes: 0 additions & 10 deletions core/src/browser/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ const downloadFile: (downloadRequest: DownloadRequest, network?: NetworkConfig)
network
) => globalThis.core?.api?.downloadFile(downloadRequest, network)

/**
* Get unit in bytes for a remote file.
*
* @param url - The url of the file.
* @returns {Promise<number>} - A promise that resolves with the file size.
*/
const getFileSize: (url: string) => Promise<number> = (url: string) =>
globalThis.core.api?.getFileSize(url)

/**
* Aborts the download of a specific file.
* @param {string} fileName - The name of the file whose download is to be aborted.
Expand Down Expand Up @@ -167,7 +158,6 @@ export {
getUserHomePath,
systemInformation,
showToast,
getFileSize,
dirName,
FileStat,
}
17 changes: 5 additions & 12 deletions core/src/node/api/processors/download.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jest.mock('fs', () => ({
createWriteStream: jest.fn(),
}))

const requestMock = jest.fn((options, callback) => {
callback(new Error('Test error'), null)
})
jest.mock('request', () => requestMock)

jest.mock('request-progress', () => {
return jest.fn().mockImplementation(() => {
return {
Expand Down Expand Up @@ -54,18 +59,6 @@ describe('Downloader', () => {
beforeEach(() => {
jest.resetAllMocks()
})
it('should handle getFileSize errors correctly', async () => {
const observer = jest.fn()
const url = 'http://example.com/file'

const downloader = new Downloader(observer)
const requestMock = jest.fn((options, callback) => {
callback(new Error('Test error'), null)
})
jest.mock('request', () => requestMock)

await expect(downloader.getFileSize(observer, url)).rejects.toThrow('Test error')
})

it('should pause download correctly', () => {
const observer = jest.fn()
Expand Down
21 changes: 0 additions & 21 deletions core/src/node/api/processors/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,25 +135,4 @@ export class Downloader implements Processor {
pauseDownload(_observer: any, fileName: any) {
DownloadManager.instance.networkRequests[fileName]?.pause()
}

async getFileSize(_observer: any, url: string): Promise<number> {
return new Promise((resolve, reject) => {
const request = require('request')
request(
{
url,
method: 'HEAD',
},
function (err: any, response: any) {
if (err) {
console.error('Getting file size failed:', err)
reject(err)
} else {
const size: number = response.headers['content-length'] ?? -1
resolve(size)
}
}
)
})
}
}
34 changes: 15 additions & 19 deletions core/src/node/api/restful/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HttpServer } from '../HttpServer'
import {
chatCompletions,
deleteBuilder,
downloadModel,
getBuilder,
retrieveBuilder,
Expand All @@ -14,8 +13,6 @@ import {
} from './helper/builder'

import { JanApiRouteConfiguration } from './helper/configuration'
import { startModel, stopModel } from './helper/startStopModel'
import { ModelSettingParams } from '../../../types'

export const commonRouter = async (app: HttpServer) => {
const normalizeData = (data: any) => {
Expand All @@ -28,19 +25,25 @@ export const commonRouter = async (app: HttpServer) => {
// Read & Delete :: Threads | Models | Assistants
Object.keys(JanApiRouteConfiguration).forEach((key) => {
app.get(`/${key}`, async (_req, _res) => {
if (key === 'models') {
if (key.includes('models')) {
return models(_req, _res)
}
return getBuilder(JanApiRouteConfiguration[key]).then(normalizeData)
})

app.get(`/${key}/:id`, async (request: any) =>
retrieveBuilder(JanApiRouteConfiguration[key], request.params.id)
)
app.get(`/${key}/:id`, async (_req: any, _res: any) => {
if (key.includes('models')) {
return models(_req, _res)
}
return retrieveBuilder(JanApiRouteConfiguration[key], _req.params.id)
})

app.delete(`/${key}/:id`, async (request: any) =>
deleteBuilder(JanApiRouteConfiguration[key], request.params.id)
)
app.delete(`/${key}/:id`, async (_req: any, _res: any) => {
if (key.includes('models')) {
return models(_req, _res)
}
return retrieveBuilder(JanApiRouteConfiguration[key], _req.params.id)
})
})

// Threads
Expand Down Expand Up @@ -70,16 +73,9 @@ export const commonRouter = async (app: HttpServer) => {
})
)

app.put(`/models/:modelId/start`, async (request: any) => {
let settingParams: ModelSettingParams | undefined = undefined
if (Object.keys(request.body).length !== 0) {
settingParams = JSON.parse(request.body) as ModelSettingParams
}

return startModel(request.params.modelId, settingParams)
})
app.post(`/models/start`, async (request: any, reply: any) => models(request, reply))

app.put(`/models/:modelId/stop`, async (request: any) => stopModel(request.params.modelId))
app.post(`/models/stop`, async (request: any, reply: any) => models(request, reply))

// Chat Completion
app.post(`/chat/completions`, async (request: any, reply: any) => chatCompletions(request, reply))
Expand Down
40 changes: 1 addition & 39 deletions core/src/node/api/restful/helper/builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import {
existsSync,
readdirSync,
readFileSync,
writeFileSync,
mkdirSync,
appendFileSync,
rmdirSync,
} from 'fs'
import { join } from 'path'
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, appendFileSync } from 'fs'
import {
getBuilder,
retrieveBuilder,
deleteBuilder,
getMessages,
retrieveMessage,
createThread,
Expand Down Expand Up @@ -82,34 +72,6 @@ describe('builder helper functions', () => {
})
})

describe('deleteBuilder', () => {
it('should return a message if trying to delete Jan assistant', async () => {
const result = await deleteBuilder({ ...mockConfiguration, dirName: 'assistants' }, 'jan')
expect(result).toEqual({ message: 'Cannot delete Jan assistant' })
})

it('should return a message if data is not found', async () => {
;(existsSync as jest.Mock).mockReturnValue(true)
;(readdirSync as jest.Mock).mockReturnValue(['file1'])
;(readFileSync as jest.Mock).mockReturnValue(JSON.stringify({ id: 'model1' }))

const result = await deleteBuilder(mockConfiguration, 'nonexistentId')
expect(result).toEqual({ message: 'Not found' })
})

it('should delete the directory and return success message', async () => {
;(existsSync as jest.Mock).mockReturnValue(true)
;(readdirSync as jest.Mock).mockReturnValue(['file1'])
;(readFileSync as jest.Mock).mockReturnValue(JSON.stringify({ id: 'model1' }))

const result = await deleteBuilder(mockConfiguration, 'model1')
expect(rmdirSync).toHaveBeenCalledWith(join('/mock/path', 'mockDir', 'model1'), {
recursive: true,
})
expect(result).toEqual({ id: 'model1', object: 'mockObject', deleted: true })
})
})

describe('getMessages', () => {
it('should return an empty array if message file does not exist', async () => {
;(existsSync as jest.Mock).mockReturnValue(false)
Expand Down
30 changes: 1 addition & 29 deletions core/src/node/api/restful/helper/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,34 +73,6 @@ export const retrieveBuilder = async (configuration: RouteConfiguration, id: str
return filteredData
}

export const deleteBuilder = async (configuration: RouteConfiguration, id: string) => {
if (configuration.dirName === 'assistants' && id === 'jan') {
return {
message: 'Cannot delete Jan assistant',
}
}

const directoryPath = join(getJanDataFolderPath(), configuration.dirName)
try {
const data = await retrieveBuilder(configuration, id)
if (!data) {
return {
message: 'Not found',
}
}

const objectPath = join(directoryPath, id)
rmdirSync(objectPath, { recursive: true })
return {
id: id,
object: configuration.delete.object,
deleted: true,
}
} catch (ex) {
console.error(ex)
}
}

export const getMessages = async (threadId: string): Promise<ThreadMessage[]> => {
const threadDirPath = join(getJanDataFolderPath(), 'threads', threadId)
const messageFile = 'messages.jsonl'
Expand Down Expand Up @@ -308,7 +280,7 @@ export const models = async (request: any, reply: any) => {
'Content-Type': 'application/json',
}

const response = await fetch(`${CORTEX_API_URL}/models`, {
const response = await fetch(`${CORTEX_API_URL}/models${request.url.split('/models')[1] ?? ""}`, {
method: request.method,
headers: headers,
body: JSON.stringify(request.body),
Expand Down
10 changes: 0 additions & 10 deletions core/src/node/api/restful/helper/startStopModel.test.ts

This file was deleted.

25 changes: 0 additions & 25 deletions core/src/node/api/restful/helper/startStopModel.ts

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/types/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum NativeRoute {

quickAskSizeUpdated = 'quickAskSizeUpdated',
ackDeepLink = 'ackDeepLink',
factoryReset = 'factoryReset'
}

/**
Expand Down Expand Up @@ -65,7 +66,6 @@ export enum DownloadRoute {
pauseDownload = 'pauseDownload',
resumeDownload = 'resumeDownload',
getDownloadProgress = 'getDownloadProgress',
getFileSize = 'getFileSize',
}

export enum DownloadEvent {
Expand Down
4 changes: 2 additions & 2 deletions core/src/types/setting/settingComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type SettingComponentProps = {

export type ConfigType = 'runtime' | 'setting'

export type ControllerType = 'slider' | 'checkbox' | 'input'
export type ControllerType = 'slider' | 'checkbox' | 'input' | 'tag'

export type InputType = 'password' | 'text' | 'email' | 'number' | 'tel' | 'url'

Expand All @@ -22,7 +22,7 @@ export type InputAction = InputActionsTuple[number]

export type InputComponentProps = {
placeholder: string
value: string
value: string | string[]
type?: InputType
textAlign?: 'left' | 'right'
inputActions?: InputAction[]
Expand Down
1 change: 1 addition & 0 deletions docs/src/pages/docs/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"desktop": "Desktop",
"data-folder": "Jan Data Folder",
"privacy": "Privacy",
"user-guides": {
"title": "BASIC USAGE",
"type": "separator"
Expand Down
Loading

0 comments on commit 0401ae7

Please sign in to comment.