Louis 5250061c11
feat: Jan Server, API and decoupled clients (#948)
* chore: expose fs apis

* chore: correct electron import path

* update download api

Signed-off-by: James <james@jan.ai>

* update chat_completion

Signed-off-by: James <james@jan.ai>

* fix electron import

Signed-off-by: James <james@jan.ai>

* feat: adding API support at 1337 (#991)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>

* feat: Add /chat/completion api and handler

* chore: add todo for modelList

* chore: read engine.json for openai chat_completion (#1030)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>

* refactor: move routes to shared node module

* refactor: exported modules from core with types (#1172)

* refactor: exported modules from core with types

* fix: fix file reading args

* refactor: fileManager handles

* fix: app issues with server refactoring

* refactor: shared server module (#1210)

* chore: resolve main

* chore: update makefile

---------

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
Co-authored-by: NamH <NamNh0122@gmail.com>
Co-authored-by: hiro <vuonghoainam.work@gmail.com>
2023-12-28 17:57:39 +07:00

104 lines
2.9 KiB
TypeScript

import { ExtensionType, fs, Assistant } from "@janhq/core";
import { AssistantExtension } from "@janhq/core";
import { join } from "path";
export default class JanAssistantExtension implements AssistantExtension {
private static readonly _homeDir = "file://assistants";
type(): ExtensionType {
return ExtensionType.Assistant;
}
async onLoad() {
// making the assistant directory
if (!(await fs.existsSync(JanAssistantExtension._homeDir)))
fs.mkdirSync(JanAssistantExtension._homeDir).then(() => {
this.createJanAssistant();
});
}
/**
* Called when the extension is unloaded.
*/
onUnload(): void {}
async createAssistant(assistant: Assistant): Promise<void> {
const assistantDir = join(JanAssistantExtension._homeDir, assistant.id);
if (!(await fs.existsSync(assistantDir))) await fs.mkdirSync(assistantDir);
// store the assistant metadata json
const assistantMetadataPath = join(assistantDir, "assistant.json");
try {
await fs.writeFileSync(
assistantMetadataPath,
JSON.stringify(assistant, null, 2)
);
} catch (err) {
console.error(err);
}
}
async getAssistants(): Promise<Assistant[]> {
// get all the assistant directories
// get all the assistant metadata json
const results: Assistant[] = [];
const allFileName: string[] = await fs.readdirSync(
JanAssistantExtension._homeDir
);
for (const fileName of allFileName) {
const filePath = join(JanAssistantExtension._homeDir, fileName);
if (filePath.includes(".DS_Store")) continue;
const jsonFiles: string[] = (await fs.readdirSync(filePath)).filter(
(file: string) => file === "assistant.json"
);
if (jsonFiles.length !== 1) {
// has more than one assistant file -> ignore
continue;
}
const content = await fs.readFileSync(
join(filePath, jsonFiles[0]),
"utf-8"
);
const assistant: Assistant =
typeof content === "object" ? content : JSON.parse(content);
results.push(assistant);
}
return results;
}
async deleteAssistant(assistant: Assistant): Promise<void> {
if (assistant.id === "jan") {
return Promise.reject("Cannot delete Jan Assistant");
}
// remove the directory
const assistantDir = join(JanAssistantExtension._homeDir, assistant.id);
await fs.rmdirSync(assistantDir);
return Promise.resolve();
}
private async createJanAssistant(): Promise<void> {
const janAssistant: Assistant = {
avatar: "",
thread_location: undefined,
id: "jan",
object: "assistant",
created_at: Date.now(),
name: "Jan",
description: "A default assistant that can use all downloaded models",
model: "*",
instructions: "",
tools: undefined,
file_ids: [],
metadata: undefined,
};
await this.createAssistant(janAssistant);
}
}