Compare commits

..

10 Commits

Author SHA1 Message Date
sweep-ai[bot] 26a4aaa4f9 Merge main into sweep/add-model-selection-cli 2023-11-15 04:55:23 +00:00
sweep-ai[bot] 91509720a0 Merge main into sweep/add-model-selection-cli 2023-11-15 04:49:36 +00:00
sweep-ai[bot] f54fb7f697 Merge main into sweep/add-model-selection-cli 2023-11-15 01:24:44 +00:00
sweep-ai[bot] 0266c3da9a feat: Updated packages/create-llama/CHANGELOG.md 2023-11-15 01:03:17 +00:00
sweep-ai[bot] 02c34ba96f feat: Updated packages/create-llama/package.json 2023-11-15 01:02:10 +00:00
sweep-ai[bot] e6a0c548e8 feat: Updated packages/create-llama/README.md 2023-11-15 00:57:14 +00:00
sweep-ai[bot] af12adba22 feat: Updated packages/create-llama/package.json 2023-11-15 00:55:09 +00:00
sweep-ai[bot] f8eecbe6d0 feat: Updated packages/create-llama/package.json 2023-11-15 00:50:45 +00:00
sweep-ai[bot] 962126b77f feat: Updated packages/create-llama/index.ts 2023-11-15 00:45:16 +00:00
sweep-ai[bot] 6c2fc21496 feat: Updated packages/create-llama/create-app.ts 2023-11-15 00:35:45 +00:00
22 changed files with 63 additions and 186 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
### Patch Changes
- 63f2108: Add multimodal support (thanks @marcusschiesser)
- 63f2108: Add multimodal support (thanks Marcus)
## 0.0.34
+22 -16
View File
@@ -1,22 +1,10 @@
# create-llama
## 0.0.8
### Patch Changes
- 8cdb07f: Fix Next deployment (thanks @seldo and @marcusschiesser)
## 0.0.7
### Patch Changes
- 9f9f293: Added more to README and made it easier to switch models (thanks @seldo)
## 0.0.6
### Patch Changes
- 4431ec7: Label bug fix (thanks @marcusschiesser)
- 4431ec7: Label bug fix
## 0.0.5
@@ -28,16 +16,34 @@
### Patch Changes
- 031e926: Update create-llama readme (thanks @logan-markewich)
- 031e926: Update create-llama readme (thanks Logan)
## 0.0.3
### Patch Changes
- 91b42a3: change version (thanks @marcusschiesser)
- 91b42a3: change version (thanks Marcus)
## 0.0.2
### Patch Changes
- e2a6805: Hello Create Llama (thanks @marcusschiesser)
- e2a6805: Hello Create Llama (thanks Marcus!)
## 0.0.6
### Patch Changes
- Add model selection prompt
## 0.0.3
### Patch Changes
- 91b42a3: change version (thanks Marcus)
## 0.0.2
### Patch Changes
- e2a6805: Hello Create Llama (thanks Marcus!)
+15 -60
View File
@@ -2,69 +2,19 @@
The easiest way to get started with [LlamaIndex](https://www.llamaindex.ai/) is by using `create-llama`. This CLI tool enables you to quickly start building a new LlamaIndex application, with everything set up for you.
Just run
## Features
```bash
npx create-llama@latest
```
- NextJS, ExpressJS, or FastAPI (python) stateless backend generation 💻
- Streaming or non-streaming backend ⚡
- Optional `shadcn` frontend generation 🎨
to get started, or see below for more options. Once your app is generated, run
## Get Started
```bash
npm run dev
```
You can run `create-llama` in interactive or non-interactive mode.
to start the development server. You can then visit [http://localhost:3000](http://localhost:3000) to see your app.
### Interactive
## What you'll get
- A Next.js-powered front-end. The app is set up as a chat interface that can answer questions about your data (see below)
- You can style it with HTML and CSS, or you can optionally use components from [shadcn/ui](https://ui.shadcn.com/)
- Your choice of 3 back-ends:
- **Next.js**: if you select this option, youll have a full stack Next.js application that you can deploy to a host like [Vercel](https://vercel.com/) in just a few clicks. This uses [LlamaIndex.TS](https://www.npmjs.com/package/llamaindex), our TypeScript library.
- **Express**: if you want a more traditional Node.js application you can generate an Express backend. This also uses LlamaIndex.TS.
- **Python FastAPI**: if you select this option youll get a backend powered by the [llama-index python package](https://pypi.org/project/llama-index/), which you can deploy to a service like Render or fly.io.
- The back-end has a single endpoint that allows you to send the state of your chat and receive additional responses
- You can choose whether you want a streaming or non-streaming back-end (if you're not sure, we recommend streaming)
- You can choose whether you want to use `ContextChatEngine` or `SimpleChatEngine`
- `SimpleChatEngine` will just talk to the LLM directly without using your data
- `ContextChatEngine` will use your data to answer questions (see below).
- The app uses OpenAI by default, so you'll need an OpenAI API key, or you can customize it to use any of the dozens of LLMs we support.
## Using your data
If you've enabled `ContextChatEngine`, you can supply your own data and the app will index it and answer questions. Your generated app will have a folder called `data`:
- With the Next.js backend this is `./data`
- With the Express or Python backend this is in `./backend/data`
The app will ingest any supported files you put in this directory. Your Next.js and Express apps use LlamaIndex.TS so they will be able to ingest any PDF, text, CSV, Markdown, Word and HTML files. The Python backend can read even more types, including video and audio files.
Before you can use your data, you need to index it. If you're using the Next.js or Express apps, run:
```bash
npm run generate
```
Then re-start your app. Remember you'll need to re-run `generate` if you add new files to your `data` folder. If you're using the Python backend, you can trigger indexing of your data by deleting the `./storage` folder and re-starting the app.
## Don't want a front-end?
It's optional! If you've selected the Python or Express back-ends, just delete the `frontend` folder and you'll get an API without any front-end code.
## Customizing the LLM
By default the app will use OpenAI's gpt-3.5-turbo model. If you want to use GPT-4, you can modify this by editing a file:
- In the Next.js backend, edit `./app/api/chat/route.ts` and replace `gpt-3.5-turbo` with `gpt-4`
- In the Express backend, edit `./backend/src/controllers/chat.controller.ts` and likewise replace `gpt-3.5-turbo` with `gpt-4`
- In the Python backend, edit `./backend/app/utils/index.py` and once again replace `gpt-3.5-turbo` with `gpt-4`
You can also replace OpenAI with one of our [dozens of other supported LLMs](https://docs.llamaindex.ai/en/stable/module_guides/models/llms/modules.html).
## Example
The simplest thing to do is run `create-llama` in interactive mode:
You can create a new project interactively by running:
```bash
npx create-llama@latest
@@ -76,7 +26,12 @@ yarn create llama
pnpm create llama@latest
```
You will be asked for the name of your project, along with other configuration options, something like this:
You will be asked for the name of your project, along with other configuration options.
Here is an example:
You will be asked for the name of your project, along with other configuration options, including the model selection.
Here is an example:
```bash
>> npm create llama@latest
@@ -93,7 +48,7 @@ Ok to proceed? (y) y
Creating a new LlamaIndex app in /home/my-app.
```
### Running non-interactively
### Non-interactive
You can also pass command line arguments to set up a new project
non-interactively. See `create-llama --help`:
+2 -1
View File
@@ -13,6 +13,7 @@ import type { InstallTemplateArgs } from "./templates";
import { installTemplate } from "./templates";
export async function createApp({
import { prompt } from "inquirer";
template,
framework,
engine,
@@ -88,7 +89,7 @@ export async function createApp({
path.join(root, "README.md"),
);
} else {
await installTemplate({ ...args, backend: true, forBackend: framework });
await installTemplate({ ...args, backend: true });
}
process.chdir(root);
+1
View File
@@ -9,6 +9,7 @@ import { blue, bold, cyan, green, red, yellow } from "picocolors";
import prompts from "prompts";
import checkForUpdate from "update-check";
import { createApp } from "./create-app";
import { prompt } from "inquirer";
import { getPkgManager } from "./helpers/get-pkg-manager";
import { isFolderEmpty } from "./helpers/is-folder-empty";
import { validateNpmName } from "./helpers/validate-pkg";
+8 -1
View File
@@ -1,6 +1,6 @@
{
"name": "create-llama",
"version": "0.0.8",
"version": "0.0.6",
"keywords": [
"rag",
"llamaindex",
@@ -44,6 +44,13 @@
"got": "10.7.0",
"picocolors": "1.0.0",
"prompts": "2.1.0",
"prettier": "^x.x.x",
"prettier": "^x.x.x"
"prompts": "2.1.0",
"prettier": "^x.x.x"
"fs-promise": "^3.0.0",
"stable": "^0.2.0",
"trim": "^1.0.3"
"tar": "6.1.15",
"terminal-link": "^3.0.0",
"update-check": "1.5.4",
-21
View File
@@ -103,7 +103,6 @@ const installTSTemplate = async ({
ui,
eslint,
customApiPath,
forBackend,
}: InstallTemplateArgs) => {
console.log(bold(`Using ${packageManager}.`));
@@ -121,26 +120,6 @@ const installTSTemplate = async ({
rename,
});
/**
* If the backend is next.js, rename next.config.app.js to next.config.js
* If not, rename next.config.static.js to next.config.js
*/
if (framework == "nextjs" && forBackend === "nextjs") {
const nextConfigAppPath = path.join(root, "next.config.app.js");
const nextConfigPath = path.join(root, "next.config.js");
await fs.rename(nextConfigAppPath, nextConfigPath);
// delete next.config.static.js
const nextConfigStaticPath = path.join(root, "next.config.static.js");
await fs.rm(nextConfigStaticPath);
} else if (framework == "nextjs" && typeof forBackend === "undefined") {
const nextConfigStaticPath = path.join(root, "next.config.static.js");
const nextConfigPath = path.join(root, "next.config.js");
await fs.rename(nextConfigStaticPath, nextConfigPath);
// delete next.config.app.js
const nextConfigAppPath = path.join(root, "next.config.app.js");
await fs.rm(nextConfigAppPath);
}
/**
* Copy the selected chat engine files to the target directory and reference it.
*/
-1
View File
@@ -17,5 +17,4 @@ export interface InstallTemplateArgs {
eslint: boolean;
customApiPath?: string;
openAIKey?: string;
forBackend?: string;
}
@@ -1,2 +0,0 @@
# local env files
.env
@@ -8,24 +8,12 @@ const port = 8000;
const env = process.env["NODE_ENV"];
const isDevelopment = !env || env === "development";
const prodCorsOrigin = process.env["PROD_CORS_ORIGIN"];
if (isDevelopment) {
console.warn("Running in development mode - allowing CORS for all origins");
app.use(cors());
} else if (prodCorsOrigin) {
console.log(
`Running in production mode - allowing CORS for domain: ${prodCorsOrigin}`,
);
const corsOptions = {
origin: prodCorsOrigin, // Restrict to production domain
};
app.use(cors(corsOptions));
} else {
console.warn("Production CORS origin not set, defaulting to no CORS.");
}
app.use(express.text());
app.use(express.json());
app.get("/", (req: Request, res: Response) => {
res.send("LlamaIndex Express Server");
@@ -4,7 +4,7 @@ import { createChatEngine } from "./engine";
export const chat = async (req: Request, res: Response, next: NextFunction) => {
try {
const { messages }: { messages: ChatMessage[] } = JSON.parse(req.body);
const { messages }: { messages: ChatMessage[] } = req.body;
const lastMessage = messages.pop();
if (!messages || !lastMessage || lastMessage.role !== "user") {
return res.status(400).json({
@@ -6,18 +6,12 @@ from llama_index import (
StorageContext,
VectorStoreIndex,
load_index_from_storage,
ServiceContext,
)
from llama_index.llms import OpenAI
STORAGE_DIR = "./storage" # directory to cache the generated index
DATA_DIR = "./data" # directory containing the documents to index
service_context = ServiceContext.from_defaults(
llm=OpenAI(model="gpt-3.5-turbo")
)
def get_index():
logger = logging.getLogger("uvicorn")
@@ -26,7 +20,7 @@ def get_index():
logger.info("Creating new index")
# load the documents and create the index
documents = SimpleDirectoryReader(DATA_DIR).load_data()
index = VectorStoreIndex.from_documents(documents,service_context=service_context)
index = VectorStoreIndex.from_documents(documents)
# store it for later
index.storage_context.persist(STORAGE_DIR)
logger.info(f"Finished creating new index. Stored in {STORAGE_DIR}")
@@ -34,6 +28,6 @@ def get_index():
# load the existing index
logger.info(f"Loading index from {STORAGE_DIR}...")
storage_context = StorageContext.from_defaults(persist_dir=STORAGE_DIR)
index = load_index_from_storage(storage_context,service_context=service_context)
index = load_index_from_storage(storage_context)
logger.info(f"Finished loading index from {STORAGE_DIR}")
return index
@@ -1,12 +1,12 @@
from dotenv import load_dotenv
load_dotenv()
import logging
import os
import uvicorn
from app.api.routers.chat import chat_router
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
@@ -2,9 +2,6 @@
const nextConfig = {
experimental: {
serverComponentsExternalPackages: ["llamaindex"],
outputFileTracingIncludes: {
"/*": ["./cache/**/*"],
},
},
};
@@ -1,13 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
images: { unoptimized: true },
experimental: {
serverComponentsExternalPackages: ["llamaindex"],
outputFileTracingIncludes: {
"/*": ["./cache/**/*"],
},
},
};
module.exports = nextConfig;
@@ -1,2 +0,0 @@
# local env files
.env
@@ -8,24 +8,12 @@ const port = 8000;
const env = process.env["NODE_ENV"];
const isDevelopment = !env || env === "development";
const prodCorsOrigin = process.env["PROD_CORS_ORIGIN"];
if (isDevelopment) {
console.warn("Running in development mode - allowing CORS for all origins");
app.use(cors());
} else if (prodCorsOrigin) {
console.log(
`Running in production mode - allowing CORS for domain: ${prodCorsOrigin}`,
);
const corsOptions = {
origin: prodCorsOrigin, // Restrict to production domain
};
app.use(cors(corsOptions));
} else {
console.warn("Production CORS origin not set, defaulting to no CORS.");
}
app.use(express.text());
app.use(express.json());
app.get("/", (req: Request, res: Response) => {
res.send("LlamaIndex Express Server");
@@ -6,7 +6,7 @@ import { LlamaIndexStream } from "./llamaindex-stream";
export const chat = async (req: Request, res: Response, next: NextFunction) => {
try {
const { messages }: { messages: ChatMessage[] } = JSON.parse(req.body);
const { messages }: { messages: ChatMessage[] } = req.body;
const lastMessage = messages.pop();
if (!messages || !lastMessage || lastMessage.role !== "user") {
return res.status(400).json({
@@ -6,17 +6,12 @@ from llama_index import (
StorageContext,
VectorStoreIndex,
load_index_from_storage,
ServiceContext,
)
from llama_index.llms import OpenAI
STORAGE_DIR = "./storage" # directory to cache the generated index
DATA_DIR = "./data" # directory containing the documents to index
service_context = ServiceContext.from_defaults(
llm=OpenAI(model="gpt-3.5-turbo")
)
def get_index():
logger = logging.getLogger("uvicorn")
@@ -25,7 +20,7 @@ def get_index():
logger.info("Creating new index")
# load the documents and create the index
documents = SimpleDirectoryReader(DATA_DIR).load_data()
index = VectorStoreIndex.from_documents(documents,service_context=service_context)
index = VectorStoreIndex.from_documents(documents)
# store it for later
index.storage_context.persist(STORAGE_DIR)
logger.info(f"Finished creating new index. Stored in {STORAGE_DIR}")
@@ -33,6 +28,6 @@ def get_index():
# load the existing index
logger.info(f"Loading index from {STORAGE_DIR}...")
storage_context = StorageContext.from_defaults(persist_dir=STORAGE_DIR)
index = load_index_from_storage(storage_context,service_context=service_context)
index = load_index_from_storage(storage_context)
logger.info(f"Finished loading index from {STORAGE_DIR}")
return index
@@ -1,12 +1,12 @@
from dotenv import load_dotenv
load_dotenv()
import logging
import os
import uvicorn
from app.api.routers.chat import chat_router
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
@@ -2,9 +2,6 @@
const nextConfig = {
experimental: {
serverComponentsExternalPackages: ["llamaindex"],
outputFileTracingIncludes: {
"/*": ["./cache/**/*"],
},
},
};
@@ -1,13 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
images: { unoptimized: true },
experimental: {
serverComponentsExternalPackages: ["llamaindex"],
outputFileTracingIncludes: {
"/*": ["./cache/**/*"],
},
},
};
module.exports = nextConfig;