Skip to content

Commit

Permalink
fix: Update code based on comments from @james
Browse files Browse the repository at this point in the history
  • Loading branch information
hiro-v committed Dec 8, 2023
1 parent fbf8ff9 commit 1177007
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 151 deletions.
4 changes: 2 additions & 2 deletions core/src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const readFile: (path: string) => Promise<any> = (path) => global.core.api?.read
* @param {string} path
* @returns {boolean} A boolean indicating whether the path is a file.
*/
const checkFileExists = (path: string): Promise<boolean> => global.core.api?.checkFileExists(path)
const exists = (path: string): Promise<boolean> => global.core.api?.exists(path)
/**
* List the directory files
* @param {string} path - The path of the directory to list files.
Expand Down Expand Up @@ -75,7 +75,7 @@ export const fs = {
isDirectory,
writeFile,
readFile,
checkFileExists,
exists,
listFiles,
mkdir,
rmdir,
Expand Down
5 changes: 1 addition & 4 deletions core/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ export type MessageRequest = {
/** Messages for constructing a chat completion request **/
messages?: ChatCompletionMessage[];

/** Runtime parameters for constructing a chat completion request **/
parameters?: ModelRuntimeParams;

/** Settings for constructing a chat completion request **/
model?: ModelInfo
model?: ModelInfo;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion electron/handlers/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function handleFsIPCs() {
* @param path - The path of the file to check.
* @returns A promise that resolves with a boolean indicating whether the file exists.
*/
ipcMain.handle('checkFileExists', async (_event, path: string) => {
ipcMain.handle('exists', async (_event, path: string) => {
return new Promise((resolve, reject) => {
const fullPath = join(userSpacePath, path)
fs.existsSync(fullPath) ? resolve(true) : resolve(false)
Expand Down
2 changes: 1 addition & 1 deletion electron/invokers/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function fsInvokers() {
* Reads a file at the specified path.
* @param {string} path - The path of the file to read.
*/
checkFileExists: (path: string) => ipcRenderer.invoke('checkFileExists', path),
exists: (path: string) => ipcRenderer.invoke('exists', path),

/**
* Writes data to a file at the specified path.
Expand Down
15 changes: 7 additions & 8 deletions extensions/inference-nitro-extension/src/@types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ declare const INFERENCE_URL: string;
* @property settings.embedding - Whether to use embedding.
*/
interface EngineSettings {
ctx_len: number;
ngl: number;
cont_batching: boolean;
embedding: boolean;
ctx_len: number;
ngl: number;
cont_batching: boolean;
embedding: boolean;
}

/**
* The response from the initModel function.
* @property error - An error message if the model fails to load.
*/
interface ModelOperationResponse {
error?: any;
modelFile?: string;
}

error?: any;
modelFile?: string;
}
104 changes: 57 additions & 47 deletions extensions/inference-nitro-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ import { join } from "path";
* It also subscribes to events emitted by the @janhq/core package and handles new message requests.
*/
export default class JanInferenceNitroExtension implements InferenceExtension {
private static readonly _homeDir = 'engines'
private static readonly _engineMetadataFileName = 'nitro.json'
private static readonly _homeDir = "engines";
private static readonly _engineMetadataFileName = "nitro.json";

static _currentModel: Model;
private static _currentModel: Model;

static _engineSettings: EngineSettings = {
"ctx_len": 2048,
"ngl": 100,
"cont_batching": false,
"embedding": false
}
private static _engineSettings: EngineSettings = {
ctx_len: 2048,
ngl: 100,
cont_batching: false,
embedding: false,
};

controller = new AbortController();
isCancelled = false;
Expand All @@ -59,12 +59,12 @@ export default class JanInferenceNitroExtension implements InferenceExtension {
* Subscribes to events emitted by the @janhq/core package.
*/
onLoad(): void {
fs.mkdir(JanInferenceNitroExtension._homeDir)
this.writeDefaultEngineSettings()
fs.mkdir(JanInferenceNitroExtension._homeDir);
this.writeDefaultEngineSettings();

// Events subscription
events.on(EventName.OnMessageSent, (data) =>
JanInferenceNitroExtension.handleMessageRequest(data, this)
JanInferenceNitroExtension.handleMessageRequest(data, this)
);

events.on(EventName.OnModelInit, (model: Model) => {
Expand Down Expand Up @@ -112,42 +112,51 @@ export default class JanInferenceNitroExtension implements InferenceExtension {

private async writeDefaultEngineSettings() {
try {
const engine_json = join(JanInferenceNitroExtension._homeDir, JanInferenceNitroExtension._engineMetadataFileName)
if (await fs.checkFileExists(engine_json)) {
JanInferenceNitroExtension._engineSettings = JSON.parse(await fs.readFile(engine_json))
}
else {
await fs.writeFile(engine_json, JSON.stringify(JanInferenceNitroExtension._engineSettings, null, 2))
const engineFile = join(
JanInferenceNitroExtension._homeDir,
JanInferenceNitroExtension._engineMetadataFileName
);
if (await fs.exists(engineFile)) {
JanInferenceNitroExtension._engineSettings = JSON.parse(
await fs.readFile(engineFile)
);
} else {
await fs.writeFile(
engineFile,
JSON.stringify(JanInferenceNitroExtension._engineSettings, null, 2)
);
}
} catch (err) {
console.error(err)
console.error(err);
}
}

private static async handleModelInit(model: Model) {
if (model.engine !== "nitro") { return }
if (model.engine !== "nitro") {
return;
}
const userSpacePath = await getUserSpace();
const modelFullPath = join(userSpacePath, "models", model.id, model.id);

const nitro_init_result = await executeOnMain(MODULE, "initModel", {
const nitroInitResult = await executeOnMain(MODULE, "initModel", {
modelFullPath: modelFullPath,
model: model
model: model,
});

if (nitro_init_result.error === null) {
events.emit(EventName.OnModelFail, model)
}
else{
if (nitroInitResult.error === null) {
events.emit(EventName.OnModelFail, model);
} else {
JanInferenceNitroExtension._currentModel = model;
events.emit(EventName.OnModelReady, model);
}
}

private static async handleModelStop(model: Model) {
if (model.engine !== 'nitro') { return }
else {
await executeOnMain(MODULE, "stopModel")
events.emit(EventName.OnModelStopped, model)
if (model.engine !== "nitro") {
return;
} else {
await executeOnMain(MODULE, "stopModel");
events.emit(EventName.OnModelStopped, model);
}
}

Expand All @@ -171,18 +180,17 @@ export default class JanInferenceNitroExtension implements InferenceExtension {

return new Promise(async (resolve, reject) => {
requestInference(
data.messages ?? [],
JanInferenceNitroExtension._engineSettings,
JanInferenceNitroExtension._currentModel
)
.subscribe({
data.messages ?? [],
JanInferenceNitroExtension._engineSettings,
JanInferenceNitroExtension._currentModel
).subscribe({
next: (_content) => {},
complete: async () => {
resolve(message);
},
error: async (err) => {
reject(err);
},
complete: async () => {
resolve(message);
},
error: async (err) => {
reject(err);
},
});
});
}
Expand All @@ -197,7 +205,9 @@ export default class JanInferenceNitroExtension implements InferenceExtension {
data: MessageRequest,
instance: JanInferenceNitroExtension
) {
if (data.model.engine !== 'nitro') { return }
if (data.model.engine !== "nitro") {
return;
}
const timestamp = Date.now();
const message: ThreadMessage = {
id: ulid(),
Expand All @@ -216,11 +226,11 @@ export default class JanInferenceNitroExtension implements InferenceExtension {
instance.controller = new AbortController();

requestInference(
data.messages ?? [],
JanInferenceNitroExtension._engineSettings,
JanInferenceNitroExtension._currentModel,
instance.controller
).subscribe({
data.messages ?? [],
JanInferenceNitroExtension._engineSettings,
JanInferenceNitroExtension._currentModel,
instance.controller
).subscribe({
next: (content) => {
const messageContent: ThreadContent = {
type: ContentType.Text,
Expand Down
64 changes: 31 additions & 33 deletions extensions/inference-nitro-extension/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ let currentModelFile = null;
*/
function stopModel(): Promise<ModelOperationResponse> {
return new Promise((resolve, reject) => {
checkAndUnloadNitro()
resolve({ error: undefined})
})
checkAndUnloadNitro();
resolve({ error: undefined });
});
}

/**
Expand All @@ -39,33 +39,32 @@ function stopModel(): Promise<ModelOperationResponse> {
* TODO: Should it be startModel instead?
*/
function initModel(wrapper: any): Promise<ModelOperationResponse> {
currentModelFile = wrapper.modelFullPath;
if (wrapper.model.engine !== "nitro") {
return Promise.resolve({ error: "Not a nitro model" })
}
else {
log.info("Started to load model " + wrapper.model.modelFullPath);
const settings = {
llama_model_path: currentModelFile,
...wrapper.model.settings,
};
log.info(`Load model settings: ${JSON.stringify(settings, null, 2)}`);
return (
// 1. Check if the port is used, if used, attempt to unload model / kill nitro process
validateModelVersion()
.then(checkAndUnloadNitro)
// 2. Spawn the Nitro subprocess
.then(spawnNitroProcess)
// 4. Load the model into the Nitro subprocess (HTTP POST request)
.then(() => loadLLMModel(settings))
// 5. Check if the model is loaded successfully
.then(validateModelStatus)
.catch((err) => {
log.error("error: " + JSON.stringify(err));
return { error: err, currentModelFile };
})
);
}
currentModelFile = wrapper.modelFullPath;
if (wrapper.model.engine !== "nitro") {
return Promise.resolve({ error: "Not a nitro model" });
} else {
log.info("Started to load model " + wrapper.model.modelFullPath);
const settings = {
llama_model_path: currentModelFile,
...wrapper.model.settings,
};
log.info(`Load model settings: ${JSON.stringify(settings, null, 2)}`);
return (
// 1. Check if the port is used, if used, attempt to unload model / kill nitro process
validateModelVersion()
.then(checkAndUnloadNitro)
// 2. Spawn the Nitro subprocess
.then(spawnNitroProcess)
// 4. Load the model into the Nitro subprocess (HTTP POST request)
.then(() => loadLLMModel(settings))
// 5. Check if the model is loaded successfully
.then(validateModelStatus)
.catch((err) => {
log.error("error: " + JSON.stringify(err));
return { error: err, currentModelFile };
})
);
}
}

/**
Expand Down Expand Up @@ -148,13 +147,12 @@ async function checkAndUnloadNitro() {
// If inUse - try unload or kill process, otherwise do nothing
if (inUse) {
// Attempt to unload model
return await fetch(NITRO_HTTP_UNLOAD_MODEL_URL, {
return fetch(NITRO_HTTP_UNLOAD_MODEL_URL, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
.catch((err) => {
}).catch((err) => {
console.error(err);
// Fallback to kill the port
return killSubprocess();
Expand Down
32 changes: 16 additions & 16 deletions extensions/inference-openai-extension/src/@types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ import { Model } from "@janhq/core";
declare const MODULE: string;

declare interface EngineSettings {
base_url?: string;
api_key?: string;
base_url?: string;
api_key?: string;
}

enum OpenAIChatCompletionModelName {
'gpt-3.5-turbo-instruct' = 'gpt-3.5-turbo-instruct',
'gpt-3.5-turbo-instruct-0914' = 'gpt-3.5-turbo-instruct-0914',
'gpt-4-1106-preview' = 'gpt-4-1106-preview',
'gpt-3.5-turbo-0613' = 'gpt-3.5-turbo-0613',
'gpt-3.5-turbo-0301' = 'gpt-3.5-turbo-0301',
'gpt-3.5-turbo' = 'gpt-3.5-turbo',
'gpt-3.5-turbo-16k-0613' = 'gpt-3.5-turbo-16k-0613',
'gpt-3.5-turbo-1106' = 'gpt-3.5-turbo-1106',
'gpt-4-vision-preview' = 'gpt-4-vision-preview',
'gpt-4' = 'gpt-4',
'gpt-4-0314' = 'gpt-4-0314',
'gpt-4-0613' = 'gpt-4-0613',
"gpt-3.5-turbo-instruct" = "gpt-3.5-turbo-instruct",
"gpt-3.5-turbo-instruct-0914" = "gpt-3.5-turbo-instruct-0914",
"gpt-4-1106-preview" = "gpt-4-1106-preview",
"gpt-3.5-turbo-0613" = "gpt-3.5-turbo-0613",
"gpt-3.5-turbo-0301" = "gpt-3.5-turbo-0301",
"gpt-3.5-turbo" = "gpt-3.5-turbo",
"gpt-3.5-turbo-16k-0613" = "gpt-3.5-turbo-16k-0613",
"gpt-3.5-turbo-1106" = "gpt-3.5-turbo-1106",
"gpt-4-vision-preview" = "gpt-4-vision-preview",
"gpt-4" = "gpt-4",
"gpt-4-0314" = "gpt-4-0314",
"gpt-4-0613" = "gpt-4-0613",
}

declare type OpenAIModel = Omit<Model, "id"> & {
id: OpenAIChatCompletionModelName;
};
id: OpenAIChatCompletionModelName;
};
Loading

0 comments on commit 1177007

Please sign in to comment.