diff --git a/src/interface/obsidian/src/main.ts b/src/interface/obsidian/src/main.ts index 470e1e89..6d4af194 100644 --- a/src/interface/obsidian/src/main.ts +++ b/src/interface/obsidian/src/main.ts @@ -38,9 +38,9 @@ export default class Khoj extends Plugin { id: 'chat', name: 'Chat', checkCallback: (checking) => { - if (!checking && this.settings.connectedToBackend) + if (!checking && this.settings.connectedToBackend && !!this.settings.openaiApiKey) new KhojChatModal(this.app, this.settings).open(); - return this.settings.connectedToBackend; + return !!this.settings.openaiApiKey; } }); diff --git a/src/interface/obsidian/src/settings.ts b/src/interface/obsidian/src/settings.ts index d7f41ba7..2cdc79a5 100644 --- a/src/interface/obsidian/src/settings.ts +++ b/src/interface/obsidian/src/settings.ts @@ -2,6 +2,7 @@ import { App, Notice, PluginSettingTab, request, Setting } from 'obsidian'; import Khoj from 'src/main'; export interface KhojSetting { + openaiApiKey: string; resultsCount: number; khojUrl: string; connectedToBackend: boolean; @@ -13,6 +14,7 @@ export const DEFAULT_SETTINGS: KhojSetting = { khojUrl: 'http://localhost:8000', connectedToBackend: false, autoConfigure: true, + openaiApiKey: '', } export class KhojSettingTab extends PluginSettingTab { @@ -41,7 +43,16 @@ export class KhojSettingTab extends PluginSettingTab { await this.plugin.saveSettings(); containerEl.firstElementChild?.setText(this.getBackendStatusMessage()); })); - new Setting(containerEl) + new Setting(containerEl) + .setName('OpenAI API Key') + .setDesc('Your OpenAI API Key for Khoj Chat') + .addText(text => text + .setValue(`${this.plugin.settings.openaiApiKey}`) + .onChange(async (value) => { + this.plugin.settings.openaiApiKey = value.trim(); + await this.plugin.saveSettings(); + })); + new Setting(containerEl) .setName('Results Count') .setDesc('The number of search results to show') .addSlider(slider => slider @@ -110,7 +121,7 @@ export class KhojSettingTab extends PluginSettingTab { getBackendStatusMessage() { return !this.plugin.settings.connectedToBackend - ? '❗Disconnected from Khoj backend. Ensure Khoj backend is running and Khoj URL is correctly set below.' - : '✅ Connected to Khoj backend.'; + ? '❗Disconnected from Khoj backend. Ensure Khoj backend is running and Khoj URL is correctly set below.' + : '✅ Connected to Khoj backend.'; } } diff --git a/src/interface/obsidian/src/utils.ts b/src/interface/obsidian/src/utils.ts index 04e1919c..ba539179 100644 --- a/src/interface/obsidian/src/utils.ts +++ b/src/interface/obsidian/src/utils.ts @@ -29,10 +29,11 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n // Set index name from the path of the current vault let indexName = getVaultAbsolutePath(vault).replace(/\//g, '_').replace(/ /g, '_'); - // Get default index directory from khoj backend - let khojDefaultIndexDirectory = await request(`${khojConfigUrl}/default`) - .then(response => JSON.parse(response)) - .then(data => { return getIndexDirectoryFromBackendConfig(data); }); + // Get default config fields from khoj backend + let defaultConfig = await request(`${khojConfigUrl}/default`).then(response => JSON.parse(response)); + let khojDefaultIndexDirectory = getIndexDirectoryFromBackendConfig(defaultConfig["content-type"]["markdown"]["embeddings-file"]); + let khojDefaultChatDirectory = getIndexDirectoryFromBackendConfig(defaultConfig["processor"]["conversation"]["conversation-logfile"]); + let khojDefaultChatModelName = defaultConfig["processor"]["conversation"]["model"]; // Get current config if khoj backend configured, else get default config from khoj backend await request(khoj_already_configured ? khojConfigUrl : `${khojConfigUrl}/default`) @@ -49,14 +50,7 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n "compressed-jsonl": `${khojDefaultIndexDirectory}/${indexName}.jsonl.gz`, } } - // Disable khoj processors, as not required - delete data["processor"]; - - // Save new config and refresh index on khoj backend - updateKhojBackend(setting.khojUrl, data); - console.log(`Khoj: Created khoj backend config:\n${JSON.stringify(data)}`) } - // Else if khoj config has no markdown content config else if (!data["content-type"]["markdown"]) { // Add markdown config to khoj content-type config @@ -67,28 +61,59 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n "embeddings-file": `${khojDefaultIndexDirectory}/${indexName}.pt`, "compressed-jsonl": `${khojDefaultIndexDirectory}/${indexName}.jsonl.gz`, } - - // Save updated config and refresh index on khoj backend - updateKhojBackend(setting.khojUrl, data); - console.log(`Khoj: Added markdown config to khoj backend config:\n${JSON.stringify(data["content-type"])}`) } - // Else if khoj is not configured to index markdown files in configured obsidian vault else if (data["content-type"]["markdown"]["input-filter"].length != 1 || data["content-type"]["markdown"]["input-filter"][0] !== mdInVault) { // Update markdown config in khoj content-type config // Set markdown config to only index markdown files in configured obsidian vault - let khojIndexDirectory = getIndexDirectoryFromBackendConfig(data); + let khojIndexDirectory = getIndexDirectoryFromBackendConfig(data["content-type"]["markdown"]["embeddings-file"]); data["content-type"]["markdown"] = { "input-filter": [mdInVault], "input-files": null, "embeddings-file": `${khojIndexDirectory}/${indexName}.pt`, "compressed-jsonl": `${khojIndexDirectory}/${indexName}.jsonl.gz`, } - // Save updated config and refresh index on khoj backend - updateKhojBackend(setting.khojUrl, data); - console.log(`Khoj: Updated markdown config in khoj backend config:\n${JSON.stringify(data["content-type"]["markdown"])}`) } + + // If OpenAI API key not set in Khoj plugin settings + if (!setting.openaiApiKey) { + // Disable khoj processors, as not required + delete data["processor"]; + } + // Else if khoj backend not configured yet + else if (!khoj_already_configured || !data["processor"]) { + data["processor"] = { + "conversation": { + "conversation-logfile": `${khojDefaultChatDirectory}/conversation.json`, + "model": khojDefaultChatModelName, + "openai-api-key": setting.openaiApiKey, + } + } + } + // Else if khoj config has no conversation processor config + else if (!data["processor"]["conversation"]) { + data["processor"]["conversation"] = { + "conversation-logfile": `${khojDefaultChatDirectory}/conversation.json`, + "model": khojDefaultChatModelName, + "openai-api-key": setting.openaiApiKey, + } + } + // Else if khoj is not configured with OpenAI API key from khoj plugin settings + else if (data["processor"]["conversation"]["openai-api-key"] !== setting.openaiApiKey) { + data["processor"]["conversation"] = { + "conversation-logfile": data["processor"]["conversation"]["conversation-logfile"], + "model": data["procesor"]["conversation"]["model"], + "openai-api-key": setting.openaiApiKey, + } + } + + // Save updated config and refresh index on khoj backend + updateKhojBackend(setting.khojUrl, data); + if (!khoj_already_configured) + console.log(`Khoj: Created khoj backend config:\n${JSON.stringify(data)}`) + else + console.log(`Khoj: Updated khoj backend config:\n${JSON.stringify(data)}`) }) .catch(error => { if (notify) @@ -111,6 +136,6 @@ export async function updateKhojBackend(khojUrl: string, khojConfig: Object) { .then(_ => request(`${khojUrl}/api/update?t=markdown`)); } -function getIndexDirectoryFromBackendConfig(khojConfig: any) { - return khojConfig["content-type"]["markdown"]["embeddings-file"].split("/").slice(0, -1).join("/"); +function getIndexDirectoryFromBackendConfig(filepath: string) { + return filepath.split("/").slice(0, -1).join("/"); }