Merge branch 'master' of github.com:debanjum/khoj into features/simplify-configuration-steps

This commit is contained in:
sabaimran 2023-07-02 16:21:54 -07:00
commit a8b83da872
8 changed files with 151 additions and 123 deletions

View file

@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Khoj Name=Khoj
Comment=A natural language search engine for your personal notes, transactions and images. Comment=An AI personal assistant for your Digital Brain
Path=/opt Path=/opt
Exec=/opt/Khoj Exec=/opt/Khoj
Icon=Khoj Icon=Khoj

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "khoj-assistant" name = "khoj-assistant"
description = "A natural language search engine for your personal notes, transactions and images" description = "An AI personal assistant for your Digital Brain"
readme = "README.md" readme = "README.md"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
requires-python = ">=3.8" requires-python = ">=3.8"

View file

@ -1,6 +1,6 @@
<img src="/src/khoj/interface/web/assets/icons/khoj-logo-sideways.svg" width="200" alt="Khoj Logo">Obsidian <img src="/src/khoj/interface/web/assets/icons/khoj-logo-sideways.svg" width="200" alt="Khoj Logo">Obsidian
> Natural language search for your Obsidian notes using [Khoj](https://github.com/khoj-ai/khoj) > An AI personal assistant for your Digital Brain in Obsidian
## Table of Contents ## Table of Contents

View file

@ -161,7 +161,7 @@ export class KhojSearchModal extends SuggestModal<SearchResult> {
// Open vault file at heading of chosen search result // Open vault file at heading of chosen search result
if (file_match) { if (file_match) {
let resultHeading = file_match.extension !== 'pdf' ? result.entry.split('\n', 1)[0] : ''; let resultHeading = file_match.extension !== 'pdf' ? result.entry.split('\n', 1)[0] : '';
let linkToEntry = `${file_match.path}${resultHeading}` let linkToEntry = resultHeading.startsWith('#') ? `${file_match.path}${resultHeading}` : file_match.path;
this.app.workspace.openLinkText(linkToEntry, ''); this.app.workspace.openLinkText(linkToEntry, '');
console.log(`Link: ${linkToEntry}, File: ${file_match.path}, Heading: ${resultHeading}`); console.log(`Link: ${linkToEntry}, File: ${file_match.path}, Heading: ${resultHeading}`);
} }

View file

@ -72,7 +72,10 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n
} }
} }
// Else if khoj is not configured to index markdown files in configured obsidian vault // Else if khoj is not configured to index markdown files in configured obsidian vault
else if (data["content-type"]["markdown"]["input-filter"].length != 1 || else if (
data["content-type"]["markdown"]["input-files"] != null ||
data["content-type"]["markdown"]["input-filter"] == null ||
data["content-type"]["markdown"]["input-filter"].length != 1 ||
data["content-type"]["markdown"]["input-filter"][0] !== mdInVault) { data["content-type"]["markdown"]["input-filter"][0] !== mdInVault) {
// Update markdown config in khoj content-type config // Update markdown config in khoj content-type config
// Set markdown config to only index markdown files in configured obsidian vault // Set markdown config to only index markdown files in configured obsidian vault
@ -86,19 +89,30 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n
} }
if (khoj_already_configured && !data["content-type"]["pdf"]) { if (khoj_already_configured && !data["content-type"]["pdf"]) {
// Add pdf config to khoj content-type config const hasPdfFiles = app.vault.getFiles().some(file => file.extension === 'pdf');
// Set pdf config to index pdf files in configured obsidian vault
if (hasPdfFiles) {
data["content-type"]["pdf"] = { data["content-type"]["pdf"] = {
"input-filter": [pdfInVault], "input-filter": [pdfInVault],
"input-files": null, "input-files": null,
"embeddings-file": `${khojDefaultPdfIndexDirectory}/${indexName}.pt`, "embeddings-file": `${khojDefaultPdfIndexDirectory}/${indexName}.pt`,
"compressed-jsonl": `${khojDefaultPdfIndexDirectory}/${indexName}.jsonl.gz`, "compressed-jsonl": `${khojDefaultPdfIndexDirectory}/${indexName}.jsonl.gz`,
} }
} else {
data["content-type"]["pdf"] = null;
}
} }
// Else if khoj is not configured to index pdf files in configured obsidian vault // Else if khoj is not configured to index pdf files in configured obsidian vault
else if (khoj_already_configured && else if (khoj_already_configured &&
(data["content-type"]["pdf"]["input-filter"].length != 1 || (
data["content-type"]["pdf"]["input-files"] != null ||
data["content-type"]["pdf"]["input-filter"] == null ||
data["content-type"]["pdf"]["input-filter"].length != 1 ||
data["content-type"]["pdf"]["input-filter"][0] !== pdfInVault)) { data["content-type"]["pdf"]["input-filter"][0] !== pdfInVault)) {
let hasPdfFiles = app.vault.getFiles().some(file => file.extension === 'pdf');
if (hasPdfFiles) {
// Update pdf config in khoj content-type config // Update pdf config in khoj content-type config
// Set pdf config to only index pdf files in configured obsidian vault // Set pdf config to only index pdf files in configured obsidian vault
let khojPdfIndexDirectory = getIndexDirectoryFromBackendConfig(data["content-type"]["pdf"]["embeddings-file"]); let khojPdfIndexDirectory = getIndexDirectoryFromBackendConfig(data["content-type"]["pdf"]["embeddings-file"]);
@ -108,6 +122,9 @@ export async function configureKhojBackend(vault: Vault, setting: KhojSetting, n
"embeddings-file": `${khojPdfIndexDirectory}/${indexName}.pt`, "embeddings-file": `${khojPdfIndexDirectory}/${indexName}.pt`,
"compressed-jsonl": `${khojPdfIndexDirectory}/${indexName}.jsonl.gz`, "compressed-jsonl": `${khojPdfIndexDirectory}/${indexName}.jsonl.gz`,
} }
} else {
data["content-type"]["pdf"] = null;
}
} }
// If OpenAI API key not set in Khoj plugin settings // If OpenAI API key not set in Khoj plugin settings

View file

@ -93,6 +93,7 @@ def configure_search(model: SearchModels, config: FullConfig, regenerate: bool,
logger.warning("🚨 No Content or Search type is configured.") logger.warning("🚨 No Content or Search type is configured.")
return return
try:
# Initialize Org Notes Search # Initialize Org Notes Search
if (t == state.SearchType.Org or t == None) and config.content_type.org and config.search_type.asymmetric: if (t == state.SearchType.Org or t == None) and config.content_type.org and config.search_type.asymmetric:
logger.info("🦄 Setting up search for orgmode notes") logger.info("🦄 Setting up search for orgmode notes")
@ -118,7 +119,11 @@ def configure_search(model: SearchModels, config: FullConfig, regenerate: bool,
) )
# Initialize Markdown Search # Initialize Markdown Search
if (t == state.SearchType.Markdown or t == None) and config.content_type.markdown and config.search_type.asymmetric: if (
(t == state.SearchType.Markdown or t == None)
and config.content_type.markdown
and config.search_type.asymmetric
):
logger.info("💎 Setting up search for markdown notes") logger.info("💎 Setting up search for markdown notes")
# Extract Entries, Generate Markdown Embeddings # Extract Entries, Generate Markdown Embeddings
model.markdown_search = text_search.setup( model.markdown_search = text_search.setup(
@ -184,6 +189,9 @@ def configure_search(model: SearchModels, config: FullConfig, regenerate: bool,
regenerate=regenerate, regenerate=regenerate,
filters=[DateFilter(), WordFilter(), FileFilter()], filters=[DateFilter(), WordFilter(), FileFilter()],
) )
except Exception as e:
logger.error("🚨 Failed to setup search")
raise e
# Invalidate Query Cache # Invalidate Query Cache
state.query_cache = LRU() state.query_cache = LRU()

View file

@ -384,7 +384,12 @@ def update(
): ):
try: try:
state.search_index_lock.acquire() state.search_index_lock.acquire()
try:
state.model = configure_search(state.model, state.config, regenerate=force or False, t=t) state.model = configure_search(state.model, state.config, regenerate=force or False, t=t)
except Exception as e:
logger.error(e)
raise HTTPException(status_code=500, detail=str(e))
finally:
state.search_index_lock.release() state.search_index_lock.release()
except ValueError as e: except ValueError as e:
logger.error(e) logger.error(e)

View file

@ -10,9 +10,7 @@ from khoj.utils.yaml import parse_config_from_file
def cli(args=None): def cli(args=None):
# Setup Argument Parser for the Commandline Interface # Setup Argument Parser for the Commandline Interface
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(description="Start Khoj; An AI personal assistant for your Digital Brain")
description="Start Khoj; A Natural Language Search Engine for your personal Notes, Transactions and Photos"
)
parser.add_argument( parser.add_argument(
"--config-file", "-c", default="~/.khoj/khoj.yml", type=pathlib.Path, help="YAML file to configure Khoj" "--config-file", "-c", default="~/.khoj/khoj.yml", type=pathlib.Path, help="YAML file to configure Khoj"
) )