diff --git a/core/src/types/api/index.ts b/core/src/types/api/index.ts index a663f2674..2f33b72e4 100644 --- a/core/src/types/api/index.ts +++ b/core/src/types/api/index.ts @@ -33,6 +33,8 @@ export enum NativeRoute { stopServer = 'stopServer', appUpdateDownload = 'appUpdateDownload', + + appToken = 'appToken', } /** diff --git a/electron/handlers/native.ts b/electron/handlers/native.ts index 7afeed285..f8f70c302 100644 --- a/electron/handlers/native.ts +++ b/electron/handlers/native.ts @@ -317,4 +317,11 @@ export function handleAppIPCs() { const { stopServer } = require('@janhq/server') return stopServer() }) + + /** + * Handles the "appToken" IPC message to generate a random app ID. + */ + ipcMain.handle(NativeRoute.appToken, async (_event): Promise => { + return process.env.appToken ?? 'cortex.cpp' + }) } diff --git a/electron/main.ts b/electron/main.ts index 19192bd99..59e72ca24 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -29,6 +29,7 @@ import { trayManager } from './managers/tray' import { logSystemInfo } from './utils/system' import { registerGlobalShortcuts } from './utils/shortcut' import { registerLogger } from './utils/logger' +import { randomBytes } from 'crypto' const preloadPath = join(__dirname, 'preload.js') const preloadQuickAskPath = join(__dirname, 'preload.quickask.js') @@ -56,6 +57,10 @@ const createMainWindow = () => { windowManager.createMainWindow(preloadPath, startUrl) } +// Generate a random token for the app +// This token is used for authentication when making request to cortex.cpp server +process.env.appToken = randomBytes(16).toString('hex') + app .whenReady() .then(() => { diff --git a/extensions/assistant-extension/rolldown.config.mjs b/extensions/assistant-extension/rolldown.config.mjs index b38e07ffb..e549ea7d9 100644 --- a/extensions/assistant-extension/rolldown.config.mjs +++ b/extensions/assistant-extension/rolldown.config.mjs @@ -28,7 +28,6 @@ export default defineConfig([ }, define: { CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), }, platform: 'node', }, diff --git a/extensions/assistant-extension/src/@types/global.d.ts b/extensions/assistant-extension/src/@types/global.d.ts index 697fee034..b724db8d0 100644 --- a/extensions/assistant-extension/src/@types/global.d.ts +++ b/extensions/assistant-extension/src/@types/global.d.ts @@ -1,4 +1,3 @@ declare const NODE: string declare const VERSION: string declare const CORTEX_API_URL: string -declare const CORTEX_API_KEY: string diff --git a/extensions/assistant-extension/src/node/retrieval.ts b/extensions/assistant-extension/src/node/retrieval.ts index 6e2951b00..05fa67d54 100644 --- a/extensions/assistant-extension/src/node/retrieval.ts +++ b/extensions/assistant-extension/src/node/retrieval.ts @@ -23,11 +23,16 @@ export class Retrieval { constructor(chunkSize: number = 4000, chunkOverlap: number = 200) { this.updateTextSplitter(chunkSize, chunkOverlap) + this.initialize() + } + + private async initialize() { + const apiKey = await window.core?.api.appToken() ?? 'cortex.cpp' // declare time-weighted retriever and storage this.timeWeightedVectorStore = new MemoryVectorStore( new OpenAIEmbeddings( - { openAIApiKey: CORTEX_API_KEY }, + { openAIApiKey: apiKey }, { basePath: `${CORTEX_API_URL}/v1` } ) ) @@ -47,9 +52,10 @@ export class Retrieval { }) } - public updateEmbeddingEngine(model: string, engine: string): void { + public async updateEmbeddingEngine(model: string, engine: string) { + const apiKey = await window.core?.api.appToken() ?? 'cortex.cpp' this.embeddingModel = new OpenAIEmbeddings( - { openAIApiKey: CORTEX_API_KEY, model }, + { openAIApiKey: apiKey, model }, // TODO: Raw settings { basePath: `${CORTEX_API_URL}/v1` } ) diff --git a/extensions/conversational-extension/rolldown.config.mjs b/extensions/conversational-extension/rolldown.config.mjs index b2b97e7e4..6d396f611 100644 --- a/extensions/conversational-extension/rolldown.config.mjs +++ b/extensions/conversational-extension/rolldown.config.mjs @@ -9,6 +9,5 @@ export default defineConfig({ platform: 'browser', define: { API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), }, }) diff --git a/extensions/conversational-extension/src/@types/global.d.ts b/extensions/conversational-extension/src/@types/global.d.ts index f4d5e3eb7..abe60d318 100644 --- a/extensions/conversational-extension/src/@types/global.d.ts +++ b/extensions/conversational-extension/src/@types/global.d.ts @@ -1,5 +1,4 @@ declare const API_URL: string -declare const CORTEX_API_KEY: string interface Core { api: APIFunctions diff --git a/extensions/conversational-extension/src/index.ts b/extensions/conversational-extension/src/index.ts index de4e6b180..5a74c460a 100644 --- a/extensions/conversational-extension/src/index.ts +++ b/extensions/conversational-extension/src/index.ts @@ -4,7 +4,7 @@ import { ThreadAssistantInfo, ThreadMessage, } from '@janhq/core' -import ky from 'ky' +import ky, { KyInstance } from 'ky' import PQueue from 'p-queue' type ThreadList = { @@ -26,17 +26,18 @@ export default class CortexConversationalExtension extends ConversationalExtensi * Extended API instance for making requests to the Cortex API. * @returns */ - api = () => - ky.extend({ - prefixUrl: API_URL, - headers: { - Authorization: `Bearer ${CORTEX_API_KEY}`, - }, - }) + api: KyInstance /** * Called when the extension is loaded. */ async onLoad() { + const apiKey = await window.core?.api.appToken() ?? 'cortex.cpp' + this.api = ky.extend({ + prefixUrl: API_URL, + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }) this.queue.add(() => this.healthz()) } @@ -50,7 +51,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async listThreads(): Promise { return this.queue.add(() => - this.api() + this.api .get('v1/threads?limit=-1') .json() .then((e) => e.data) @@ -63,7 +64,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async createThread(thread: Thread): Promise { return this.queue.add(() => - this.api().post('v1/threads', { json: thread }).json() + this.api.post('v1/threads', { json: thread }).json() ) as Promise } @@ -74,7 +75,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi async modifyThread(thread: Thread): Promise { return this.queue .add(() => - this.api().patch(`v1/threads/${thread.id}`, { json: thread }) + this.api.patch(`v1/threads/${thread.id}`, { json: thread }) ) .then() } @@ -85,7 +86,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async deleteThread(threadId: string): Promise { return this.queue - .add(() => this.api().delete(`v1/threads/${threadId}`)) + .add(() => this.api.delete(`v1/threads/${threadId}`)) .then() } @@ -96,7 +97,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async createMessage(message: ThreadMessage): Promise { return this.queue.add(() => - this.api() + this.api .post(`v1/threads/${message.thread_id}/messages`, { json: message, }) @@ -111,7 +112,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async modifyMessage(message: ThreadMessage): Promise { return this.queue.add(() => - this.api() + this.api .patch( `v1/threads/${message.thread_id}/messages/${message.id}`, { @@ -131,7 +132,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi async deleteMessage(threadId: string, messageId: string): Promise { return this.queue .add(() => - this.api().delete(`v1/threads/${threadId}/messages/${messageId}`) + this.api.delete(`v1/threads/${threadId}/messages/${messageId}`) ) .then() } @@ -143,7 +144,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async listMessages(threadId: string): Promise { return this.queue.add(() => - this.api() + this.api .get(`v1/threads/${threadId}/messages?order=asc&limit=-1`) .json() .then((e) => e.data) @@ -158,7 +159,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi */ async getThreadAssistant(threadId: string): Promise { return this.queue.add(() => - this.api() + this.api .get(`v1/assistants/${threadId}?limit=-1`) .json() ) as Promise @@ -174,7 +175,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi assistant: ThreadAssistantInfo ): Promise { return this.queue.add(() => - this.api() + this.api .post(`v1/assistants/${threadId}`, { json: assistant }) .json() ) as Promise @@ -191,7 +192,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi assistant: ThreadAssistantInfo ): Promise { return this.queue.add(() => - this.api() + this.api .patch(`v1/assistants/${threadId}`, { json: assistant }) .json() ) as Promise @@ -202,7 +203,7 @@ export default class CortexConversationalExtension extends ConversationalExtensi * @returns */ async healthz(): Promise { - return this.api() + return this.api .get('healthz', { retry: { limit: 20, delay: () => 500, methods: ['get'] }, }) diff --git a/extensions/engine-management-extension/rolldown.config.mjs b/extensions/engine-management-extension/rolldown.config.mjs index a7e529215..02b84b363 100644 --- a/extensions/engine-management-extension/rolldown.config.mjs +++ b/extensions/engine-management-extension/rolldown.config.mjs @@ -28,7 +28,6 @@ export default defineConfig([ 'Authorization: Bearer {{api_key}}' ), VERSION: JSON.stringify(pkgJson.version ?? '0.0.0'), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), }, }, { diff --git a/extensions/engine-management-extension/src/@types/global.d.ts b/extensions/engine-management-extension/src/@types/global.d.ts index ef66c328e..0dbed3806 100644 --- a/extensions/engine-management-extension/src/@types/global.d.ts +++ b/extensions/engine-management-extension/src/@types/global.d.ts @@ -6,7 +6,6 @@ declare const DEFAULT_REQUEST_PAYLOAD_TRANSFORM: string declare const DEFAULT_RESPONSE_BODY_TRANSFORM: string declare const DEFAULT_REQUEST_HEADERS_TRANSFORM: string declare const VERSION: string -declare const CORTEX_API_KEY: string declare const DEFAULT_REMOTE_ENGINES: ({ id: string diff --git a/extensions/engine-management-extension/src/index.ts b/extensions/engine-management-extension/src/index.ts index b617673c8..c6137b4b5 100644 --- a/extensions/engine-management-extension/src/index.ts +++ b/extensions/engine-management-extension/src/index.ts @@ -15,7 +15,7 @@ import { ModelEvent, EngineEvent, } from '@janhq/core' -import ky, { HTTPError } from 'ky' +import ky, { HTTPError, KyInstance } from 'ky' import PQueue from 'p-queue' import { EngineError } from './error' import { getJanDataFolderPath } from '@janhq/core' @@ -35,17 +35,18 @@ export default class JanEngineManagementExtension extends EngineManagementExtens * Extended API instance for making requests to the Cortex API. * @returns */ - api = () => - ky.extend({ - prefixUrl: API_URL, - headers: { - Authorization: `Bearer ${CORTEX_API_KEY}`, - }, - }) + api: KyInstance /** * Called when the extension is loaded. */ async onLoad() { + const apiKey = (await window.core?.api.appToken()) ?? 'cortex.cpp' + this.api = ky.extend({ + prefixUrl: API_URL, + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }) // Symlink Engines Directory await executeOnMain(NODE, 'symlinkEngines') // Run Healthcheck @@ -70,7 +71,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async getEngines(): Promise { return this.queue.add(() => - this.api() + this.api .get('v1/engines') .json() .then((e) => e) @@ -81,7 +82,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens * @returns A Promise that resolves to an object of list engines. */ async getRemoteModels(name: string): Promise { - return this.api() + return this.api .get(`v1/models/remote/${name}`) .json() .catch(() => ({ @@ -95,7 +96,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async getInstalledEngines(name: InferenceEngine): Promise { return this.queue.add(() => - this.api() + this.api .get(`v1/engines/${name}`) .json() .then((e) => e) @@ -114,7 +115,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens platform?: string ) { return this.queue.add(() => - this.api() + this.api .get(`v1/engines/${name}/releases/${version}`) .json() .then((e) => @@ -130,7 +131,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async getLatestReleasedEngine(name: InferenceEngine, platform?: string) { return this.queue.add(() => - this.api() + this.api .get(`v1/engines/${name}/releases/latest`) .json() .then((e) => @@ -145,7 +146,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async installEngine(name: string, engineConfig: EngineConfig) { return this.queue.add(() => - this.api() + this.api .post(`v1/engines/${name}/install`, { json: engineConfig }) .then((e) => e) ) as Promise<{ messages: string }> @@ -178,7 +179,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens engineConfig.metadata.header_template = DEFAULT_REQUEST_HEADERS_TRANSFORM return this.queue.add(() => - this.api() + this.api .post('v1/engines', { json: engineConfig }) .then((e) => { if (persistModels && engineConfig.metadata?.get_models_url) { @@ -198,7 +199,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async uninstallEngine(name: InferenceEngine, engineConfig: EngineConfig) { return this.queue.add(() => - this.api() + this.api .delete(`v1/engines/${name}/install`, { json: engineConfig }) .then((e) => e) ) as Promise<{ messages: string }> @@ -211,7 +212,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens async addRemoteModel(model: Model) { return this.queue .add(() => - this.api() + this.api .post('v1/models/add', { json: { inference_params: { @@ -236,7 +237,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async getDefaultEngineVariant(name: InferenceEngine) { return this.queue.add(() => - this.api() + this.api .get(`v1/engines/${name}/default`) .json<{ messages: string }>() .then((e) => e) @@ -253,7 +254,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens engineConfig: EngineConfig ) { return this.queue.add(() => - this.api() + this.api .post(`v1/engines/${name}/default`, { json: engineConfig }) .then((e) => e) ) as Promise<{ messages: string }> @@ -264,7 +265,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens */ async updateEngine(name: InferenceEngine, engineConfig?: EngineConfig) { return this.queue.add(() => - this.api() + this.api .post(`v1/engines/${name}/update`, { json: engineConfig }) .then((e) => e) ) as Promise<{ messages: string }> @@ -275,7 +276,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens * @returns */ async healthz(): Promise { - return this.api() + return this.api .get('healthz', { retry: { limit: 20, delay: () => 500, methods: ['get'] }, }) diff --git a/extensions/hardware-management-extension/rolldown.config.mjs b/extensions/hardware-management-extension/rolldown.config.mjs index d5d8a60d9..1a9c34ba0 100644 --- a/extensions/hardware-management-extension/rolldown.config.mjs +++ b/extensions/hardware-management-extension/rolldown.config.mjs @@ -11,7 +11,6 @@ export default defineConfig([ define: { NODE: JSON.stringify(`${pkgJson.name}/${pkgJson.node}`), API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), }, }, ]) diff --git a/extensions/hardware-management-extension/src/@types/global.d.ts b/extensions/hardware-management-extension/src/@types/global.d.ts index 1ee055750..a412681e8 100644 --- a/extensions/hardware-management-extension/src/@types/global.d.ts +++ b/extensions/hardware-management-extension/src/@types/global.d.ts @@ -1,6 +1,5 @@ declare const API_URL: string declare const NODE: string -declare const CORTEX_API_KEY: string interface Core { api: APIFunctions diff --git a/extensions/hardware-management-extension/src/index.ts b/extensions/hardware-management-extension/src/index.ts index b81cef876..849b6206f 100644 --- a/extensions/hardware-management-extension/src/index.ts +++ b/extensions/hardware-management-extension/src/index.ts @@ -1,5 +1,5 @@ import { HardwareManagementExtension, HardwareInformation } from '@janhq/core' -import ky from 'ky' +import ky, { KyInstance } from 'ky' import PQueue from 'p-queue' /** @@ -13,17 +13,18 @@ export default class JSONHardwareManagementExtension extends HardwareManagementE * Extended API instance for making requests to the Cortex API. * @returns */ - api = () => - ky.extend({ - prefixUrl: API_URL, - headers: { - 'Authorization': `Bearer ${CORTEX_API_KEY}`, - }, - }); + api: KyInstance /** * Called when the extension is loaded. */ async onLoad() { + const apiKey = await window.core?.api.appToken() ?? 'cortex.cpp' + this.api = ky.extend({ + prefixUrl: API_URL, + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }) // Run Healthcheck this.queue.add(() => this.healthz()) } @@ -38,7 +39,7 @@ export default class JSONHardwareManagementExtension extends HardwareManagementE * @returns */ async healthz(): Promise { - return this.api() + return this.api .get('healthz', { retry: { limit: 20, delay: () => 500, methods: ['get'] }, }) @@ -50,7 +51,7 @@ export default class JSONHardwareManagementExtension extends HardwareManagementE */ async getHardware(): Promise { return this.queue.add(() => - this.api() + this.api .get('v1/hardware') .json() .then((e) => e) @@ -65,7 +66,7 @@ export default class JSONHardwareManagementExtension extends HardwareManagementE activated_gpus: number[] }> { return this.queue.add(() => - this.api().post('v1/hardware/activate', { json: data }).then((e) => e) + this.api.post('v1/hardware/activate', { json: data }).then((e) => e) ) as Promise<{ message: string activated_gpus: number[] diff --git a/extensions/inference-cortex-extension/rolldown.config.mjs b/extensions/inference-cortex-extension/rolldown.config.mjs index 0be60c9a7..ef4c56c7b 100644 --- a/extensions/inference-cortex-extension/rolldown.config.mjs +++ b/extensions/inference-cortex-extension/rolldown.config.mjs @@ -19,7 +19,6 @@ export default defineConfig([ CORTEX_SOCKET_URL: JSON.stringify( `ws://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}` ), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), CORTEX_ENGINE_VERSION: JSON.stringify('v0.1.55'), }, }, @@ -36,7 +35,6 @@ export default defineConfig([ extensions: ['.js', '.ts', '.json'], }, define: { - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), CORTEX_API_URL: JSON.stringify( `http://127.0.0.1:${process.env.CORTEX_API_PORT ?? '39291'}` ), diff --git a/extensions/inference-cortex-extension/src/@types/global.d.ts b/extensions/inference-cortex-extension/src/@types/global.d.ts index 2f942495f..52f97b9ab 100644 --- a/extensions/inference-cortex-extension/src/@types/global.d.ts +++ b/extensions/inference-cortex-extension/src/@types/global.d.ts @@ -3,4 +3,3 @@ declare const CORTEX_API_URL: string declare const CORTEX_SOCKET_URL: string declare const CORTEX_ENGINE_VERSION: string declare const SETTINGS: any -declare const CORTEX_API_KEY: string diff --git a/extensions/inference-cortex-extension/src/index.ts b/extensions/inference-cortex-extension/src/index.ts index 568ab6c96..595885264 100644 --- a/extensions/inference-cortex-extension/src/index.ts +++ b/extensions/inference-cortex-extension/src/index.ts @@ -17,7 +17,7 @@ import { ModelEvent, } from '@janhq/core' import PQueue from 'p-queue' -import ky from 'ky' +import ky, { KyInstance } from 'ky' /** * Event subscription types of Downloader @@ -75,33 +75,30 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { abortControllers = new Map() - /** - * Extended API instance for making requests to the Cortex API. - * @returns - */ - api = () => - ky.extend({ - prefixUrl: CORTEX_API_URL, - headers: { - Authorization: `Bearer ${CORTEX_API_KEY}`, - }, - }) + api!: KyInstance /** * Authorization headers for the API requests. * @returns */ headers(): Promise { - return Promise.resolve({ - Authorization: `Bearer ${CORTEX_API_KEY}`, - }) + return window.core?.api.appToken().then((token: string) => ({ + Authorization: `Bearer ${token}`, + })) } /** - * Subscribes to events emitted by the @janhq/core package. + * Called when the extension is loaded. */ async onLoad() { super.onLoad() + const apiKey = (await window.core?.api.appToken()) ?? 'cortex.cpp' + this.api = ky.extend({ + prefixUrl: CORTEX_API_URL, + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }) // Register Settings this.registerSettings(SETTINGS) @@ -175,7 +172,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { this.abortControllers.set(model.id, controller) return await this.queue.add(() => - this.api() + this.api .post('v1/models/start', { json: { ...extractModelLoadParams(model.settings), @@ -205,7 +202,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { } override async unloadModel(model: Model): Promise { - return this.api() + return this.api .post('v1/models/stop', { json: { model: model.id }, }) @@ -221,7 +218,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { * @returns */ private async healthz(): Promise { - return this.api() + return this.api .get('healthz', { retry: { limit: 20, @@ -237,7 +234,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine { * @returns */ private async clean(): Promise { - return this.api() + return this.api .delete('processmanager/destroy', { timeout: 2000, // maximum 2 seconds retry: { diff --git a/extensions/inference-cortex-extension/src/node/index.ts b/extensions/inference-cortex-extension/src/node/index.ts index b243b83c2..d82225745 100644 --- a/extensions/inference-cortex-extension/src/node/index.ts +++ b/extensions/inference-cortex-extension/src/node/index.ts @@ -46,7 +46,7 @@ function run(): Promise { dataFolderPath, 'config', '--api_keys', - CORTEX_API_KEY ?? 'cortexserver', + process.env.appToken ?? 'cortex.cpp', ], { env: { diff --git a/extensions/model-extension/rolldown.config.mjs b/extensions/model-extension/rolldown.config.mjs index 55aae387d..54ea654ff 100644 --- a/extensions/model-extension/rolldown.config.mjs +++ b/extensions/model-extension/rolldown.config.mjs @@ -13,6 +13,5 @@ export default defineConfig({ SETTINGS: JSON.stringify(settingJson), CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`), DEFAULT_MODEL_SOURCES: JSON.stringify(modelSources), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), }, }) diff --git a/extensions/model-extension/src/@types/global.d.ts b/extensions/model-extension/src/@types/global.d.ts index a623300e2..e4d269cdb 100644 --- a/extensions/model-extension/src/@types/global.d.ts +++ b/extensions/model-extension/src/@types/global.d.ts @@ -2,7 +2,6 @@ declare const NODE: string declare const CORTEX_API_URL: string declare const SETTINGS: SettingComponentProps[] declare const DEFAULT_MODEL_SOURCES: any -declare const CORTEX_API_KEY: string interface Core { api: APIFunctions diff --git a/extensions/model-extension/src/index.ts b/extensions/model-extension/src/index.ts index de543c150..aaa010738 100644 --- a/extensions/model-extension/src/index.ts +++ b/extensions/model-extension/src/index.ts @@ -13,7 +13,7 @@ import { import { scanModelsFolder } from './legacy/model-json' import { deleteModelFiles } from './legacy/delete' import PQueue from 'p-queue' -import ky from 'ky' +import ky, { KyInstance } from 'ky' /** * cortex.cpp setting keys @@ -37,19 +37,18 @@ export default class JanModelExtension extends ModelExtension { * Extended API instance for making requests to the Cortex API. * @returns */ - api = () => - ky.extend({ - prefixUrl: CORTEX_API_URL, - headers: { - Authorization: `Bearer ${CORTEX_API_KEY}`, - }, - }) - + api: KyInstance /** * Called when the extension is loaded. - * @override */ async onLoad() { + const apiKey = (await window.core?.api.appToken()) ?? 'cortex.cpp' + this.api = ky.extend({ + prefixUrl: CORTEX_API_URL, + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }) this.queue.add(() => this.healthz()) this.registerSettings(SETTINGS) @@ -95,7 +94,7 @@ export default class JanModelExtension extends ModelExtension { * Sending POST to /models/pull/{id} endpoint to pull the model */ return this.queue.add(() => - this.api() + this.api .post('v1/models/pull', { json: { model, id, name } }) .json() .catch(async (e) => { @@ -116,7 +115,7 @@ export default class JanModelExtension extends ModelExtension { * Sending DELETE to /models/pull/{id} endpoint to cancel a model pull */ return this.queue.add(() => - this.api() + this.api .delete('v1/models/pull', { json: { taskId: model } }) .json() .then() @@ -130,7 +129,7 @@ export default class JanModelExtension extends ModelExtension { */ async deleteModel(model: string): Promise { return this.queue - .add(() => this.api().delete(`v1/models/${model}`).json().then()) + .add(() => this.api.delete(`v1/models/${model}`).json().then()) .catch((e) => console.debug(e)) .finally(async () => { // Delete legacy model files @@ -232,7 +231,7 @@ export default class JanModelExtension extends ModelExtension { async updateModel(model: Partial): Promise { return this.queue .add(() => - this.api() + this.api .patch(`v1/models/${model.id}`, { json: { ...model } }) .json() .then() @@ -246,7 +245,7 @@ export default class JanModelExtension extends ModelExtension { */ async getModel(model: string): Promise { return this.queue.add(() => - this.api() + this.api .get(`v1/models/${model}`) .json() .then((e) => this.transformModel(e)) @@ -265,7 +264,7 @@ export default class JanModelExtension extends ModelExtension { option?: OptionType ): Promise { return this.queue.add(() => - this.api() + this.api .post('v1/models/import', { json: { model, modelPath, name, option }, }) @@ -282,7 +281,7 @@ export default class JanModelExtension extends ModelExtension { */ async getSources(): Promise { const sources = await this.queue - .add(() => this.api().get('v1/models/sources').json>()) + .add(() => this.api.get('v1/models/sources').json>()) .then((e) => (typeof e === 'object' ? (e.data as ModelSource[]) : [])) .catch(() => []) return sources.concat( @@ -296,7 +295,7 @@ export default class JanModelExtension extends ModelExtension { */ async addSource(source: string): Promise { return this.queue.add(() => - this.api().post('v1/models/sources', { + this.api.post('v1/models/sources', { json: { source, }, @@ -310,7 +309,7 @@ export default class JanModelExtension extends ModelExtension { */ async deleteSource(source: string): Promise { return this.queue.add(() => - this.api().delete('v1/models/sources', { + this.api.delete('v1/models/sources', { json: { source, }, @@ -325,7 +324,7 @@ export default class JanModelExtension extends ModelExtension { */ async isModelLoaded(model: string): Promise { return this.queue - .add(() => this.api().get(`v1/models/status/${model}`)) + .add(() => this.api.get(`v1/models/status/${model}`)) .then((e) => true) .catch(() => false) } @@ -344,7 +343,7 @@ export default class JanModelExtension extends ModelExtension { */ async fetchModels(): Promise { return this.queue - .add(() => this.api().get('v1/models?limit=-1').json>()) + .add(() => this.api.get('v1/models?limit=-1').json>()) .then((e) => typeof e === 'object' ? e.data.map((e) => this.transformModel(e)) : [] ) @@ -384,7 +383,7 @@ export default class JanModelExtension extends ModelExtension { }): Promise { return this.queue .add(() => - this.api() + this.api .patch('v1/configs', { json: body }) .then(() => {}) ) @@ -396,7 +395,7 @@ export default class JanModelExtension extends ModelExtension { * @returns */ private healthz(): Promise { - return this.api() + return this.api .get('healthz', { retry: { limit: 20, @@ -416,7 +415,7 @@ export default class JanModelExtension extends ModelExtension { const models = await this.fetchModels() return this.queue.add(() => - this.api() + this.api .get('v1/models/hub?author=cortexso&tag=cortex.cpp') .json>() .then((e) => { diff --git a/server/global.d.ts b/server/global.d.ts index 3b58bab56..1fb95b9a0 100644 --- a/server/global.d.ts +++ b/server/global.d.ts @@ -1,2 +1 @@ -declare const CORTEX_API_URL: string -declare const CORTEX_API_KEY: string \ No newline at end of file +declare const CORTEX_API_URL: string \ No newline at end of file diff --git a/server/index.ts b/server/index.ts index 4c14eb4c1..4ea927199 100644 --- a/server/index.ts +++ b/server/index.ts @@ -90,7 +90,7 @@ export const startServer = async (configs?: ServerConfig): Promise => { if (req.url.includes('/configs')) return headers return { ...headers, - authorization: `Bearer ${CORTEX_API_KEY}`, // Add or modify Authorization header + authorization: `Bearer ${process.env.appToken}`, // Add or modify Authorization header } } diff --git a/server/rolldown.config.mjs b/server/rolldown.config.mjs index cfb6c714f..5f094a1af 100644 --- a/server/rolldown.config.mjs +++ b/server/rolldown.config.mjs @@ -16,7 +16,6 @@ export default defineConfig([ platform: 'node', define: { CORTEX_API_URL: JSON.stringify(`http://127.0.0.1:${process.env.CORTEX_API_PORT ?? "39291"}`), - CORTEX_API_KEY: JSON.stringify(process.env.CORTEX_API_KEY ?? 'cortexserver'), } }, ]) diff --git a/web/hooks/useGetLatestRelease.ts b/web/hooks/useGetLatestRelease.ts index 97304f74c..58de2ddb8 100644 --- a/web/hooks/useGetLatestRelease.ts +++ b/web/hooks/useGetLatestRelease.ts @@ -3,7 +3,7 @@ import useSWR from 'swr' const fetchLatestRelease = async (includeBeta: boolean) => { const res = await fetch( - 'https://api.github.com/menloresearch/janhq/jan/releases' + 'https://api.github.com/repos/menloresearch/jan/releases' ) if (!res.ok) throw new Error('Failed to fetch releases')