Compare commits

..

25 Commits

Author SHA1 Message Date
Alex Yang b25558497c chore: bump version 2024-01-26 22:31:27 -06:00
Emanuel Ferreira 9ba4547c4d fix: not overwrite metadata (#453) 2024-01-26 09:07:52 -03:00
Tyrone Avnit 4fea0adf43 Expose BaseExtractor Class (#454) 2024-01-26 09:07:36 -03:00
Marcus Schiesser de070dbfa7 RELEASING: Releasing 1 package(s)
Releases:
  create-llama@0.0.19

[skip ci]
2024-01-26 16:33:12 +07:00
Marcus Schiesser 87eb72bdb2 fix: don't install root package for llamapack examples (as there isn't one) 2024-01-26 16:30:50 +07:00
Thuc Pham fe03aaae55 feat: generate llama pack example (#429) 2024-01-26 15:02:49 +07:00
yisding 9ce7d3d648 Update packages (#448) 2024-01-26 11:54:58 +07:00
Alex Yang 0471407761 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.2

[skip ci]
2024-01-25 22:26:59 -06:00
Alex Yang e4b807a018 fix(core): invalid package.json 2024-01-25 22:26:31 -06:00
Alex Yang 0a0ec37725 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.1

[skip ci]
2024-01-25 22:18:14 -06:00
Alex Yang 8abca5d818 build(core): release with node resolution compatibility (#451) 2024-01-25 22:12:15 -06:00
jess-render 3a29a8036b Add node_modules to gitignore in Express backends (#447)
Co-authored-by: Jess Lin <jesslin@Jesss-MBP.render.com>
2024-01-26 09:34:53 +07:00
yisding e2b9b66f71 RELEASING: Releasing 2 package(s)
Releases:
  llamaindex@0.1.0
  docs@0.0.1

[skip ci]
2024-01-25 15:47:02 -08:00
yisding bb66cb7e36 Openai embeddings 3 (#445) 2024-01-25 15:45:21 -08:00
Alex Yang 2159e77c9d RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.0.51

[skip ci]
2024-01-25 14:59:22 -06:00
Emanuel Ferreira 3154f521d9 chore: add qdrant readme (#444) 2024-01-25 17:58:37 -03:00
Alex Yang fda8024607 revert: export conditions not working with moduleResolution node (#443) 2024-01-25 13:51:05 -06:00
Marcus Schiesser 89336e4ddf feat: add deno jupyter examples (#428) 2024-01-25 18:09:19 +07:00
Marcus Schiesser a94f747307 RELEASING: Releasing 1 package(s)
Releases:
  create-llama@0.0.18

[skip ci]
2024-01-25 17:46:19 +07:00
Marcus Schiesser 88d3b41044 fix: create-llama packaging 2024-01-25 17:44:29 +07:00
Marcus Schiesser 7fd02ab8d1 RELEASING: Releasing 1 package(s)
Releases:
  create-llama@0.0.17

[skip ci]
2024-01-25 16:58:45 +07:00
Huu Le (Lee) 9e5d8e143e Feat: add local pdf file option (#441) 2024-01-25 15:20:42 +07:00
Huu Le (Lee) f0f7df29b3 remove chromadb override (as llamaindex is forcing now chromadb 1.7.3) 2024-01-25 14:24:01 +07:00
yisding 05ba70881c RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.0.50

[skip ci]
2024-01-24 23:00:50 -08:00
yisding 8a729cdd0d minor bug fixes with together AI (#440) 2024-01-24 22:59:09 -08:00
53 changed files with 2860 additions and 2315 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"llamaindex": patch
---
update dependencies
-5
View File
@@ -1,5 +0,0 @@
---
"create-llama": patch
---
Add an option that allows the user to run the generated app
-5
View File
@@ -1,5 +0,0 @@
---
"llamaindex": patch
---
fix bugs in Together.AI integration (thanks @Nutlope for reporting)
-3
View File
@@ -1,6 +1,3 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm format
pnpm lint
npx lint-staged
-3
View File
@@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm test
+1
View File
@@ -1 +1,2 @@
auto-install-peers = true
enable-pre-post-scripts = true
+7
View File
@@ -0,0 +1,7 @@
# docs
## 0.0.1
### Patch Changes
- 3154f52: chore: add qdrant readme
@@ -1,5 +1,5 @@
---
sidebar_position: 0
sidebar_position: 1
---
# Documents and Nodes
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 0
sidebar_position: 1
---
# LLM
@@ -0,0 +1,2 @@
label: "Vector Stores"
position: 0
@@ -0,0 +1,88 @@
# Qdrant Vector Store
To run this example, you need to have a Qdrant instance running. You can run it with Docker:
```bash
docker pull qdrant/qdrant
docker run -p 6333:6333 qdrant/qdrant
```
## Importing the modules
```ts
import fs from "node:fs/promises";
import { Document, VectorStoreIndex, QdrantVectorStore } from "llamaindex";
```
## Load the documents
```ts
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
```
## Setup Qdrant
```ts
const vectorStore = new QdrantVectorStore({
url: "http://localhost:6333",
port: 6333,
});
```
## Setup the index
```ts
const document = new Document({ text: essay, id_: path });
const index = await VectorStoreIndex.fromDocuments([document], {
vectorStore,
});
```
## Query the index
```ts
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({
query: "What did the author do in college?",
});
// Output response
console.log(response.toString());
```
## Full code
```ts
import fs from "node:fs/promises";
import { Document, VectorStoreIndex, QdrantVectorStore } from "llamaindex";
async function main() {
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
const vectorStore = new QdrantVectorStore({
url: "http://localhost:6333",
port: 6333,
});
const document = new Document({ text: essay, id_: path });
const index = await VectorStoreIndex.fromDocuments([document], {
vectorStore,
});
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({
query: "What did the author do in college?",
});
// Output response
console.log(response.toString());
}
main().catch(console.error);
```
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.0",
"version": "0.0.1",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -15,8 +15,8 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^3.1.0",
"@docusaurus/remark-plugin-npm2yarn": "^3.1.0",
"@docusaurus/core": "^3.1.1",
"@docusaurus/remark-plugin-npm2yarn": "^3.1.1",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.1.0",
"postcss": "^8.4.33",
@@ -27,11 +27,11 @@
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.1.0",
"@docusaurus/preset-classic": "^3.1.0",
"@docusaurus/theme-classic": "^3.1.0",
"@docusaurus/types": "^3.1.0",
"@docusaurus/preset-classic": "^3.1.1",
"@docusaurus/theme-classic": "^3.1.1",
"@docusaurus/types": "^3.1.1",
"@tsconfig/docusaurus": "^2.0.2",
"@types/node": "^18.19.6",
"@types/node": "^18.19.10",
"docusaurus-plugin-typedoc": "^0.22.0",
"typedoc": "^0.25.7",
"typedoc-plugin-markdown": "^3.17.1",
+1
View File
@@ -0,0 +1 @@
.ipynb_checkpoints/
+31
View File
@@ -0,0 +1,31 @@
# Jupyter examples
## Preparation
1. Install Deno, e.g. on macOS:
```
brew install deno
```
2. Install Jupyter
```
pip3 install jupyterlab
```
3. Install Deno kernel
```
deno jupyter --unstable --install
```
4. Run Jupyter
```
jupyter lab
```
## Run examples
Then you can open in Jupyter any of the examples in this directory.
+82
View File
@@ -0,0 +1,82 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"id": "8be89595-8885-4d5e-b1da-1df04eda5c7a",
"metadata": {},
"outputs": [],
"source": [
"import {\n",
" Document,\n",
" SimpleNodeParser\n",
"} from \"npm:llamaindex\";"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "65de03f9-455a-4c59-9089-093cb6998af7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[\n",
" TextNode {\n",
" id_: \u001b[32m\"1b2ab25e-562a-4821-bdde-860bd23121c1\"\u001b[39m,\n",
" metadata: {},\n",
" excludedEmbedMetadataKeys: [],\n",
" excludedLlmMetadataKeys: [],\n",
" relationships: {\n",
" SOURCE: {\n",
" nodeId: \u001b[32m\"0cb8de0e-845f-4e73-a7bd-f04426aacfed\"\u001b[39m,\n",
" metadata: {},\n",
" hash: \u001b[32m\"jatVVXETDFjV2fV1/fbTrdpY6ZGnSYekq9m1X/Ff1qs=\"\u001b[39m\n",
" }\n",
" },\n",
" hash: \u001b[32m\"zVyeDsfMwWH1CqK2269o5uzGWl/DpIWO4ZcVCuyENi4=\"\u001b[39m,\n",
" text: \u001b[32m\"I am 10 years old. John is 20 years old.\"\u001b[39m,\n",
" metadataSeparator: \u001b[32m\"\\n\"\u001b[39m\n",
" }\n",
"]\n"
]
}
],
"source": [
"const nodeParser = new SimpleNodeParser();\n",
"const nodes = nodeParser.getNodesFromDocuments([\n",
" new Document({ text: \"I am 10 years old. John is 20 years old.\" }),\n",
"]);\n",
"\n",
"console.log(nodes);"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc0ec12f-2062-47af-916d-7c77ca39433a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Deno",
"language": "typescript",
"name": "deno"
},
"language_info": {
"file_extension": ".ts",
"mimetype": "text/x.typescript",
"name": "typescript",
"nb_converter": "script",
"pygments_lexer": "typescript",
"version": "5.3.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+83
View File
@@ -0,0 +1,83 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 7,
"id": "8be89595-8885-4d5e-b1da-1df04eda5c7a",
"metadata": {},
"outputs": [],
"source": [
"import {\n",
" Document,\n",
" VectorStoreIndex\n",
"} from \"npm:llamaindex\";"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "65de03f9-455a-4c59-9089-093cb6998af7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"In college, the author studied subjects such as linear algebra and physics, but did not find them particularly interesting. They also slacked off and skipped lectures, leading to gaps in their knowledge. They had a negative experience with their English classes and became resentful and suspicious of higher education. They eventually dropped out of college and did not return until five years later to pick up their papers.\n"
]
}
],
"source": [
"// Create Document object with essay\n",
"const resp = await fetch('https://raw.githubusercontent.com/run-llama/LlamaIndexTS/main/packages/core/examples/abramov.txt');\n",
"const text = await resp.text();\n",
"const document = new Document({ text });\n",
"\n",
"// Split text and create embeddings. Store them in a VectorStoreIndex\n",
"const index = await VectorStoreIndex.fromDocuments([document]);\n",
"\n",
"// Query the index\n",
"const queryEngine = index.asQueryEngine();\n",
"const response = await queryEngine.query({\n",
" query: \"What did the author do in college?\",\n",
"});\n",
"\n",
"// Output response\n",
"console.log(response.toString());"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc0ec12f-2062-47af-916d-7c77ca39433a",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "68bdd292-5cf7-46e0-8646-51be1f070ad6",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Deno",
"language": "typescript",
"name": "deno"
},
"language_info": {
"file_extension": ".ts",
"mimetype": "text/x.typescript",
"name": "typescript",
"nb_converter": "script",
"pygments_lexer": "typescript",
"version": "5.3.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+7 -7
View File
@@ -2,18 +2,18 @@
"name": "examples",
"private": true,
"dependencies": {
"@datastax/astra-db-ts": "^0.1.2",
"@datastax/astra-db-ts": "^0.1.4",
"@notionhq/client": "^2.2.14",
"@pinecone-database/pinecone": "^1.1.2",
"chromadb": "^1.7.3",
"@pinecone-database/pinecone": "^1.1.3",
"chromadb": "^1.8.1",
"commander": "^11.1.0",
"dotenv": "^16.3.1",
"llamaindex": "latest",
"dotenv": "^16.4.1",
"llamaindex": "workspace:^",
"mongodb": "^6.2.0"
},
"devDependencies": {
"@types/node": "^18.18.6",
"ts-node": "^10.9.1"
"@types/node": "^18.19.10",
"ts-node": "^10.9.2"
},
"scripts": {
"lint": "eslint ."
+41
View File
@@ -0,0 +1,41 @@
import fs from "node:fs/promises";
import {
Document,
OpenAIEmbedding,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
async function main() {
// Load essay from abramov.txt in Node
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
// Create Document object with essay
const document = new Document({ text: essay, id_: path });
// Create service context and specify text-embedding-3-large
const embedModel = new OpenAIEmbedding({
model: "text-embedding-3-large",
dimensions: 1024,
});
const serviceContext = serviceContextFromDefaults({ embedModel });
// Split text and create embeddings. Store them in a VectorStoreIndex
const index = await VectorStoreIndex.fromDocuments([document], {
serviceContext,
});
// Query the index
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({
query: "What did the author do in college?",
});
// Output response
console.log(response.toString());
}
main().catch(console.error);
+6 -6
View File
@@ -8,7 +8,7 @@
"format": "prettier --ignore-unknown --cache --check .",
"format:write": "prettier --ignore-unknown --write .",
"lint": "turbo run lint",
"prepare": "husky install",
"prepare": "husky",
"test": "turbo run test",
"type-check": "tsc -b --diagnostics",
"release": "pnpm run build:release && changeset publish",
@@ -18,20 +18,20 @@
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@turbo/gen": "^1.11.2",
"@turbo/gen": "^1.11.3",
"@types/jest": "^29.5.11",
"eslint": "^8.56.0",
"eslint-config-custom": "workspace:*",
"husky": "^8.0.3",
"husky": "^9.0.6",
"jest": "^29.7.0",
"lint-staged": "^15.2.0",
"prettier": "^3.2.4",
"prettier-plugin-organize-imports": "^3.2.4",
"ts-jest": "^29.1.1",
"turbo": "^1.11.2",
"ts-jest": "^29.1.2",
"turbo": "^1.11.3",
"typescript": "^5.3.3"
},
"packageManager": "pnpm@8.10.5+sha256.a4bd9bb7b48214bbfcd95f264bd75bb70d100e5d4b58808f5cd6ab40c6ac21c5",
"packageManager": "pnpm@8.14.3+sha256.2d0363bb6c314daa67087ef07743eea1ba2e2d360c835e8fec6b5575e4ed9484",
"pnpm": {
"overrides": {
"trim": "1.0.1",
+30
View File
@@ -1,5 +1,35 @@
# llamaindex
## 0.1.2
- e4b807a: fix: invalid package.json
## 0.1.1
No changes for this release.
## 0.1.0
### Minor Changes
- 3154f52: chore: add qdrant readme
### Patch Changes
- bb66cb7: add new OpenAI embeddings (with dimension reduction support)
## 0.0.51
### Patch Changes
- fda8024: revert: export conditions not working with moduleResolution `node`
## 0.0.50
### Patch Changes
- 8a729cd: fix bugs in Together.AI integration (thanks @Nutlope for reporting)
## 0.0.49
### Patch Changes
-130
View File
@@ -1,130 +0,0 @@
# LlamaIndex.TS
[![NPM Version](https://img.shields.io/npm/v/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM License](https://img.shields.io/npm/l/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM Downloads](https://img.shields.io/npm/dm/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![Discord](https://img.shields.io/discord/1059199217496772688)](https://discord.com/invite/eN6D2HQ4aX)
LlamaIndex is a data framework for your LLM application.
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in Typescript and Javascript.
Documentation: https://ts.llamaindex.ai/
## What is LlamaIndex.TS?
LlamaIndex.TS aims to be a lightweight, easy to use set of libraries to help you integrate large language models into your applications with your own data.
## Getting started with an example:
LlamaIndex.TS requires Node v18 or higher. You can download it from https://nodejs.org or use https://nvm.sh (our preferred option).
In a new folder:
```bash
export OPENAI_API_KEY="sk-......" # Replace with your key from https://platform.openai.com/account/api-keys
pnpm init
pnpm install typescript
pnpm exec tsc --init # if needed
pnpm install llamaindex
pnpm install @types/node
```
Create the file example.ts
```ts
// example.ts
import fs from "fs/promises";
import { Document, VectorStoreIndex } from "llamaindex";
async function main() {
// Load essay from abramov.txt in Node
const essay = await fs.readFile(
"node_modules/llamaindex/examples/abramov.txt",
"utf-8",
);
// Create Document object with essay
const document = new Document({ text: essay });
// Split text and create embeddings. Store them in a VectorStoreIndex
const index = await VectorStoreIndex.fromDocuments([document]);
// Query the index
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query(
"What did the author do in college?",
);
// Output response
console.log(response.toString());
}
main();
```
Then you can run it using
```bash
pnpx ts-node example.ts
```
## Playground
Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
## Core concepts for getting started:
- [Document](/packages/core/src/Node.ts): A document represents a text file, PDF file or other contiguous piece of data.
- [Node](/packages/core/src/Node.ts): The basic data building block. Most commonly, these are parts of the document split into manageable pieces that are small enough to be fed into an embedding model and LLM.
- [Embedding](/packages/core/src/Embedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that quesiton.
- [Indices](/packages/core/src/indices/): Indices store the Nodes and the embeddings of those nodes. QueryEngines retrieve Nodes from these Indices using embedding similarity.
- [QueryEngine](/packages/core/src/QueryEngine.ts): Query engines are what generate the query you put in and give you back the result. Query engines generally combine a pre-built prompt with selected Nodes from your Index to give the LLM the context it needs to answer your query.
- [ChatEngine](/packages/core/src/ChatEngine.ts): A ChatEngine helps you build a chatbot that will interact with your Indices.
- [SimplePrompt](/packages/core/src/Prompt.ts): A simple standardized function call definition that takes in inputs and formats them in a template literal. SimplePrompts can be specialized using currying and combined using other SimplePrompt functions.
## Note: NextJS:
If you're using NextJS App Router, you'll need to use the NodeJS runtime (default) and add the following config to your next.config.js to have it use imports/exports in the same way Node does.
```js
export const runtime = "nodejs"; // default
```
```js
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.alias = {
...config.resolve.alias,
sharp$: false,
"onnxruntime-node$": false,
};
return config;
},
};
module.exports = nextConfig;
```
## Supported LLMs:
- OpenAI GPT-3.5-turbo and GPT-4
- Anthropic Claude Instant and Claude 2
- Llama2 Chat LLMs (70B, 13B, and 7B parameters)
- MistralAI Chat LLMs
## Contributing:
We are in the very early days of LlamaIndex.TS. If youre interested in hacking on it with us check out our [contributing guide](/CONTRIBUTING.md)
## Bugs? Questions?
Please join our Discord! https://discord.com/invite/eN6D2HQ4aX
+24 -152
View File
@@ -1,16 +1,17 @@
{
"name": "llamaindex",
"version": "0.0.49",
"private": true,
"version": "0.1.2",
"license": "MIT",
"dependencies": {
"@anthropic-ai/sdk": "^0.9.1",
"@datastax/astra-db-ts": "^0.1.2",
"@mistralai/mistralai": "^0.0.7",
"@anthropic-ai/sdk": "^0.12.4",
"@datastax/astra-db-ts": "^0.1.4",
"@mistralai/mistralai": "^0.0.10",
"@notionhq/client": "^2.2.14",
"@pinecone-database/pinecone": "^1.1.2",
"@pinecone-database/pinecone": "^1.1.3",
"@qdrant/js-client-rest": "^1.7.0",
"@xenova/transformers": "^2.10.0",
"assemblyai": "^4.0.0",
"@xenova/transformers": "^2.14.1",
"assemblyai": "^4.2.1",
"chromadb": "~1.7.3",
"file-type": "^18.7.0",
"js-tiktoken": "^1.0.8",
@@ -19,26 +20,28 @@
"md-utils-ts": "^2.0.0",
"mongodb": "^6.3.0",
"notion-md-crawler": "^0.0.2",
"openai": "^4.20.1",
"openai": "^4.26.0",
"papaparse": "^5.4.1",
"pathe": "^1.1.2",
"pdfjs-dist": "4.0.269",
"pg": "^8.11.3",
"pgvector": "^0.1.5",
"pgvector": "^0.1.7",
"portkey-ai": "^0.1.16",
"rake-modified": "^1.0.8",
"replicate": "^0.21.1",
"string-strip-html": "^13.4.3",
"replicate": "^0.25.2",
"string-strip-html": "^13.4.5",
"wink-nlp": "^1.14.3"
},
"devDependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@types/edit-json-file": "^1.7.3",
"@types/jest": "^29.5.11",
"@types/lodash": "^4.14.202",
"@types/node": "^18.19.6",
"@types/node": "^18.19.10",
"@types/papaparse": "^5.3.14",
"@types/pg": "^8.10.9",
"bunchee": "^4.4.1",
"@types/pg": "^8.11.0",
"bunchee": "^4.4.2",
"edit-json-file": "^1.8.0",
"madge": "^6.1.0",
"typescript": "^5.3.3"
},
@@ -50,154 +53,19 @@
"exports": {
".": {
"types": "./dist/index.d.mts",
"edge-light": "./dist/index.edge-light.mjs",
"import": "./dist/index.mjs",
"edge-light": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./env": {
"types": "./dist/env.d.mts",
"edge-light": "./dist/env.edge-light.mjs",
"import": "./dist/env.mjs",
"edge-light": "./dist/env.mjs",
"require": "./dist/env.js"
},
"./storage/FileSystem": {
"types": "./dist/storage/FileSystem.d.mts",
"edge-light": "./dist/storage/FileSystem.edge-light.mjs",
"import": "./dist/storage/FileSystem.mjs",
"require": "./dist/storage/FileSystem.js"
},
"./ChatHistory": {
"types": "./dist/ChatHistory.d.mts",
"import": "./dist/ChatHistory.mjs",
"require": "./dist/ChatHistory.js"
},
"./constants": {
"types": "./dist/constants.d.mts",
"import": "./dist/constants.mjs",
"require": "./dist/constants.js"
},
"./GlobalsHelper": {
"types": "./dist/GlobalsHelper.d.mts",
"import": "./dist/GlobalsHelper.mjs",
"require": "./dist/GlobalsHelper.js"
},
"./Node": {
"types": "./dist/Node.d.mts",
"import": "./dist/Node.mjs",
"require": "./dist/Node.js"
},
"./OutputParser": {
"types": "./dist/OutputParser.d.mts",
"import": "./dist/OutputParser.mjs",
"require": "./dist/OutputParser.js"
},
"./Prompt": {
"types": "./dist/Prompt.d.mts",
"import": "./dist/Prompt.mjs",
"require": "./dist/Prompt.js"
},
"./PromptHelper": {
"types": "./dist/PromptHelper.d.mts",
"import": "./dist/PromptHelper.mjs",
"require": "./dist/PromptHelper.js"
},
"./QueryEngine": {
"types": "./dist/QueryEngine.d.mts",
"import": "./dist/QueryEngine.mjs",
"require": "./dist/QueryEngine.js"
},
"./QuestionGenerator": {
"types": "./dist/QuestionGenerator.d.mts",
"import": "./dist/QuestionGenerator.mjs",
"require": "./dist/QuestionGenerator.js"
},
"./Response": {
"types": "./dist/Response.d.mts",
"import": "./dist/Response.mjs",
"require": "./dist/Response.js"
},
"./Retriever": {
"types": "./dist/Retriever.d.mts",
"import": "./dist/Retriever.mjs",
"require": "./dist/Retriever.js"
},
"./ServiceContext": {
"types": "./dist/ServiceContext.d.mts",
"import": "./dist/ServiceContext.mjs",
"require": "./dist/ServiceContext.js"
},
"./TextSplitter": {
"types": "./dist/TextSplitter.d.mts",
"import": "./dist/TextSplitter.mjs",
"require": "./dist/TextSplitter.js"
},
"./Tool": {
"types": "./dist/Tool.d.mts",
"import": "./dist/Tool.mjs",
"require": "./dist/Tool.js"
},
"./readers/AssemblyAI": {
"types": "./dist/readers/AssemblyAI.d.mts",
"import": "./dist/readers/AssemblyAI.mjs",
"require": "./dist/readers/AssemblyAI.js"
},
"./readers/base": {
"types": "./dist/readers/base.d.mts",
"import": "./dist/readers/base.mjs",
"require": "./dist/readers/base.js"
},
"./readers/CSVReader": {
"types": "./dist/readers/CSVReader.d.mts",
"import": "./dist/readers/CSVReader.mjs",
"require": "./dist/readers/CSVReader.js"
},
"./readers/DocxReader": {
"types": "./dist/readers/DocxReader.d.mts",
"import": "./dist/readers/DocxReader.mjs",
"require": "./dist/readers/DocxReader.js"
},
"./readers/HTMLReader": {
"types": "./dist/readers/HTMLReader.d.mts",
"import": "./dist/readers/HTMLReader.mjs",
"require": "./dist/readers/HTMLReader.js"
},
"./readers/ImageReader": {
"types": "./dist/readers/ImageReader.d.mts",
"import": "./dist/readers/ImageReader.mjs",
"require": "./dist/readers/ImageReader.js"
},
"./readers/MarkdownReader": {
"types": "./dist/readers/MarkdownReader.d.mts",
"import": "./dist/readers/MarkdownReader.mjs",
"require": "./dist/readers/MarkdownReader.js"
},
"./readers/NotionReader": {
"types": "./dist/readers/NotionReader.d.mts",
"import": "./dist/readers/NotionReader.mjs",
"require": "./dist/readers/NotionReader.js"
},
"./readers/PDFReader": {
"types": "./dist/readers/PDFReader.d.mts",
"import": "./dist/readers/PDFReader.mjs",
"require": "./dist/readers/PDFReader.js"
},
"./readers/SimpleDirectoryReader": {
"types": "./dist/readers/SimpleDirectoryReader.d.mts",
"import": "./dist/readers/SimpleDirectoryReader.mjs",
"require": "./dist/readers/SimpleDirectoryReader.js"
},
"./readers/SimpleMongoReader": {
"types": "./dist/readers/SimpleMongoReader.d.mts",
"import": "./dist/readers/SimpleMongoReader.mjs",
"require": "./dist/readers/SimpleMongoReader.js"
}
},
"files": [
"dist",
"examples",
"src",
"types",
"CHANGELOG.md"
"**"
],
"repository": {
"type": "git",
@@ -208,6 +76,10 @@
"lint": "eslint .",
"test": "jest",
"build": "bunchee",
"postbuild": "pnpm run copy && pnpm run modify-package-json",
"copy": "cp -r package.json CHANGELOG.md ../../README.md ../../LICENSE examples src dist/",
"modify-package-json": "node ./scripts/modify-package-json.mjs",
"prepublish": "pnpm run modify-package-json && echo \"please cd ./dist and run pnpm publish\" && exit 1",
"dev": "bunchee -w",
"circular-check": "madge --circular ./src/*.ts"
}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env node
/**
* This script is used to modify the package.json file in the dist folder
* so that it can be published to npm.
*/
import editJsonFile from "edit-json-file";
import fs from "node:fs/promises";
{
await fs.copyFile("./package.json", "./dist/package.json");
const file = editJsonFile("./dist/package.json");
file.unset("scripts");
file.unset("private");
await new Promise((resolve) => file.save(resolve));
}
{
const packageJson = await fs.readFile("./dist/package.json", "utf8");
const modifiedPackageJson = packageJson.replaceAll("./dist/", "./");
await fs.writeFile(
"./dist/package.json",
JSON.stringify(JSON.parse(modifiedPackageJson), null, 2),
"utf8",
);
}
-2
View File
@@ -6,6 +6,4 @@ export const DEFAULT_CHUNK_OVERLAP = 20;
export const DEFAULT_CHUNK_OVERLAP_RATIO = 0.1;
export const DEFAULT_SIMILARITY_TOP_K = 2;
// NOTE: for text-embedding-ada-002
export const DEFAULT_EMBEDDING_DIM = 1536;
export const DEFAULT_PADDING = 5;
@@ -9,28 +9,55 @@ import {
import { OpenAISession, getOpenAISession } from "../llm/openai";
import { BaseEmbedding } from "./types";
export enum OpenAIEmbeddingModelType {
TEXT_EMBED_ADA_002 = "text-embedding-ada-002",
}
export const ALL_OPENAI_EMBEDDING_MODELS = {
"text-embedding-ada-002": {
dimensions: 1536,
maxTokens: 8191,
},
"text-embedding-3-small": {
dimensions: 1536,
dimensionOptions: [512, 1536],
maxTokens: 8191,
},
"text-embedding-3-large": {
dimensions: 3072,
dimensionOptions: [256, 1024, 3072],
maxTokens: 8191,
},
};
export class OpenAIEmbedding extends BaseEmbedding {
model: OpenAIEmbeddingModelType | string;
/** embeddding model. defaults to "text-embedding-ada-002" */
model: string;
/** number of dimensions of the resulting vector, for models that support choosing fewer dimensions. undefined will default to model default */
dimensions: number | undefined;
// OpenAI session params
/** api key */
apiKey?: string = undefined;
/** maximum number of retries, default 10 */
maxRetries: number;
/** timeout in ms, default 60 seconds */
timeout?: number;
/** other session options for OpenAI */
additionalSessionOptions?: Omit<
Partial<OpenAIClientOptions>,
"apiKey" | "maxRetries" | "timeout"
>;
/** session object */
session: OpenAISession;
/**
* OpenAI Embedding
* @param init - initial parameters
*/
constructor(init?: Partial<OpenAIEmbedding> & { azure?: AzureOpenAIConfig }) {
super();
this.model = init?.model ?? OpenAIEmbeddingModelType.TEXT_EMBED_ADA_002;
this.model = init?.model ?? "text-embedding-ada-002";
this.dimensions = init?.dimensions; // if no dimensions provided, will be undefined/not sent to OpenAI
this.maxRetries = init?.maxRetries ?? 10;
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
@@ -76,6 +103,7 @@ export class OpenAIEmbedding extends BaseEmbedding {
private async getOpenAIEmbedding(input: string) {
const { data } = await this.session.openai.embeddings.create({
model: this.model,
dimensions: this.dimensions, // only sent to OpenAI if set by user
input,
});
+1
View File
@@ -4,3 +4,4 @@ export {
SummaryExtractor,
TitleExtractor,
} from "./MetadataExtractors";
export { BaseExtractor } from "./types";
+4 -1
View File
@@ -46,7 +46,10 @@ export abstract class BaseExtractor implements TransformComponent {
let curMetadataList = await this.extract(newNodes);
for (let idx in newNodes) {
newNodes[idx].metadata = curMetadataList[idx];
newNodes[idx].metadata = {
...newNodes[idx].metadata,
...curMetadataList[idx],
};
}
for (let idx in newNodes) {
+8 -1
View File
@@ -41,14 +41,21 @@ import {
export const GPT4_MODELS = {
"gpt-4": { contextWindow: 8192 },
"gpt-4-32k": { contextWindow: 32768 },
"gpt-4-32k-0613": { contextWindow: 32768 },
"gpt-4-turbo-preview": { contextWindow: 128000 },
"gpt-4-1106-preview": { contextWindow: 128000 },
"gpt-4-vision-preview": { contextWindow: 8192 },
"gpt-4-0125-preview": { contextWindow: 128000 },
"gpt-4-vision-preview": { contextWindow: 128000 },
};
// NOTE we don't currently support gpt-3.5-turbo-instruct and don't plan to in the near future
export const GPT35_MODELS = {
"gpt-3.5-turbo": { contextWindow: 4096 },
"gpt-3.5-turbo-0613": { contextWindow: 4096 },
"gpt-3.5-turbo-16k": { contextWindow: 16384 },
"gpt-3.5-turbo-16k-0613": { contextWindow: 16384 },
"gpt-3.5-turbo-1106": { contextWindow: 16384 },
"gpt-3.5-turbo-0125": { contextWindow: 16384 },
};
/**
+26 -2
View File
@@ -17,6 +17,14 @@ const ALL_AZURE_OPENAI_CHAT_MODELS = {
},
"gpt-4": { contextWindow: 8192, openAIModel: "gpt-4" },
"gpt-4-32k": { contextWindow: 32768, openAIModel: "gpt-4-32k" },
"gpt-4-vision-preview": {
contextWindow: 128000,
openAIModel: "gpt-4-vision-preview",
},
"gpt-4-1106-preview": {
contextWindow: 128000,
openAIModel: "gpt-4-1106-preview",
},
};
const ALL_AZURE_OPENAI_EMBEDDING_MODELS = {
@@ -25,13 +33,29 @@ const ALL_AZURE_OPENAI_EMBEDDING_MODELS = {
openAIModel: "text-embedding-ada-002",
maxTokens: 8191,
},
"text-embedding-3-small": {
dimensions: 1536,
dimensionOptions: [512, 1536],
openAIModel: "text-embedding-3-small",
maxTokens: 8191,
},
"text-embedding-3-large": {
dimensions: 3072,
dimensionOptions: [256, 1024, 3072],
openAIModel: "text-embedding-3-large",
maxTokens: 8191,
},
};
const ALL_AZURE_API_VERSIONS = [
"2022-12-01",
"2023-05-15",
"2023-06-01-preview",
"2023-07-01-preview",
"2023-03-15-preview", // retiring 2024-04-02
"2023-06-01-preview", // retiring 2024-04-02
"2023-07-01-preview", // retiring 2024-04-02
"2023-08-01-preview", // retiring 2024-04-02
"2023-09-01-preview",
"2023-12-01-preview",
];
const DEFAULT_API_VERSION = "2023-05-15";
@@ -20,6 +20,7 @@ export class PGVectorStore implements VectorStore {
private schemaName: string = PGVECTOR_SCHEMA;
private tableName: string = PGVECTOR_TABLE;
private connectionString: string | undefined = undefined;
private dimensions: number = 1536;
private db?: pg.Client;
@@ -38,15 +39,18 @@ export class PGVectorStore implements VectorStore {
* @param {string} config.schemaName - The name of the schema (optional). Defaults to PGVECTOR_SCHEMA.
* @param {string} config.tableName - The name of the table (optional). Defaults to PGVECTOR_TABLE.
* @param {string} config.connectionString - The connection string (optional).
* @param {number} config.dimensions - The dimensions of the embedding model.
*/
constructor(config?: {
schemaName?: string;
tableName?: string;
connectionString?: string;
dimensions?: number;
}) {
this.schemaName = config?.schemaName ?? PGVECTOR_SCHEMA;
this.tableName = config?.tableName ?? PGVECTOR_TABLE;
this.connectionString = config?.connectionString;
this.dimensions = config?.dimensions ?? 1536;
}
/**
@@ -108,7 +112,7 @@ export class PGVectorStore implements VectorStore {
collection VARCHAR,
document TEXT,
metadata JSONB DEFAULT '{}',
embeddings VECTOR(1536)
embeddings VECTOR(${this.dimensions})
)`;
await db.query(tbl);
@@ -54,11 +54,9 @@ export class QdrantVectorStore implements VectorStore {
apiKey,
batchSize,
}: QdrantParams) {
if (!client && (!url || !apiKey)) {
if (!url || !apiKey || !collectionName) {
throw new Error(
"QdrantVectorStore requires url, apiKey and collectionName",
);
if (!client && !url) {
if (!url || !collectionName) {
throw new Error("QdrantVectorStore requires url and collectionName");
}
}
-3
View File
@@ -1,3 +0,0 @@
declare module "@mistralai/mistralai" {
export = MistralClient;
}
+20
View File
@@ -1,5 +1,25 @@
# create-llama
## 0.0.19
### Patch Changes
- 3a29a80: Add node_modules to gitignore in Express backends
- fe03aaa: feat: generate llama pack example
## 0.0.18
### Patch Changes
- 88d3b41: fix packaging
## 0.0.17
### Patch Changes
- fa17f7e: Add an option that allows the user to run the generated app
- 9e5d8e1: Add an option to select a local PDF file as data source
## 0.0.16
### Patch Changes
+4
View File
@@ -32,9 +32,11 @@ export async function createApp({
openAiKey,
model,
communityProjectPath,
llamapack,
vectorDb,
externalPort,
postInstallAction,
contextFile,
}: InstallAppArgs): Promise<void> {
const root = path.resolve(appPath);
@@ -74,9 +76,11 @@ export async function createApp({
openAiKey,
model,
communityProjectPath,
llamapack,
vectorDb,
externalPort,
postInstallAction,
contextFile,
};
if (frontend) {
@@ -1,2 +1,6 @@
export const COMMUNITY_OWNER = "run-llama";
export const COMMUNITY_REPO = "create_llama_projects";
export const LLAMA_PACK_OWNER = "run-llama";
export const LLAMA_PACK_REPO = "llama-hub";
export const LLAMA_HUB_FOLDER_PATH = `${LLAMA_PACK_OWNER}/${LLAMA_PACK_REPO}/main/llama_hub`;
export const LLAMA_PACK_CONFIG_PATH = `${LLAMA_HUB_FOLDER_PATH}/llama_packs/library.json`;
+29 -12
View File
@@ -7,6 +7,7 @@ import { cyan } from "picocolors";
import { COMMUNITY_OWNER, COMMUNITY_REPO } from "./constant";
import { PackageManager } from "./get-pkg-manager";
import { installLlamapackProject } from "./llama-pack";
import { isHavingPoetryLockFile, tryPoetryRun } from "./poetry";
import { installPythonTemplate } from "./python";
import { downloadAndExtractRepo } from "./repo";
@@ -70,22 +71,32 @@ const copyTestData = async (
engine?: TemplateEngine,
openAiKey?: string,
vectorDb?: TemplateVectorDB,
contextFile?: string,
// eslint-disable-next-line max-params
) => {
if (engine === "context") {
const srcPath = path.join(
__dirname,
"..",
"templates",
"components",
"data",
);
const destPath = path.join(root, "data");
console.log(`\nCopying test data to ${cyan(destPath)}\n`);
await copy("**", destPath, {
parents: true,
cwd: srcPath,
});
if (contextFile) {
console.log(`\nCopying provided file to ${cyan(destPath)}\n`);
await fs.mkdir(destPath, { recursive: true });
await fs.copyFile(
contextFile,
path.join(destPath, path.basename(contextFile)),
);
} else {
const srcPath = path.join(
__dirname,
"..",
"templates",
"components",
"data",
);
console.log(`\nCopying test data to ${cyan(destPath)}\n`);
await copy("**", destPath, {
parents: true,
cwd: srcPath,
});
}
}
if (packageManager && engine === "context") {
@@ -143,6 +154,11 @@ export const installTemplate = async (
return;
}
if (props.template === "llamapack" && props.llamapack) {
await installLlamapackProject(props);
return;
}
if (props.framework === "fastapi") {
await installPythonTemplate(props);
} else {
@@ -168,6 +184,7 @@ export const installTemplate = async (
props.engine,
props.openAiKey,
props.vectorDb,
props.contextFile,
);
} else {
// this is a frontend for a full-stack app, create .env file with model information
@@ -0,0 +1,91 @@
import fs from "fs/promises";
import path from "path";
import { LLAMA_HUB_FOLDER_PATH, LLAMA_PACK_CONFIG_PATH } from "./constant";
import { copy } from "./copy";
import { installPythonDependencies } from "./python";
import { getRepoRawContent } from "./repo";
import { InstallTemplateArgs } from "./types";
export async function getAvailableLlamapackOptions(): Promise<
{
name: string;
folderPath: string;
example: boolean | undefined;
}[]
> {
const libraryJsonRaw = await getRepoRawContent(LLAMA_PACK_CONFIG_PATH);
const libraryJson = JSON.parse(libraryJsonRaw);
const llamapackKeys = Object.keys(libraryJson);
return llamapackKeys
.map((key) => ({
name: key,
folderPath: libraryJson[key].id,
example: libraryJson[key].example,
}))
.filter((item) => !!item.example);
}
const copyLlamapackEmptyProject = async ({
root,
}: Pick<InstallTemplateArgs, "root">) => {
const templatePath = path.join(
__dirname,
"..",
"templates/components/sample-projects/llamapack",
);
await copy("**", root, {
parents: true,
cwd: templatePath,
});
};
const copyData = async ({
root,
}: Pick<InstallTemplateArgs, "root" | "llamapack">) => {
const dataPath = path.join(__dirname, "..", "templates/components/data");
await copy("**", path.join(root, "data"), {
parents: true,
cwd: dataPath,
});
};
const installLlamapackExample = async ({
root,
llamapack,
}: Pick<InstallTemplateArgs, "root" | "llamapack">) => {
const exampleFileName = "example.py";
const readmeFileName = "README.md";
const exampleFilePath = `${LLAMA_HUB_FOLDER_PATH}/${llamapack}/${exampleFileName}`;
const readmeFilePath = `${LLAMA_HUB_FOLDER_PATH}/${llamapack}/${readmeFileName}`;
// Download example.py from llamapack and save to root
const exampleContent = await getRepoRawContent(exampleFilePath);
await fs.writeFile(path.join(root, exampleFileName), exampleContent);
// Download README.md from llamapack and combine with README-template.md,
// save to root and then delete template file
const readmeContent = await getRepoRawContent(readmeFilePath);
const readmeTemplateContent = await fs.readFile(
path.join(root, "README-template.md"),
"utf-8",
);
await fs.writeFile(
path.join(root, readmeFileName),
`${readmeContent}\n${readmeTemplateContent}`,
);
await fs.unlink(path.join(root, "README-template.md"));
};
export const installLlamapackProject = async ({
root,
llamapack,
postInstallAction,
}: Pick<InstallTemplateArgs, "root" | "llamapack" | "postInstallAction">) => {
console.log("\nInstalling Llamapack project:", llamapack!);
await copyLlamapackEmptyProject({ root });
await copyData({ root });
await installLlamapackExample({ root, llamapack });
if (postInstallAction !== "none") {
installPythonDependencies({ noRoot: true });
}
};
+4 -2
View File
@@ -10,9 +10,11 @@ export function isPoetryAvailable(): boolean {
return false;
}
export function tryPoetryInstall(): boolean {
export function tryPoetryInstall(noRoot: boolean): boolean {
try {
execSync("poetry install", { stdio: "inherit" });
execSync(`poetry install${noRoot ? " --no-root" : ""}`, {
stdio: "inherit",
});
return true;
} catch (_) {}
return false;
+5 -3
View File
@@ -92,12 +92,14 @@ export const addDependencies = async (
}
};
export const installPythonDependencies = (root: string) => {
export const installPythonDependencies = (
{ noRoot }: { noRoot: boolean } = { noRoot: false },
) => {
if (isPoetryAvailable()) {
console.log(
`Installing python dependencies using poetry. This may take a while...`,
);
const installSuccessful = tryPoetryInstall();
const installSuccessful = tryPoetryInstall(noRoot);
if (!installSuccessful) {
console.error(
red("Install failed. Please install dependencies manually."),
@@ -181,6 +183,6 @@ export const installPythonTemplate = async ({
await addDependencies(root, addOnDependencies);
if (postInstallAction !== "none") {
installPythonDependencies(root);
installPythonDependencies();
}
};
+8
View File
@@ -61,3 +61,11 @@ export async function getRepoRootFolders(
const folders = data.filter((item) => item.type === "dir");
return folders.map((item) => item.name);
}
export async function getRepoRawContent(repoFilePath: string) {
const url = `https://raw.githubusercontent.com/${repoFilePath}`;
const response = await got(url, {
responseType: "text",
});
return response.body;
}
+3 -1
View File
@@ -1,6 +1,6 @@
import { PackageManager } from "../helpers/get-pkg-manager";
export type TemplateType = "simple" | "streaming" | "community";
export type TemplateType = "simple" | "streaming" | "community" | "llamapack";
export type TemplateFramework = "nextjs" | "express" | "fastapi";
export type TemplateEngine = "simple" | "context";
export type TemplateUI = "html" | "shadcn";
@@ -15,6 +15,7 @@ export interface InstallTemplateArgs {
template: TemplateType;
framework: TemplateFramework;
engine: TemplateEngine;
contextFile?: string;
ui: TemplateUI;
eslint: boolean;
customApiPath?: string;
@@ -22,6 +23,7 @@ export interface InstallTemplateArgs {
forBackend?: string;
model: string;
communityProjectPath?: string;
llamapack?: string;
vectorDb?: TemplateVectorDB;
externalPort?: number;
postInstallAction?: TemplatePostInstallAction;
+2
View File
@@ -237,9 +237,11 @@ async function run(): Promise<void> {
openAiKey: program.openAiKey,
model: program.model,
communityProjectPath: program.communityProjectPath,
llamapack: program.llamapack,
vectorDb: program.vectorDb,
externalPort: program.externalPort,
postInstallAction: program.postInstallAction,
contextFile: program.contextFile,
});
conf.set("preferences", preferences);
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "create-llama",
"version": "0.0.16",
"version": "0.0.19",
"keywords": [
"rag",
"llamaindex",
@@ -17,7 +17,7 @@
"create-llama": "./dist/index.js"
},
"files": [
"./dist/index.js",
"dist",
"./templates"
],
"scripts": {
@@ -29,11 +29,11 @@
"prepublishOnly": "cd ../../ && pnpm run build:release"
},
"devDependencies": {
"@playwright/test": "^1.40.0",
"@playwright/test": "^1.41.1",
"@types/async-retry": "1.4.2",
"@types/ci-info": "2.0.0",
"@types/cross-spawn": "6.0.0",
"@types/node": "^20.9.0",
"@types/node": "^20.11.7",
"@types/prompts": "2.0.1",
"@types/tar": "6.1.5",
"@types/validate-npm-package-name": "3.0.0",
@@ -49,7 +49,7 @@
"picocolors": "1.0.0",
"prompts": "2.1.0",
"rimraf": "^5.0.5",
"smol-toml": "^1.1.3",
"smol-toml": "^1.1.4",
"tar": "6.1.15",
"terminal-link": "^3.0.0",
"update-check": "1.5.4",
+154 -51
View File
@@ -1,14 +1,32 @@
import { execSync } from "child_process";
import ciInfo from "ci-info";
import fs from "fs";
import path from "path";
import { blue, green } from "picocolors";
import { blue, green, red } from "picocolors";
import prompts from "prompts";
import { InstallAppArgs } from "./create-app";
import { TemplateFramework } from "./helpers";
import { COMMUNITY_OWNER, COMMUNITY_REPO } from "./helpers/constant";
import { getAvailableLlamapackOptions } from "./helpers/llama-pack";
import { getRepoRootFolders } from "./helpers/repo";
export type QuestionArgs = Omit<InstallAppArgs, "appPath" | "packageManager">;
const MACOS_FILE_SELECTION_SCRIPT = `
osascript -l JavaScript -e '
a = Application.currentApplication();
a.includeStandardAdditions = true;
a.chooseFile({ withPrompt: "Please select a file to process:" }).toString()
'`;
const WINDOWS_FILE_SELECTION_SCRIPT = `
Add-Type -AssemblyName System.Windows.Forms
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$result = $openFileDialog.ShowDialog()
if ($result -eq 'OK') {
$openFileDialog.FileName
}
`;
const defaults: QuestionArgs = {
template: "streaming",
@@ -20,6 +38,7 @@ const defaults: QuestionArgs = {
openAiKey: "",
model: "gpt-3.5-turbo",
communityProjectPath: "",
llamapack: "",
postInstallAction: "dependencies",
};
@@ -55,6 +74,45 @@ const getVectorDbChoices = (framework: TemplateFramework) => {
return displayedChoices;
};
const selectPDFFile = async () => {
// Popup to select a PDF file
try {
let selectedFilePath: string = "";
switch (process.platform) {
case "win32": // Windows
selectedFilePath = execSync(WINDOWS_FILE_SELECTION_SCRIPT, {
shell: "powershell.exe",
})
.toString()
.trim();
break;
case "darwin": // MacOS
selectedFilePath = execSync(MACOS_FILE_SELECTION_SCRIPT)
.toString()
.trim();
break;
default: // Unsupported OS
console.log(red("Unsupported OS error!"));
process.exit(1);
}
// Check is pdf file
if (!selectedFilePath.endsWith(".pdf")) {
console.log(
red("Unsupported file error! Please select a valid PDF file!"),
);
process.exit(1);
}
return selectedFilePath;
} catch (error) {
console.log(
red(
"Got error when trying to select file! Please try again or select other options.",
),
);
process.exit(1);
}
};
export const onPromptState = (state: any) => {
if (state.aborted) {
// If we don't re-enable the terminal cursor before exiting
@@ -73,6 +131,48 @@ export const askQuestions = async (
field: K,
): QuestionArgs[K] => preferences[field] ?? defaults[field];
// Ask for next action after installation
async function askPostInstallAction() {
if (program.postInstallAction === undefined) {
if (ciInfo.isCI) {
program.postInstallAction = getPrefOrDefault("postInstallAction");
} else {
let actionChoices = [
{
title: "Just generate code (~1 sec)",
value: "none",
},
{
title: "Generate code and install dependencies (~2 min)",
value: "dependencies",
},
];
const hasOpenAiKey = program.openAiKey || process.env["OPENAI_API_KEY"];
if (program.vectorDb === "none" && hasOpenAiKey) {
actionChoices.push({
title:
"Generate code, install dependencies, and run the app (~2 min)",
value: "runApp",
});
}
const { action } = await prompts(
{
type: "select",
name: "action",
message: "How would you like to proceed?",
choices: actionChoices,
initial: 1,
},
handlers,
);
program.postInstallAction = action;
}
}
}
if (!program.template) {
if (ciInfo.isCI) {
program.template = getPrefOrDefault("template");
@@ -92,6 +192,10 @@ export const askQuestions = async (
title: `Community template from ${styledRepo}`,
value: "community",
},
{
title: "Example using a LlamaPack",
value: "llamapack",
},
],
initial: 1,
},
@@ -125,6 +229,27 @@ export const askQuestions = async (
return; // early return - no further questions needed for community projects
}
if (program.template === "llamapack") {
const availableLlamaPacks = await getAvailableLlamapackOptions();
const { llamapack } = await prompts(
{
type: "select",
name: "llamapack",
message: "Select LlamaPack",
choices: availableLlamaPacks.map((pack) => ({
title: pack.name,
value: pack.folderPath,
})),
initial: 0,
},
handlers,
);
program.llamapack = llamapack;
preferences.llamapack = llamapack;
await askPostInstallAction();
return; // early return - no further questions needed for llamapack projects
}
if (!program.framework) {
if (ciInfo.isCI) {
program.framework = getPrefOrDefault("framework");
@@ -243,24 +368,40 @@ export const askQuestions = async (
if (ciInfo.isCI) {
program.engine = getPrefOrDefault("engine");
} else {
const { engine } = await prompts(
let choices = [
{
title: "No data, just a simple chat",
value: "simple",
},
{ title: "Use an example PDF", value: "exampleFile" },
];
if (process.platform === "win32" || process.platform === "darwin") {
choices.push({ title: "Use a local PDF file", value: "localFile" });
}
const { dataSource } = await prompts(
{
type: "select",
name: "engine",
name: "dataSource",
message: "Which data source would you like to use?",
choices: [
{
title: "No data, just a simple chat",
value: "simple",
},
{ title: "Use an example PDF", value: "context" },
],
choices: choices,
initial: 1,
},
handlers,
);
program.engine = engine;
preferences.engine = engine;
switch (dataSource) {
case "simple":
program.engine = "simple";
break;
case "exampleFile":
program.engine = "context";
break;
case "localFile":
program.engine = "context";
// If the user selected the "pdf" option, ask them to select a file
program.contextFile = await selectPDFFile();
break;
}
}
if (program.engine !== "simple" && !program.vectorDb) {
if (ciInfo.isCI) {
@@ -314,45 +455,7 @@ export const askQuestions = async (
}
}
// Ask for next action after installation
if (program.postInstallAction === undefined) {
if (ciInfo.isCI) {
program.postInstallAction = getPrefOrDefault("postInstallAction");
} else {
let actionChoices = [
{
title: "Just generate code (~1 sec)",
value: "none",
},
{
title: "Generate code and install dependencies (~2 min)",
value: "dependencies",
},
];
const hasOpenAiKey = program.openAiKey || process.env["OPENAI_API_KEY"];
if (program.vectorDb === "none" && hasOpenAiKey) {
actionChoices.push({
title:
"Generate code, install dependencies, and run the app (~2 min)",
value: "runApp",
});
}
const { action } = await prompts(
{
type: "select",
name: "action",
message: "How would you like to proceed?",
choices: actionChoices,
initial: 1,
},
handlers,
);
program.postInstallAction = action;
}
}
await askPostInstallAction();
// TODO: consider using zod to validate the input (doesn't work like this as not every option is required)
// templateUISchema.parse(program.ui);
@@ -0,0 +1,16 @@
---
## Quickstart
1. Check above instructions for setting up your environment and export required environment variables
For example, if you are using bash, you can run the following command to set up OpenAI API key
```bash
export OPENAI_API_KEY=your_api_key
```
2. Run the example
```
poetry run python example.py
```
@@ -0,0 +1,16 @@
[tool.poetry]
name = "app"
version = "0.1.0"
description = "Llama Pack Example"
authors = ["Marcus Schiesser <mail@marcusschiesser.de>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11,<3.12"
llama-index = "^0.9.19"
python-dotenv = "^1.0.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
@@ -1,2 +1,3 @@
# local env files
.env
node_modules/
@@ -14,9 +14,6 @@
"express": "^4.18.2",
"llamaindex": "0.0.37"
},
"overrides": {
"chromadb": "1.7.3"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
@@ -1,2 +1,3 @@
# local env files
.env
node_modules/
@@ -15,9 +15,6 @@
"express": "^4.18.2",
"llamaindex": "0.0.37"
},
"overrides": {
"chromadb": "1.7.3"
},
"devDependencies": {
"@types/cors": "^2.8.16",
"@types/express": "^4.17.21",
@@ -27,9 +27,6 @@
"supports-color": "^9.4.0",
"tailwind-merge": "^2.1.0"
},
"overrides": {
"chromadb": "1.7.3"
},
"devDependencies": {
"@types/node": "^20.10.3",
"@types/react": "^18.2.42",
+4 -4
View File
@@ -5,15 +5,15 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"eslint-config-next": "^13.4.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-turbo": "^1.9.3",
"eslint-config-next": "^13.5.6",
"eslint-config-prettier": "^8.10.0",
"eslint-config-turbo": "^1.11.3",
"eslint-plugin-react": "7.28.0"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"next": "^13.4.10"
"next": "^13.5.6"
}
}
+1971 -1888
View File
File diff suppressed because it is too large Load Diff