Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: reroute threads and messages requests to cortex.cpp backend #4249

Merged
merged 13 commits into from
Dec 17, 2024
29 changes: 23 additions & 6 deletions core/src/browser/extensions/conversational.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Thread, ThreadInterface, ThreadMessage, MessageInterface } from '../../types'
import {
Thread,
ThreadInterface,
ThreadMessage,
MessageInterface,
ThreadAssistantInfo,
} from '../../types'
import { BaseExtension, ExtensionTypeEnum } from '../extension'

/**
Expand All @@ -14,13 +20,24 @@
* Conversation extension type.
*/
type(): ExtensionTypeEnum | undefined {
return ExtensionTypeEnum.Conversational

Check warning on line 23 in core/src/browser/extensions/conversational.ts

View workflow job for this annotation

GitHub Actions / coverage-check

23 line is not covered with tests
}

abstract getThreads(): Promise<Thread[]>
abstract saveThread(thread: Thread): Promise<void>
abstract listThreads(): Promise<Thread[]>
abstract createThread(thread: Partial<Thread>): Promise<Thread>
abstract modifyThread(thread: Thread): Promise<void>
abstract deleteThread(threadId: string): Promise<void>
abstract addNewMessage(message: ThreadMessage): Promise<void>
abstract writeMessages(threadId: string, messages: ThreadMessage[]): Promise<void>
abstract getAllMessages(threadId: string): Promise<ThreadMessage[]>
abstract createMessage(message: Partial<ThreadMessage>): Promise<ThreadMessage>
abstract deleteMessage(threadId: string, messageId: string): Promise<void>
abstract listMessages(threadId: string): Promise<ThreadMessage[]>
abstract getThreadAssistant(threadId: string): Promise<ThreadAssistantInfo>
abstract createThreadAssistant(
threadId: string,
assistant: ThreadAssistantInfo
): Promise<ThreadAssistantInfo>
abstract modifyThreadAssistant(
threadId: string,
assistant: ThreadAssistantInfo
): Promise<ThreadAssistantInfo>
abstract modifyMessage(message: ThreadMessage): Promise<ThreadMessage>
}
1 change: 0 additions & 1 deletion core/src/browser/extensions/engines/AIEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { events } from '../../events'
import { BaseExtension } from '../../extension'
import { MessageRequest, Model, ModelEvent } from '../../../types'
import { EngineManager } from './EngineManager'
import { ModelManager } from '../../models/manager'

/**
* Base AIEngine
Expand Down
5 changes: 2 additions & 3 deletions core/src/node/api/restful/helper/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
mkdirSync,
appendFileSync,
createWriteStream,
rmdirSync,
} from 'fs'
import { JanApiRouteConfiguration, RouteConfiguration } from './configuration'
import { join } from 'path'
Expand Down Expand Up @@ -42,15 +41,15 @@
try {
return JSON.parse(result)
} catch (err) {
console.error(err)

Check warning on line 44 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

44 line is not covered with tests
}
})
.filter((e: any) => !!e)

return modelData
} catch (err) {
console.error(err)
return []

Check warning on line 52 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

51-52 lines are not covered with tests
}
}

Expand All @@ -58,7 +57,7 @@
if (existsSync(path)) {
return readFileSync(path, 'utf-8')
} else {
return undefined

Check warning on line 60 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

60 line is not covered with tests
}
}

Expand All @@ -85,8 +84,8 @@

const messageFilePath = join(threadDirPath, messageFile)
if (!existsSync(messageFilePath)) {
console.debug('message file not found')
return []

Check warning on line 88 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

87-88 lines are not covered with tests
}

const lines = readFileSync(messageFilePath, 'utf-8')
Expand All @@ -100,8 +99,8 @@
})
return messages
} catch (err) {
console.error(err)
return []

Check warning on line 103 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

102-103 lines are not covered with tests
}
}

Expand All @@ -126,7 +125,7 @@
}
}

const threadId = generateThreadId(thread.assistants[0].assistant_id)
const threadId = generateThreadId(thread.assistants[0]?.assistant_id)
try {
const updatedThread = {
...thread,
Expand All @@ -144,7 +143,7 @@
await writeFileSync(threadJsonPath, JSON.stringify(updatedThread, null, 2))
return updatedThread
} catch (err) {
return {

Check warning on line 146 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

146 line is not covered with tests
error: err,
}
}
Expand Down Expand Up @@ -174,7 +173,7 @@
await writeFileSync(threadJsonPath, JSON.stringify(updatedThread, null, 2))
return updatedThread
} catch (err) {
return {

Check warning on line 176 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

176 line is not covered with tests
message: err,
}
}
Expand Down Expand Up @@ -219,7 +218,7 @@
appendFileSync(threadMessagePath, JSON.stringify(threadMessage) + '\n')
return threadMessage
} catch (err) {
return {

Check warning on line 221 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

221 line is not covered with tests
message: err,
}
}
Expand All @@ -240,7 +239,7 @@

const directoryPath = join(getJanDataFolderPath(), 'models', modelId)
if (!existsSync(directoryPath)) {
mkdirSync(directoryPath)

Check warning on line 242 in core/src/node/api/restful/helper/builder.ts

View workflow job for this annotation

GitHub Actions / coverage-check

242 line is not covered with tests
}

// path to model binary
Expand Down Expand Up @@ -280,7 +279,7 @@
'Content-Type': 'application/json',
}

const response = await fetch(`${CORTEX_API_URL}/models${request.url.split('/models')[1] ?? ""}`, {
const response = await fetch(`${CORTEX_API_URL}/models${request.url.split('/models')[1] ?? ''}`, {
louis-jan marked this conversation as resolved.
Show resolved Hide resolved
method: request.method,
headers: headers,
body: JSON.stringify(request.body),
Expand Down
7 changes: 7 additions & 0 deletions core/src/types/assistant/assistantEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ export type Assistant = {
/** Represents the metadata of the object. */
metadata?: Record<string, unknown>
}

export interface CodeInterpreterTool {
/**
* The type of tool being defined: `code_interpreter`
*/
type: 'code_interpreter'
}
58 changes: 53 additions & 5 deletions core/src/types/message/messageEntity.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CodeInterpreterTool } from '../assistant'
import { ChatCompletionMessage, ChatCompletionRole } from '../inference'
import { ModelInfo } from '../model'
import { Thread } from '../thread'
Expand All @@ -15,6 +16,10 @@ export type ThreadMessage = {
thread_id: string
/** The assistant id of this thread. **/
assistant_id?: string
/**
* A list of files attached to the message, and the tools they were added to.
*/
attachments?: Array<Attachment> | null
/** The role of the author of this message. **/
role: ChatCompletionRole
/** The content of this message. **/
Expand Down Expand Up @@ -52,6 +57,11 @@ export type MessageRequest = {
*/
assistantId?: string

/**
* A list of files attached to the message, and the tools they were added to.
*/
attachments: Array<Attachment> | null

/** Messages for constructing a chat completion request **/
messages?: ChatCompletionMessage[]

Expand Down Expand Up @@ -97,8 +107,7 @@ export enum ErrorCode {
*/
export enum ContentType {
Text = 'text',
Image = 'image',
Pdf = 'pdf',
Image = 'image_url',
}

/**
Expand All @@ -108,8 +117,15 @@ export enum ContentType {
export type ContentValue = {
value: string
annotations: string[]
name?: string
size?: number
}

/**
* The `ImageContentValue` type defines the shape of a content value object of image type
* @data_transfer_object
*/
export type ImageContentValue = {
detail?: string
url?: string
}

/**
Expand All @@ -118,5 +134,37 @@ export type ContentValue = {
*/
export type ThreadContent = {
type: ContentType
text: ContentValue
text?: ContentValue
image_url?: ImageContentValue
}

export interface Attachment {
/**
* The ID of the file to attach to the message.
*/
file_id?: string

/**
* The tools to add this file to.
*/
tools?: Array<CodeInterpreterTool | Attachment.AssistantToolsFileSearchTypeOnly>
}

export namespace Attachment {
export interface AssistantToolsFileSearchTypeOnly {
/**
* The type of tool being defined: `file_search`
*/
type: 'file_search'
}
}

/**
* On an incomplete message, details about why the message is incomplete.
*/
export interface IncompleteDetails {
/**
* The reason the message is incomplete.
*/
reason: 'content_filter' | 'max_tokens' | 'run_cancelled' | 'run_expired' | 'run_failed'
}
20 changes: 10 additions & 10 deletions core/src/types/message/messageInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ export interface MessageInterface {
* @param {ThreadMessage} message - The message to be added.
* @returns {Promise<void>} A promise that resolves when the message has been added.
*/
addNewMessage(message: ThreadMessage): Promise<void>

/**
* Writes an array of messages to a specific thread.
* @param {string} threadId - The ID of the thread to write the messages to.
* @param {ThreadMessage[]} messages - The array of messages to be written.
* @returns {Promise<void>} A promise that resolves when the messages have been written.
*/
writeMessages(threadId: string, messages: ThreadMessage[]): Promise<void>
createMessage(message: ThreadMessage): Promise<ThreadMessage>

/**
* Retrieves all messages from a specific thread.
* @param {string} threadId - The ID of the thread to retrieve the messages from.
* @returns {Promise<ThreadMessage[]>} A promise that resolves to an array of messages from the thread.
*/
getAllMessages(threadId: string): Promise<ThreadMessage[]>
listMessages(threadId: string): Promise<ThreadMessage[]>

/**
* Deletes a specific message from a thread.
* @param {string} threadId - The ID of the thread from which the message will be deleted.
* @param {string} messageId - The ID of the message to be deleted.
* @returns {Promise<void>} A promise that resolves when the message has been successfully deleted.
*/
deleteMessage(threadId: string, messageId: string): Promise<void>
}
14 changes: 11 additions & 3 deletions core/src/types/thread/threadInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ export interface ThreadInterface {
* @abstract
* @returns {Promise<Thread[]>} A promise that resolves to an array of threads.
*/
getThreads(): Promise<Thread[]>
listThreads(): Promise<Thread[]>

/**
* Saves a thread.
* Create a thread.
* @abstract
* @param {Thread} thread - The thread to save.
* @returns {Promise<void>} A promise that resolves when the thread is saved.
*/
saveThread(thread: Thread): Promise<void>
createThread(thread: Thread): Promise<Thread>

/**
* modify a thread.
* @abstract
* @param {Thread} thread - The thread to save.
* @returns {Promise<void>} A promise that resolves when the thread is saved.
*/
modifyThread(thread: Thread): Promise<void>

/**
* Deletes a thread.
Expand Down
3 changes: 1 addition & 2 deletions electron/tests/config/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,5 @@ test.beforeAll(async () => {
})

test.afterAll(async () => {
// temporally disabling this due to the config for parallel testing WIP
// teardownElectron()
teardownElectron()
})
2 changes: 1 addition & 1 deletion extensions/assistant-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default class JanAssistantExtension extends AssistantExtension {
top_k: 2,
chunk_size: 1024,
chunk_overlap: 64,
retrieval_template: `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
retrieval_template: `Use the following pieces of context to answer the question at the end.
----------------
CONTEXT: {CONTEXT}
----------------
Expand Down
5 changes: 3 additions & 2 deletions extensions/assistant-extension/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ export function toolRetrievalUpdateTextSplitter(
retrieval.updateTextSplitter(chunkSize, chunkOverlap)
}
export async function toolRetrievalIngestNewDocument(
thread: string,
file: string,
model: string,
engine: string,
useTimeWeighted: boolean
) {
const filePath = path.join(getJanDataFolderPath(), normalizeFilePath(file))
const threadPath = path.dirname(filePath.replace('files', ''))
const threadPath = path.join(getJanDataFolderPath(), 'threads', thread)
const filePath = path.join(getJanDataFolderPath(), 'files', file)
retrieval.updateEmbeddingEngine(model, engine)
return retrieval
.ingestAgentKnowledge(filePath, `${threadPath}/memory`, useTimeWeighted)
Expand Down
1 change: 1 addition & 0 deletions extensions/assistant-extension/src/tools/retrieval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class RetrievalTool extends InferenceTool {
await executeOnMain(
NODE,
'toolRetrievalIngestNewDocument',
data.thread?.id,
docFile,
data.model?.id,
data.model?.engine,
Expand Down
8 changes: 5 additions & 3 deletions extensions/conversational-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
"devDependencies": {
"cpx": "^1.5.0",
"rimraf": "^3.0.2",
"ts-loader": "^9.5.0",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"ts-loader": "^9.5.0"
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@janhq/core": "file:../../core"
"@janhq/core": "file:../../core",
"ky": "^1.7.2",
"p-queue": "^8.0.1"
},
"engines": {
"node": ">=18.0.0"
Expand Down
14 changes: 14 additions & 0 deletions extensions/conversational-extension/src/@types/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export {}
declare global {
declare const API_URL: string
declare const SOCKET_URL: string

interface Core {
api: APIFunctions
events: EventEmitter
}
interface Window {
core?: Core | undefined
electronAPI?: any | undefined
}
}
Loading
Loading