From ecec138cb679dd7399dbcebe41471ec578c879c0 Mon Sep 17 00:00:00 2001 From: "Huu Le (Lee)" <39040748+leehuwuj@users.noreply.github.com> Date: Sat, 3 Feb 2024 01:04:58 +0700 Subject: [PATCH] feat: Add create-llama option to RagCLI (#10405) --- docs/use_cases/q_and_a/rag_cli.md | 32 ++++++++++++- llama_index/command_line/rag.py | 74 +++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/docs/use_cases/q_and_a/rag_cli.md b/docs/use_cases/q_and_a/rag_cli.md index 3d17e7676..9a0a0e840 100644 --- a/docs/use_cases/q_and_a/rag_cli.md +++ b/docs/use_cases/q_and_a/rag_cli.md @@ -22,7 +22,7 @@ After that, you can start using the tool: ```shell $ llamaindex-cli rag -h -usage: llamaindex-cli rag [-h] [-q QUESTION] [-f FILES] [-c] [-v] [--clear] +usage: llamaindex-cli rag [-h] [-q QUESTION] [-f FILES] [-c] [-v] [--clear] [--create-llama] options: -h, --help show this help message and exit @@ -33,6 +33,7 @@ options: -c, --chat If flag is present, opens a chat REPL. -v, --verbose Whether to print out verbose information during execution. --clear Clears out all currently embedded data. + --create-llama Create a LlamaIndex application based on the selected files. ``` ## Usage @@ -58,6 +59,35 @@ Here are some high level steps to get you started: ``` 1. **Open a Chat REPL**: You can even open a chat interface within your terminal! Just run `$ llamaindex-cli rag --chat` and start asking questions about the files you've ingested. +### Create a LlamaIndex chat application + +You can also create a full-stack chat application with a FastAPI backend and NextJS frontend based on the files that you have selected. + +To bootstrap the application, make sure you have NodeJS and npx installed on your machine. If not, please refer to the [LlamaIndex.TS](https://ts.llamaindex.ai/getting_started/installation) documentation for instructions. + +Once you have everything set up, creating a new application is easy. Simply run the following command: + +`$ llamaindex-cli rag --create-llama` + +It will call our `create-llama` tool, so you will need to provide several pieces of information to create the app. You can find more information about the `create-llama` on [npmjs - create-llama](https://www.npmjs.com/package/create-llama#example) + +```shell +⯠llamaindex-cli rag --create-llama + +Calling create-llama using data from /tmp/rag-data/... + +✔ What is your project named? … my-app +✔ Which model would you like to use? › gpt-3.5-turbo +✔ Please provide your OpenAI API key (leave blank to skip): … +? How would you like to proceed? › - Use arrow-keys. Return to submit. + Just generate code (~1 sec) + Generate code and install dependencies (~2 min) +⯠Generate code, install dependencies, and run the app (~2 min) +... +``` + +If you choose the option `Generate code, install dependencies, and run the app (~2 min)`, all dependencies will be installed and the app will run automatically. You can then access the application by going to this address: http://localhost:3000. + ### Supported File Types Internally, the `rag` CLI tool uses the [SimpleDirectoryReader](/api/llama_index.readers.SimpleDirectoryReader.rst) to parse the raw files in your local filesystem into strings. diff --git a/llama_index/command_line/rag.py b/llama_index/command_line/rag.py index f57c880d0..0ea3b26f4 100644 --- a/llama_index/command_line/rag.py +++ b/llama_index/command_line/rag.py @@ -1,5 +1,6 @@ import asyncio import os +import shutil from argparse import ArgumentParser from glob import iglob from pathlib import Path @@ -24,6 +25,8 @@ from llama_index.readers.base import BaseReader from llama_index.response_synthesizers import CompactAndRefine from llama_index.utils import get_cache_dir +RAG_HISTORY_FILE_NAME = "files_history.txt" + def default_ragcli_persist_dir() -> str: return str(Path(get_cache_dir()) / "rag_cli") @@ -164,6 +167,7 @@ class RagCLI(BaseModel): chat: bool = False, verbose: bool = False, clear: bool = False, + create_llama: bool = False, **kwargs: Dict[str, Any], ) -> None: """ @@ -208,6 +212,70 @@ class RagCLI(BaseModel): await ingestion_pipeline.arun(show_progress=verbose, documents=documents) ingestion_pipeline.persist(persist_dir=self.persist_dir) + # Append the `--files` argument to the history file + with open(f"{self.persist_dir}/{RAG_HISTORY_FILE_NAME}", "a") as f: + f.write(files + "\n") + + if create_llama: + if shutil.which("npx") is None: + print( + "`npx` is not installed. Please install it by calling `npm install -g npx`" + ) + else: + history_file_path = Path(f"{self.persist_dir}/{RAG_HISTORY_FILE_NAME}") + if not history_file_path.exists(): + print( + "No data has been ingested, " + "please specify `--files` to create llama dataset." + ) + else: + with open(history_file_path) as f: + stored_paths = {line.strip() for line in f if line.strip()} + if len(stored_paths) == 0: + print( + "No data has been ingested, " + "please specify `--files` to create llama dataset." + ) + elif len(stored_paths) > 1: + print( + "Multiple files or folders were ingested, which is not supported by create-llama. " + "Please call `llamaindex-cli rag --clear` to clear the cache first, " + "then call `llamaindex-cli rag --files` again with a single folder or file" + ) + else: + path = stored_paths.pop() + if "*" in path: + print( + "Glob pattern is not supported by create-llama. " + "Please call `llamaindex-cli rag --clear` to clear the cache first, " + "then call `llamaindex-cli rag --files` again with a single folder or file." + ) + elif not os.path.exists(path): + print( + f"The path {path} does not exist. " + "Please call `llamaindex-cli rag --clear` to clear the cache first, " + "then call `llamaindex-cli rag --files` again with a single folder or file." + ) + else: + print(f"Calling create-llama using data from {path} ...") + command_args = [ + "npx", + "create-llama@latest", + "--frontend", + "--template", + "streaming", + "--framework", + "fastapi", + "--ui", + "shadcn", + "--vector-db", + "none", + "--engine", + "context", + f"--files {path}", + ] + os.system(" ".join(command_args)) + if question is not None: await self.handle_question(question) if chat: @@ -276,6 +344,12 @@ class RagCLI(BaseModel): help="Clears out all currently embedded data.", action="store_true", ) + parser.add_argument( + "--create-llama", + help="Create a LlamaIndex application with your embedded data.", + required=False, + action="store_true", + ) parser.set_defaults( func=lambda args: asyncio.run(instance_generator().handle_cli(**vars(args))) ) -- GitLab