mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-19 18:43:34 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c4af6a0a8 | |||
| 4eecc5148e |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"create-llama": patch
|
||||
---
|
||||
|
||||
feat(create-llama) add option to select tools (google_search, wikipedia)
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"create-llama": patch
|
||||
---
|
||||
|
||||
Added latest turbo models for GPT-3.5 and GPT 4
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
---
|
||||
|
||||
fix: update `VectorIndexRetriever` constructor parameters' type.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
---
|
||||
|
||||
feat: use batching in vector store index
|
||||
@@ -4,6 +4,6 @@
|
||||
"ghcr.io/devcontainers/features/node:1": {},
|
||||
"ghcr.io/devcontainers-contrib/features/turborepo-npm:1": {},
|
||||
"ghcr.io/devcontainers-contrib/features/typescript:2": {},
|
||||
"ghcr.io/devcontainers-contrib/features/pnpm:2": {}
|
||||
}
|
||||
"ghcr.io/devcontainers-contrib/features/pnpm:2": {},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -49,14 +49,8 @@ jobs:
|
||||
- name: Build create-llama
|
||||
run: pnpm run build
|
||||
working-directory: ./packages/create-llama
|
||||
- name: Pack
|
||||
run: pnpm pack --pack-destination ./output
|
||||
working-directory: ./packages/create-llama
|
||||
- name: Extract Pack
|
||||
run: tar -xvzf ./output/*.tgz -C ./output
|
||||
working-directory: ./packages/create-llama
|
||||
- name: Run Playwright tests
|
||||
run: pnpm exec playwright test
|
||||
run: pnpm run e2e
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
working-directory: ./packages/create-llama
|
||||
|
||||
@@ -38,12 +38,6 @@ jobs:
|
||||
- name: Run Circular Dependency Check
|
||||
run: pnpm run circular-check
|
||||
working-directory: ./packages/core
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: typecheck-build-dist
|
||||
path: ./packages/core/dist
|
||||
if-no-files-found: error
|
||||
typecheck-examples:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
@@ -78,15 +78,3 @@ pnpm start
|
||||
That should start a webserver which will serve the docs on https://localhost:3000
|
||||
|
||||
Any changes you make should be reflected in the browser. If you need to regenerate the API docs and find that your TSDoc isn't getting the updates, feel free to remove apps/docs/api. It will automatically regenerate itself when you run pnpm start again.
|
||||
|
||||
## Publishing
|
||||
|
||||
To publish a new version of the library, run
|
||||
|
||||
```shell
|
||||
pnpm new-llamaindex
|
||||
pnpm new-create-llama
|
||||
pnpm release
|
||||
git push # push to the main branch
|
||||
git push --tags
|
||||
```
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
# OpenAI Agent + QueryEngineTool
|
||||
|
||||
QueryEngineTool is a tool that allows you to query a vector index. In this example, we will create a vector index from a set of documents and then create a QueryEngineTool from the vector index. We will then create an OpenAIAgent with the QueryEngineTool and chat with the agent.
|
||||
|
||||
## Setup
|
||||
|
||||
First, you need to install the `llamaindex` package. You can do this by running the following command in your terminal:
|
||||
|
||||
```bash
|
||||
pnpm i llamaindex
|
||||
```
|
||||
|
||||
Then you can import the necessary classes and functions.
|
||||
|
||||
```ts
|
||||
import {
|
||||
OpenAIAgent,
|
||||
SimpleDirectoryReader,
|
||||
VectorStoreIndex,
|
||||
QueryEngineTool,
|
||||
} from "llamaindex";
|
||||
```
|
||||
|
||||
## Create a vector index
|
||||
|
||||
Now we can create a vector index from a set of documents.
|
||||
|
||||
```ts
|
||||
// Load the documents
|
||||
const documents = await new SimpleDirectoryReader().loadData({
|
||||
directoryPath: "node_modules/llamaindex/examples/",
|
||||
});
|
||||
|
||||
// Create a vector index from the documents
|
||||
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
|
||||
```
|
||||
|
||||
## Create a QueryEngineTool
|
||||
|
||||
Now we can create a QueryEngineTool from the vector index.
|
||||
|
||||
```ts
|
||||
// Create a query engine from the vector index
|
||||
const abramovQueryEngine = vectorIndex.asQueryEngine();
|
||||
|
||||
// Create a QueryEngineTool with the query engine
|
||||
const queryEngineTool = new QueryEngineTool({
|
||||
queryEngine: abramovQueryEngine,
|
||||
metadata: {
|
||||
name: "abramov_query_engine",
|
||||
description: "A query engine for the Abramov documents",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Create an OpenAIAgent
|
||||
|
||||
```ts
|
||||
// Create an OpenAIAgent with the query engine tool tools
|
||||
|
||||
const agent = new OpenAIAgent({
|
||||
tools: [queryEngineTool],
|
||||
verbose: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Chat with the agent
|
||||
|
||||
Now we can chat with the agent.
|
||||
|
||||
```ts
|
||||
const response = await agent.chat({
|
||||
message: "What was his salary?",
|
||||
});
|
||||
|
||||
console.log(String(response));
|
||||
```
|
||||
|
||||
## Full code
|
||||
|
||||
```ts
|
||||
import {
|
||||
OpenAIAgent,
|
||||
SimpleDirectoryReader,
|
||||
VectorStoreIndex,
|
||||
QueryEngineTool,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
// Load the documents
|
||||
const documents = await new SimpleDirectoryReader().loadData({
|
||||
directoryPath: "node_modules/llamaindex/examples/",
|
||||
});
|
||||
|
||||
// Create a vector index from the documents
|
||||
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
// Create a query engine from the vector index
|
||||
const abramovQueryEngine = vectorIndex.asQueryEngine();
|
||||
|
||||
// Create a QueryEngineTool with the query engine
|
||||
const queryEngineTool = new QueryEngineTool({
|
||||
queryEngine: abramovQueryEngine,
|
||||
metadata: {
|
||||
name: "abramov_query_engine",
|
||||
description: "A query engine for the Abramov documents",
|
||||
},
|
||||
});
|
||||
|
||||
// Create an OpenAIAgent with the function tools
|
||||
const agent = new OpenAIAgent({
|
||||
tools: [queryEngineTool],
|
||||
verbose: true,
|
||||
});
|
||||
|
||||
// Chat with the agent
|
||||
const response = await agent.chat({
|
||||
message: "What was his salary?",
|
||||
});
|
||||
|
||||
// Print the response
|
||||
console.log(String(response));
|
||||
}
|
||||
|
||||
main().then(() => {
|
||||
console.log("Done");
|
||||
});
|
||||
```
|
||||
@@ -6,6 +6,6 @@
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo"
|
||||
}
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import {
|
||||
OpenAIAgent,
|
||||
QueryEngineTool,
|
||||
SimpleDirectoryReader,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
// Load the documents
|
||||
const documents = await new SimpleDirectoryReader().loadData({
|
||||
directoryPath: "node_modules/llamaindex/examples/",
|
||||
});
|
||||
|
||||
// Create a vector index from the documents
|
||||
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
// Create a query engine from the vector index
|
||||
const abramovQueryEngine = vectorIndex.asQueryEngine();
|
||||
|
||||
// Create a QueryEngineTool with the query engine
|
||||
const queryEngineTool = new QueryEngineTool({
|
||||
queryEngine: abramovQueryEngine,
|
||||
metadata: {
|
||||
name: "abramov_query_engine",
|
||||
description: "A query engine for the Abramov documents",
|
||||
},
|
||||
});
|
||||
|
||||
// Create an OpenAIAgent with the function tools
|
||||
const agent = new OpenAIAgent({
|
||||
tools: [queryEngineTool],
|
||||
verbose: true,
|
||||
});
|
||||
|
||||
// Chat with the agent
|
||||
const response = await agent.chat({
|
||||
message: "What was his salary?",
|
||||
});
|
||||
|
||||
// Print the response
|
||||
console.log(String(response));
|
||||
}
|
||||
|
||||
main().then(() => {
|
||||
console.log("Done");
|
||||
});
|
||||
@@ -14,27 +14,18 @@ Here are two sample scripts which work well with the sample data in the Astra Po
|
||||
|
||||
- `ASTRA_DB_APPLICATION_TOKEN`: The generated app token for your Astra database
|
||||
- `ASTRA_DB_ENDPOINT`: The API endpoint for your Astra database
|
||||
- `ASTRA_DB_NAMESPACE`: (Optional) The namespace where your collection is stored defaults to `default_keyspace`
|
||||
- `OPENAI_API_KEY`: Your OpenAI key
|
||||
|
||||
2. `cd` Into the `examples` directory
|
||||
3. run `npm i`
|
||||
|
||||
## Example load and query
|
||||
|
||||
Loads and queries a simple vectorstore with some documents about Astra DB
|
||||
|
||||
run `ts-node astradb/example`
|
||||
|
||||
## Movie Reviews Example
|
||||
|
||||
### Load the data
|
||||
## Load the data
|
||||
|
||||
This sample loads the same dataset of movie reviews as the Astra Portal sample dataset. (Feel free to load the data in your the Astra Data Explorer to compare)
|
||||
|
||||
run `ts-node astradb/load`
|
||||
|
||||
### Use RAG to Query the data
|
||||
## Use RAG to Query the data
|
||||
|
||||
Check out your data in the Astra Data Explorer and change the sample query as you see fit.
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import {
|
||||
AstraDBVectorStore,
|
||||
Document,
|
||||
storageContextFromDefaults,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
|
||||
const collectionName = "test_collection";
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const docs = [
|
||||
new Document({
|
||||
text: "AstraDB is built on Apache Cassandra",
|
||||
metadata: {
|
||||
id: 123,
|
||||
foo: "bar",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
text: "AstraDB is a NoSQL DB",
|
||||
metadata: {
|
||||
id: 456,
|
||||
foo: "baz",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
text: "AstraDB supports vector search",
|
||||
metadata: {
|
||||
id: 789,
|
||||
foo: "qux",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const astraVS = new AstraDBVectorStore();
|
||||
await astraVS.create(collectionName, {
|
||||
vector: { dimension: 1536, metric: "cosine" },
|
||||
});
|
||||
await astraVS.connect(collectionName);
|
||||
|
||||
const ctx = await storageContextFromDefaults({ vectorStore: astraVS });
|
||||
const index = await VectorStoreIndex.fromDocuments(docs, {
|
||||
storageContext: ctx,
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const response = await queryEngine.query({
|
||||
query: "Describe AstraDB.",
|
||||
});
|
||||
|
||||
console.log(response.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -10,9 +10,9 @@ const collectionName = "movie_reviews";
|
||||
async function main() {
|
||||
try {
|
||||
const reader = new PapaCSVReader(false);
|
||||
const docs = await reader.loadData("./data/movie_reviews.csv");
|
||||
const docs = await reader.loadData("../data/movie_reviews.csv");
|
||||
|
||||
const astraVS = new AstraDBVectorStore({ contentKey: "reviewtext" });
|
||||
const astraVS = new AstraDBVectorStore();
|
||||
await astraVS.create(collectionName, {
|
||||
vector: { dimension: 1536, metric: "cosine" },
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ const collectionName = "movie_reviews";
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const astraVS = new AstraDBVectorStore({ contentKey: "reviewtext" });
|
||||
const astraVS = new AstraDBVectorStore();
|
||||
await astraVS.connect(collectionName);
|
||||
|
||||
const ctx = serviceContextFromDefaults();
|
||||
@@ -19,7 +19,7 @@ async function main() {
|
||||
const queryEngine = await index.asQueryEngine({ retriever });
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query: 'How was "La Sapienza" reviewed?',
|
||||
query: "What is the best reviewed movie?",
|
||||
});
|
||||
|
||||
console.log(results.response);
|
||||
|
||||
+10
-17
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
Document,
|
||||
QueryEngineTool,
|
||||
SubQuestionQueryEngine,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import { Document, SubQuestionQueryEngine, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
import essay from "./essay";
|
||||
|
||||
@@ -11,18 +6,16 @@ import essay from "./essay";
|
||||
const document = new Document({ text: essay, id_: essay });
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngineTools = [
|
||||
new QueryEngineTool({
|
||||
queryEngine: index.asQueryEngine(),
|
||||
metadata: {
|
||||
name: "pg_essay",
|
||||
description: "Paul Graham essay on What I Worked On",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const queryEngine = SubQuestionQueryEngine.fromDefaults({
|
||||
queryEngineTools,
|
||||
queryEngineTools: [
|
||||
{
|
||||
queryEngine: index.asQueryEngine(),
|
||||
metadata: {
|
||||
name: "pg_essay",
|
||||
description: "Paul Graham essay on What I Worked On",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const response = await queryEngine.query({
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
"incremental": true,
|
||||
"composite": true
|
||||
"composite": true,
|
||||
},
|
||||
"ts-node": {
|
||||
"files": true,
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
"module": "commonjs",
|
||||
},
|
||||
},
|
||||
"include": ["./**/*.ts"]
|
||||
"include": ["./**/*.ts"],
|
||||
}
|
||||
|
||||
+7
-7
@@ -18,20 +18,20 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"@turbo/gen": "^1.12.2",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@turbo/gen": "^1.11.3",
|
||||
"@types/jest": "^29.5.11",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"husky": "^9.0.10",
|
||||
"husky": "^9.0.6",
|
||||
"jest": "^29.7.0",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"lint-staged": "^15.2.0",
|
||||
"prettier": "^3.2.4",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"ts-jest": "^29.1.2",
|
||||
"turbo": "^1.12.2",
|
||||
"turbo": "^1.11.3",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"packageManager": "pnpm@8.15.1",
|
||||
"packageManager": "pnpm@8.14.3+sha256.2d0363bb6c314daa67087ef07743eea1ba2e2d360c835e8fec6b5575e4ed9484",
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"trim": "1.0.1",
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
# llamaindex
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b6c1500: feat(embedBatchSize): add batching for embeddings
|
||||
- 6cc3a36: fix: update `VectorIndexRetriever` constructor parameters' type.
|
||||
- cd82947: feat(queryEngineTool): add query engine tool to agents
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 09464e6: add OpenAIAgent (thanks @EmanuelCampos)
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+19
-14
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"name": "llamaindex",
|
||||
"private": true,
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.8",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.13.0",
|
||||
"@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.3",
|
||||
"@qdrant/js-client-rest": "^1.7.0",
|
||||
"@xenova/transformers": "^2.15.0",
|
||||
"assemblyai": "^4.2.2",
|
||||
"@xenova/transformers": "^2.14.1",
|
||||
"assemblyai": "^4.2.1",
|
||||
"chromadb": "~1.7.3",
|
||||
"file-type": "^18.7.0",
|
||||
"js-tiktoken": "^1.0.10",
|
||||
"js-tiktoken": "^1.0.8",
|
||||
"lodash": "^4.17.21",
|
||||
"mammoth": "^1.6.0",
|
||||
"md-utils-ts": "^2.0.0",
|
||||
"mongodb": "^6.3.0",
|
||||
"notion-md-crawler": "^0.0.2",
|
||||
"openai": "^4.26.1",
|
||||
"openai": "^4.26.0",
|
||||
"papaparse": "^5.4.1",
|
||||
"pathe": "^1.1.2",
|
||||
"pdf2json": "^3.0.5",
|
||||
@@ -29,18 +29,18 @@
|
||||
"portkey-ai": "^0.1.16",
|
||||
"rake-modified": "^1.0.8",
|
||||
"replicate": "^0.25.2",
|
||||
"string-strip-html": "^13.4.6",
|
||||
"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.12",
|
||||
"@types/jest": "^29.5.11",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^18.19.14",
|
||||
"@types/node": "^18.19.10",
|
||||
"@types/papaparse": "^5.3.14",
|
||||
"@types/pg": "^8.11.0",
|
||||
"bunchee": "^4.4.6",
|
||||
"bunchee": "^4.4.3",
|
||||
"edit-json-file": "^1.8.0",
|
||||
"madge": "^6.1.0",
|
||||
"typescript": "^5.3.3"
|
||||
@@ -118,6 +118,11 @@
|
||||
"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",
|
||||
@@ -128,10 +133,10 @@
|
||||
"import": "./dist/TextSplitter.mjs",
|
||||
"require": "./dist/TextSplitter.js"
|
||||
},
|
||||
"./tools": {
|
||||
"types": "./dist/tools.d.mts",
|
||||
"import": "./dist/tools.mjs",
|
||||
"require": "./dist/tools.js"
|
||||
"./Tool": {
|
||||
"types": "./dist/Tool.d.mts",
|
||||
"import": "./dist/Tool.mjs",
|
||||
"require": "./dist/Tool.js"
|
||||
},
|
||||
"./readers/AssemblyAIReader": {
|
||||
"types": "./dist/readers/AssemblyAIReader.d.mts",
|
||||
|
||||
@@ -266,14 +266,7 @@ export class AgentRunner extends BaseAgentRunner {
|
||||
let resultOutput;
|
||||
|
||||
while (true) {
|
||||
const curStepOutput = await this._runStep(
|
||||
task.taskId,
|
||||
undefined,
|
||||
ChatResponseMode.WAIT,
|
||||
{
|
||||
toolChoice,
|
||||
},
|
||||
);
|
||||
const curStepOutput = await this._runStep(task.taskId);
|
||||
|
||||
if (curStepOutput.isLast) {
|
||||
resultOutput = curStepOutput;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Anthropic } from "@anthropic-ai/sdk";
|
||||
import { NodeWithScore } from "../Node";
|
||||
|
||||
/*
|
||||
@@ -40,7 +39,14 @@ export interface DefaultStreamToken {
|
||||
//OpenAI stream token schema is the default.
|
||||
//Note: Anthropic and Replicate also use similar token schemas.
|
||||
export type OpenAIStreamToken = DefaultStreamToken;
|
||||
export type AnthropicStreamToken = Anthropic.Completion;
|
||||
export type AnthropicStreamToken = {
|
||||
completion: string;
|
||||
model: string;
|
||||
stop_reason: string | undefined;
|
||||
stop?: boolean | undefined;
|
||||
log_id?: string;
|
||||
};
|
||||
|
||||
//
|
||||
//Callback Responses
|
||||
//
|
||||
|
||||
@@ -36,7 +36,7 @@ export class HuggingFaceEmbedding extends BaseEmbedding {
|
||||
return this.extractor;
|
||||
}
|
||||
|
||||
override async getTextEmbedding(text: string): Promise<number[]> {
|
||||
async getTextEmbedding(text: string): Promise<number[]> {
|
||||
const extractor = await this.getExtractor();
|
||||
const output = await extractor(text, { pooling: "mean", normalize: true });
|
||||
return Array.from(output.data);
|
||||
|
||||
@@ -59,9 +59,7 @@ export class OpenAIEmbedding extends BaseEmbedding {
|
||||
this.model = init?.model ?? "text-embedding-ada-002";
|
||||
this.dimensions = init?.dimensions; // if no dimensions provided, will be undefined/not sent to OpenAI
|
||||
|
||||
this.embedBatchSize = init?.embedBatchSize ?? 10;
|
||||
this.maxRetries = init?.maxRetries ?? 10;
|
||||
|
||||
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
|
||||
this.additionalSessionOptions = init?.additionalSessionOptions;
|
||||
|
||||
@@ -102,43 +100,21 @@ export class OpenAIEmbedding extends BaseEmbedding {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
* @param options
|
||||
*/
|
||||
private async getOpenAIEmbedding(input: string[]): Promise<number[][]> {
|
||||
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,
|
||||
});
|
||||
|
||||
return data.map((d) => d.embedding);
|
||||
return data[0].embedding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
*/
|
||||
async getTextEmbeddings(texts: string[]): Promise<number[][]> {
|
||||
return await this.getOpenAIEmbedding(texts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a single text
|
||||
* @param texts
|
||||
*/
|
||||
async getTextEmbedding(text: string): Promise<number[]> {
|
||||
return (await this.getOpenAIEmbedding([text]))[0];
|
||||
return this.getOpenAIEmbedding(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a query
|
||||
* @param texts
|
||||
* @param options
|
||||
*/
|
||||
async getQueryEmbedding(query: string): Promise<number[]> {
|
||||
return (await this.getOpenAIEmbedding([query]))[0];
|
||||
return this.getOpenAIEmbedding(query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ import { BaseNode, MetadataMode } from "../Node";
|
||||
import { TransformComponent } from "../ingestion";
|
||||
import { SimilarityType, similarity } from "./utils";
|
||||
|
||||
const DEFAULT_EMBED_BATCH_SIZE = 10;
|
||||
|
||||
export abstract class BaseEmbedding implements TransformComponent {
|
||||
embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
|
||||
|
||||
similarity(
|
||||
embedding1: number[],
|
||||
embedding2: number[],
|
||||
@@ -18,66 +14,12 @@ export abstract class BaseEmbedding implements TransformComponent {
|
||||
abstract getTextEmbedding(text: string): Promise<number[]>;
|
||||
abstract getQueryEmbedding(query: string): Promise<number[]>;
|
||||
|
||||
/**
|
||||
* Optionally override this method to retrieve multiple embeddings in a single request
|
||||
* @param texts
|
||||
*/
|
||||
async getTextEmbeddings(texts: string[]): Promise<Array<number[]>> {
|
||||
const embeddings: number[][] = [];
|
||||
|
||||
for (const text of texts) {
|
||||
const embedding = await this.getTextEmbedding(text);
|
||||
embeddings.push(embedding);
|
||||
}
|
||||
|
||||
return embeddings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
* @param options
|
||||
*/
|
||||
async getTextEmbeddingsBatch(
|
||||
texts: string[],
|
||||
options?: {
|
||||
logProgress?: boolean;
|
||||
},
|
||||
): Promise<Array<number[]>> {
|
||||
const resultEmbeddings: Array<number[]> = [];
|
||||
const chunkSize = this.embedBatchSize;
|
||||
|
||||
const queue: string[] = texts;
|
||||
|
||||
const curBatch: string[] = [];
|
||||
|
||||
for (let i = 0; i < queue.length; i++) {
|
||||
curBatch.push(queue[i]);
|
||||
if (i == queue.length - 1 || curBatch.length == chunkSize) {
|
||||
const embeddings = await this.getTextEmbeddings(curBatch);
|
||||
|
||||
resultEmbeddings.push(...embeddings);
|
||||
|
||||
if (options?.logProgress) {
|
||||
console.log(`getting embedding progress: ${i} / ${queue.length}`);
|
||||
}
|
||||
|
||||
curBatch.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return resultEmbeddings;
|
||||
}
|
||||
|
||||
async transform(nodes: BaseNode[], _options?: any): Promise<BaseNode[]> {
|
||||
const texts = nodes.map((node) => node.getContent(MetadataMode.EMBED));
|
||||
|
||||
const embeddings = await this.getTextEmbeddingsBatch(texts);
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
nodes[i].embedding = embeddings[i];
|
||||
for (const node of nodes) {
|
||||
node.embedding = await this.getTextEmbedding(
|
||||
node.getContent(MetadataMode.EMBED),
|
||||
);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
} from "../../synthesizers";
|
||||
import {
|
||||
BaseQueryEngine,
|
||||
BaseTool,
|
||||
QueryEngineParamsNonStreaming,
|
||||
QueryEngineParamsStreaming,
|
||||
QueryEngineTool,
|
||||
ToolMetadata,
|
||||
} from "../../types";
|
||||
import { BaseQuestionGenerator, SubQuestion } from "./types";
|
||||
@@ -27,23 +27,28 @@ import { BaseQuestionGenerator, SubQuestion } from "./types";
|
||||
export class SubQuestionQueryEngine implements BaseQueryEngine {
|
||||
responseSynthesizer: BaseSynthesizer;
|
||||
questionGen: BaseQuestionGenerator;
|
||||
queryEngines: BaseTool[];
|
||||
queryEngines: Record<string, BaseQueryEngine>;
|
||||
metadatas: ToolMetadata[];
|
||||
|
||||
constructor(init: {
|
||||
questionGen: BaseQuestionGenerator;
|
||||
responseSynthesizer: BaseSynthesizer;
|
||||
queryEngineTools: BaseTool[];
|
||||
queryEngineTools: QueryEngineTool[];
|
||||
}) {
|
||||
this.questionGen = init.questionGen;
|
||||
this.responseSynthesizer =
|
||||
init.responseSynthesizer ?? new ResponseSynthesizer();
|
||||
this.queryEngines = init.queryEngineTools;
|
||||
this.queryEngines = init.queryEngineTools.reduce<
|
||||
Record<string, BaseQueryEngine>
|
||||
>((acc, tool) => {
|
||||
acc[tool.metadata.name] = tool.queryEngine;
|
||||
return acc;
|
||||
}, {});
|
||||
this.metadatas = init.queryEngineTools.map((tool) => tool.metadata);
|
||||
}
|
||||
|
||||
static fromDefaults(init: {
|
||||
queryEngineTools: BaseTool[];
|
||||
queryEngineTools: QueryEngineTool[];
|
||||
questionGen?: BaseQuestionGenerator;
|
||||
responseSynthesizer?: BaseSynthesizer;
|
||||
serviceContext?: ServiceContext;
|
||||
@@ -117,24 +122,13 @@ export class SubQuestionQueryEngine implements BaseQueryEngine {
|
||||
): Promise<NodeWithScore | null> {
|
||||
try {
|
||||
const question = subQ.subQuestion;
|
||||
const queryEngine = this.queryEngines[subQ.toolName];
|
||||
|
||||
const queryEngine = this.queryEngines.find(
|
||||
(tool) => tool.metadata.name === subQ.toolName,
|
||||
);
|
||||
|
||||
if (!queryEngine) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const responseText = await queryEngine?.call?.({
|
||||
const response = await queryEngine.query({
|
||||
query: question,
|
||||
parentEvent,
|
||||
});
|
||||
|
||||
if (!responseText) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const responseText = response.response;
|
||||
const nodeText = `Sub question: ${question}\nResponse: ${responseText}`;
|
||||
const node = new TextNode({ text: nodeText });
|
||||
return { node, score: 0 };
|
||||
|
||||
@@ -166,14 +166,20 @@ export class VectorStoreIndex extends BaseIndex<IndexDict> {
|
||||
nodes: BaseNode[],
|
||||
options?: { logProgress?: boolean },
|
||||
): Promise<BaseNode[]> {
|
||||
const texts = nodes.map((node) => node.getContent(MetadataMode.EMBED));
|
||||
const embeddings = await this.embedModel.getTextEmbeddingsBatch(texts, {
|
||||
logProgress: options?.logProgress,
|
||||
});
|
||||
return nodes.map((node, i) => {
|
||||
node.embedding = embeddings[i];
|
||||
return node;
|
||||
});
|
||||
const nodesWithEmbeddings: BaseNode[] = [];
|
||||
|
||||
for (let i = 0; i < nodes.length; ++i) {
|
||||
const node = nodes[i];
|
||||
if (options?.logProgress) {
|
||||
console.log(`Getting embedding for node ${i + 1}/${nodes.length}`);
|
||||
}
|
||||
node.embedding = await this.embedModel.getTextEmbedding(
|
||||
node.getContent(MetadataMode.EMBED),
|
||||
);
|
||||
nodesWithEmbeddings.push(node);
|
||||
}
|
||||
|
||||
return nodesWithEmbeddings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,11 +42,7 @@ export class NotionReader implements BaseReader {
|
||||
toDocuments(pages: Pages): Document[] {
|
||||
return Object.values(pages).map((page) => {
|
||||
const text = pageToString(page);
|
||||
return new Document({
|
||||
id_: page.metadata.id, // Use the Notion-provided UUID for the document
|
||||
text,
|
||||
metadata: page.metadata,
|
||||
});
|
||||
return new Document({ text, metadata: page.metadata });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { AstraDB } from "@datastax/astra-db-ts";
|
||||
import { Collection } from "@datastax/astra-db-ts/dist/collections";
|
||||
import { CreateCollectionOptions } from "@datastax/astra-db-ts/dist/collections/options";
|
||||
import { BaseNode, MetadataMode } from "../../Node";
|
||||
import { BaseNode, Document, MetadataMode } from "../../Node";
|
||||
import { VectorStore, VectorStoreQuery, VectorStoreQueryResult } from "./types";
|
||||
import { metadataDictToNode, nodeToMetadata } from "./utils";
|
||||
|
||||
const MAX_INSERT_BATCH_SIZE = 20;
|
||||
|
||||
@@ -13,7 +12,7 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
|
||||
astraDBClient: AstraDB;
|
||||
idKey: string;
|
||||
contentKey: string;
|
||||
contentKey: string | undefined; // if undefined the entirety of the node aside from the id and embedding will be stored as content
|
||||
metadataKey: string;
|
||||
|
||||
private collection: Collection | undefined;
|
||||
@@ -23,7 +22,6 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
params?: {
|
||||
token: string;
|
||||
endpoint: string;
|
||||
namespace: string;
|
||||
};
|
||||
},
|
||||
) {
|
||||
@@ -42,15 +40,11 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
if (!endpoint) {
|
||||
throw new Error("Must specify ASTRA_DB_ENDPOINT via env variable.");
|
||||
}
|
||||
const namespace =
|
||||
init?.params?.namespace ??
|
||||
process.env.ASTRA_DB_NAMESPACE ??
|
||||
"default_keyspace";
|
||||
this.astraDBClient = new AstraDB(token, endpoint, namespace);
|
||||
this.astraDBClient = new AstraDB(token, endpoint);
|
||||
}
|
||||
|
||||
this.idKey = init?.idKey ?? "_id";
|
||||
this.contentKey = init?.contentKey ?? "content";
|
||||
this.contentKey = init?.contentKey;
|
||||
this.metadataKey = init?.metadataKey ?? "metadata";
|
||||
}
|
||||
|
||||
@@ -108,20 +102,12 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
if (!nodes || nodes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const dataToInsert = nodes.map((node) => {
|
||||
const metadata = nodeToMetadata(
|
||||
node,
|
||||
true,
|
||||
this.contentKey,
|
||||
this.flatMetadata,
|
||||
);
|
||||
|
||||
return {
|
||||
_id: node.id_,
|
||||
$vector: node.getEmbedding(),
|
||||
[this.idKey]: node.id_,
|
||||
[this.contentKey]: node.getContent(MetadataMode.NONE),
|
||||
[this.metadataKey]: metadata,
|
||||
content: node.getContent(MetadataMode.ALL),
|
||||
metadata: node.metadata,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -136,10 +122,11 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
|
||||
for (const batch of batchData) {
|
||||
console.debug(`Inserting batch of size ${batch.length}`);
|
||||
await collection.insertMany(batch);
|
||||
|
||||
const result = await collection.insertMany(batch);
|
||||
}
|
||||
|
||||
return dataToInsert.map((node) => node?.[this.idKey] as string);
|
||||
return dataToInsert.map((node) => node._id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,24 +185,27 @@ export class AstraDBVectorStore implements VectorStore {
|
||||
const similarities: number[] = [];
|
||||
|
||||
await cursor.forEach(async (row: Record<string, any>) => {
|
||||
const {
|
||||
$vector: embedding,
|
||||
$similarity: similarity,
|
||||
[this.idKey]: id,
|
||||
[this.contentKey]: content,
|
||||
[this.metadataKey]: metadata = {},
|
||||
...rest
|
||||
} = row;
|
||||
const id = row[this.idKey];
|
||||
const embedding = row.$vector;
|
||||
const similarity = row.$similarity;
|
||||
const metadata = row[this.metadataKey];
|
||||
|
||||
const node = metadataDictToNode(metadata, {
|
||||
fallback: {
|
||||
id,
|
||||
text: content,
|
||||
metadata,
|
||||
...rest,
|
||||
},
|
||||
// Remove fields from content
|
||||
delete row[this.idKey];
|
||||
delete row.$similarity;
|
||||
delete row.$vector;
|
||||
delete row[this.metadataKey];
|
||||
|
||||
const content = this.contentKey
|
||||
? row[this.contentKey]
|
||||
: JSON.stringify(row);
|
||||
|
||||
const node = new Document({
|
||||
id_: id,
|
||||
text: content,
|
||||
metadata: metadata ?? {},
|
||||
embedding: embedding,
|
||||
});
|
||||
node.setContent(content);
|
||||
|
||||
ids.push(id);
|
||||
similarities.push(similarity);
|
||||
|
||||
@@ -36,16 +36,7 @@ export function nodeToMetadata(
|
||||
return metadata;
|
||||
}
|
||||
|
||||
type MetadataDictToNodeOptions = {
|
||||
// If the metadata doesn't contain node content, use this object as a fallback, for usage see
|
||||
// AstraDBVectorStore.ts
|
||||
fallback: Record<string, any>;
|
||||
};
|
||||
|
||||
export function metadataDictToNode(
|
||||
metadata: Metadata,
|
||||
options?: MetadataDictToNodeOptions,
|
||||
): BaseNode {
|
||||
export function metadataDictToNode(metadata: Metadata): BaseNode {
|
||||
const {
|
||||
_node_content: nodeContent,
|
||||
_node_type: nodeType,
|
||||
@@ -54,17 +45,11 @@ export function metadataDictToNode(
|
||||
ref_doc_id,
|
||||
...rest
|
||||
} = metadata;
|
||||
let nodeObj;
|
||||
if (!nodeContent) {
|
||||
if (options?.fallback) {
|
||||
nodeObj = options?.fallback;
|
||||
} else {
|
||||
throw new Error("Node content not found in metadata.");
|
||||
}
|
||||
} else {
|
||||
nodeObj = JSON.parse(nodeContent);
|
||||
nodeObj.metadata = rest;
|
||||
throw new Error("Node content not found in metadata.");
|
||||
}
|
||||
const nodeObj = JSON.parse(nodeContent);
|
||||
nodeObj.metadata = rest;
|
||||
|
||||
// Note: we're using the name of the class stored in `_node_type`
|
||||
// and not the type attribute to reconstruct
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
import { OpenAIEmbedding, similarity, SimilarityType } from "../embeddings";
|
||||
import { mockEmbeddingModel } from "./utility/mockOpenAI";
|
||||
|
||||
// Mock the OpenAI getOpenAISession function during testing
|
||||
jest.mock("../llm/open_ai", () => {
|
||||
return {
|
||||
getOpenAISession: jest.fn().mockImplementation(() => null),
|
||||
};
|
||||
});
|
||||
import { similarity, SimilarityType } from "../embeddings";
|
||||
|
||||
describe("similarity", () => {
|
||||
test("throws error on mismatched lengths", () => {
|
||||
@@ -50,32 +42,3 @@ describe("similarity", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("[OpenAIEmbedding]", () => {
|
||||
let embedModel: OpenAIEmbedding;
|
||||
|
||||
beforeAll(() => {
|
||||
let openAIEmbedding = new OpenAIEmbedding();
|
||||
|
||||
mockEmbeddingModel(openAIEmbedding);
|
||||
|
||||
embedModel = openAIEmbedding;
|
||||
});
|
||||
|
||||
test("getTextEmbedding", async () => {
|
||||
const embedding = await embedModel.getTextEmbedding("hello");
|
||||
expect(embedding.length).toEqual(6);
|
||||
});
|
||||
|
||||
test("getTextEmbeddings", async () => {
|
||||
const texts = ["hello", "world"];
|
||||
const embeddings = await embedModel.getTextEmbeddings(texts);
|
||||
expect(embeddings.length).toEqual(1);
|
||||
});
|
||||
|
||||
test("getTextEmbeddingsBatch", async () => {
|
||||
const texts = ["hello", "world"];
|
||||
const embeddings = await embedModel.getTextEmbeddingsBatch(texts);
|
||||
expect(embeddings.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,11 +90,6 @@ export function mockEmbeddingModel(embedModel: OpenAIEmbedding) {
|
||||
resolve([1, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
});
|
||||
jest.spyOn(embedModel, "getTextEmbeddings").mockImplementation(async (x) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve([[1, 0, 0, 0, 0, 0]]);
|
||||
});
|
||||
});
|
||||
jest.spyOn(embedModel, "getQueryEmbedding").mockImplementation(async (x) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve([0, 1, 0, 0, 0, 0]);
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { BaseQueryEngine, BaseTool, ToolMetadata } from "../types";
|
||||
|
||||
export type QueryEngineToolParams = {
|
||||
queryEngine: BaseQueryEngine;
|
||||
metadata: ToolMetadata;
|
||||
};
|
||||
|
||||
type QueryEngineCallParams = {
|
||||
query: string;
|
||||
};
|
||||
|
||||
const DEFAULT_NAME = "query_engine_tool";
|
||||
const DEFAULT_DESCRIPTION =
|
||||
"Useful for running a natural language query against a knowledge base and get back a natural language response.";
|
||||
const DEFAULT_PARAMETERS = {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: {
|
||||
type: "string",
|
||||
description: "The query to search for",
|
||||
},
|
||||
},
|
||||
required: ["query"],
|
||||
};
|
||||
|
||||
export class QueryEngineTool implements BaseTool {
|
||||
private queryEngine: BaseQueryEngine;
|
||||
metadata: ToolMetadata;
|
||||
|
||||
constructor({ queryEngine, metadata }: QueryEngineToolParams) {
|
||||
this.queryEngine = queryEngine;
|
||||
this.metadata = {
|
||||
name: metadata?.name ?? DEFAULT_NAME,
|
||||
description: metadata?.description ?? DEFAULT_DESCRIPTION,
|
||||
parameters: metadata?.parameters ?? DEFAULT_PARAMETERS,
|
||||
};
|
||||
}
|
||||
|
||||
async call(...args: QueryEngineCallParams[]): Promise<any> {
|
||||
let queryStr: string;
|
||||
|
||||
if (args && args.length > 0) {
|
||||
queryStr = String(args[0].query);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Cannot call query engine without specifying `input` parameter.",
|
||||
);
|
||||
}
|
||||
|
||||
const response = await this.queryEngine.query({ query: queryStr });
|
||||
|
||||
return response.response;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from "./QueryEngineTool";
|
||||
export * from "./functionTool";
|
||||
export * from "./types";
|
||||
|
||||
@@ -40,6 +40,13 @@ export interface BaseTool {
|
||||
metadata: ToolMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Tool that uses a QueryEngine.
|
||||
*/
|
||||
export interface QueryEngineTool extends BaseTool {
|
||||
queryEngine: BaseQueryEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* An OutputParser is used to extract structured data from the raw output of the LLM.
|
||||
*/
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
"strict": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"target": "ES2015",
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules"]
|
||||
"exclude": ["node_modules"],
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import path from "path";
|
||||
import { green, yellow } from "picocolors";
|
||||
import { green } from "picocolors";
|
||||
import { tryGitInit } from "./helpers/git";
|
||||
import { isFolderEmpty } from "./helpers/is-folder-empty";
|
||||
import { getOnline } from "./helpers/is-online";
|
||||
@@ -12,7 +12,6 @@ import terminalLink from "terminal-link";
|
||||
import type { InstallTemplateArgs } from "./helpers";
|
||||
import { installTemplate } from "./helpers";
|
||||
import { templatesDir } from "./helpers/dir";
|
||||
import { toolsRequireConfig } from "./helpers/tools";
|
||||
|
||||
export type InstallAppArgs = Omit<
|
||||
InstallTemplateArgs,
|
||||
@@ -39,7 +38,6 @@ export async function createApp({
|
||||
externalPort,
|
||||
postInstallAction,
|
||||
dataSource,
|
||||
tools,
|
||||
}: InstallAppArgs): Promise<void> {
|
||||
const root = path.resolve(appPath);
|
||||
|
||||
@@ -84,7 +82,6 @@ export async function createApp({
|
||||
externalPort,
|
||||
postInstallAction,
|
||||
dataSource,
|
||||
tools,
|
||||
};
|
||||
|
||||
if (frontend) {
|
||||
@@ -117,17 +114,6 @@ export async function createApp({
|
||||
console.log();
|
||||
}
|
||||
|
||||
if (toolsRequireConfig(tools)) {
|
||||
console.log(
|
||||
yellow(
|
||||
`You have selected tools that require configuration. Please configure them in the ${terminalLink(
|
||||
"tools_config.json",
|
||||
`file://${root}/tools_config.json`,
|
||||
)} file.`,
|
||||
),
|
||||
);
|
||||
}
|
||||
console.log("");
|
||||
console.log(`${green("Success!")} Created ${appName} at ${appPath}`);
|
||||
|
||||
console.log(
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo"
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
},
|
||||
"include": ["./**/*.ts"]
|
||||
"include": ["./**/*.ts"],
|
||||
}
|
||||
|
||||
@@ -74,15 +74,6 @@ export async function runCreateLlama(
|
||||
externalPort: number,
|
||||
postInstallAction: TemplatePostInstallAction,
|
||||
): Promise<CreateLlamaResult> {
|
||||
const createLlama = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"output",
|
||||
"package",
|
||||
"dist",
|
||||
"index.js",
|
||||
);
|
||||
|
||||
const name = [
|
||||
templateType,
|
||||
templateFramework,
|
||||
@@ -91,8 +82,8 @@ export async function runCreateLlama(
|
||||
appType,
|
||||
].join("-");
|
||||
const command = [
|
||||
"node",
|
||||
createLlama,
|
||||
"npx",
|
||||
"create-llama",
|
||||
name,
|
||||
"--template",
|
||||
templateType,
|
||||
@@ -117,8 +108,6 @@ export async function runCreateLlama(
|
||||
externalPort,
|
||||
"--post-install-action",
|
||||
postInstallAction,
|
||||
"--tools",
|
||||
"none",
|
||||
].join(" ");
|
||||
console.log(`running command '${command}' in ${cwd}`);
|
||||
let appProcess = exec(command, {
|
||||
|
||||
@@ -6,7 +6,6 @@ import terminalLink from "terminal-link";
|
||||
import { copy } from "./copy";
|
||||
import { templatesDir } from "./dir";
|
||||
import { isPoetryAvailable, tryPoetryInstall } from "./poetry";
|
||||
import { getToolConfig } from "./tools";
|
||||
import { InstallTemplateArgs, TemplateVectorDB } from "./types";
|
||||
|
||||
interface Dependency {
|
||||
@@ -129,7 +128,6 @@ export const installPythonTemplate = async ({
|
||||
engine,
|
||||
vectorDb,
|
||||
dataSource,
|
||||
tools,
|
||||
postInstallAction,
|
||||
}: Pick<
|
||||
InstallTemplateArgs,
|
||||
@@ -139,7 +137,6 @@ export const installPythonTemplate = async ({
|
||||
| "engine"
|
||||
| "vectorDb"
|
||||
| "dataSource"
|
||||
| "tools"
|
||||
| "postInstallAction"
|
||||
>) => {
|
||||
console.log("\nInitializing Python project with template:", template, "\n");
|
||||
@@ -165,44 +162,20 @@ export const installPythonTemplate = async ({
|
||||
});
|
||||
|
||||
if (engine === "context") {
|
||||
const enginePath = path.join(root, "app", "engine");
|
||||
const compPath = path.join(templatesDir, "components");
|
||||
|
||||
const vectorDbDirName = vectorDb ?? "none";
|
||||
let vectorDbDirName = vectorDb ?? "none";
|
||||
const VectorDBPath = path.join(
|
||||
compPath,
|
||||
"vectordbs",
|
||||
"python",
|
||||
vectorDbDirName,
|
||||
);
|
||||
await copy("**", enginePath, {
|
||||
const enginePath = path.join(root, "app", "engine");
|
||||
await copy("**", path.join(root, "app", "engine"), {
|
||||
parents: true,
|
||||
cwd: VectorDBPath,
|
||||
});
|
||||
|
||||
// Copy engine code
|
||||
if (tools !== undefined && tools.length > 0) {
|
||||
await copy("**", enginePath, {
|
||||
parents: true,
|
||||
cwd: path.join(compPath, "engines", "python", "agent"),
|
||||
});
|
||||
// Write tools_config.json
|
||||
const configContent: Record<string, any> = {};
|
||||
tools.forEach((tool) => {
|
||||
configContent[tool] = getToolConfig(tool) ?? {};
|
||||
});
|
||||
const configFilePath = path.join(root, "tools_config.json");
|
||||
await fs.writeFile(
|
||||
configFilePath,
|
||||
JSON.stringify(configContent, null, 2),
|
||||
);
|
||||
} else {
|
||||
await copy("**", enginePath, {
|
||||
parents: true,
|
||||
cwd: path.join(compPath, "engines", "python", "chat"),
|
||||
});
|
||||
}
|
||||
|
||||
const dataSourceType = dataSource?.type;
|
||||
if (dataSourceType !== undefined && dataSourceType !== "none") {
|
||||
let loaderPath =
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
export type Tool = {
|
||||
display: string;
|
||||
name: string;
|
||||
config?: Record<string, any>;
|
||||
};
|
||||
|
||||
export const supportedTools: Tool[] = [
|
||||
{
|
||||
display: "Google Search (configuration required after installation)",
|
||||
name: "google_search",
|
||||
config: {
|
||||
engine:
|
||||
"Your search engine id, see https://developers.google.com/custom-search/v1/overview#prerequisites",
|
||||
key: "Your search api key",
|
||||
num: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
display: "Wikipedia",
|
||||
name: "wikipedia",
|
||||
},
|
||||
];
|
||||
|
||||
export const getToolConfig = (name: string) => {
|
||||
return supportedTools.find((tool) => tool.name === name)?.config;
|
||||
};
|
||||
|
||||
export const toolsRequireConfig = (tools?: string[]): boolean => {
|
||||
if (tools) {
|
||||
return tools.some((tool) => getToolConfig(tool));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -41,5 +41,4 @@ export interface InstallTemplateArgs {
|
||||
vectorDb?: TemplateVectorDB;
|
||||
externalPort?: number;
|
||||
postInstallAction?: TemplatePostInstallAction;
|
||||
tools?: string[];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { createApp } from "./create-app";
|
||||
import { getPkgManager } from "./helpers/get-pkg-manager";
|
||||
import { isFolderEmpty } from "./helpers/is-folder-empty";
|
||||
import { runApp } from "./helpers/run-app";
|
||||
import { supportedTools } from "./helpers/tools";
|
||||
import { validateNpmName } from "./helpers/validate-pkg";
|
||||
import packageJson from "./package.json";
|
||||
import { QuestionArgs, askQuestions, onPromptState } from "./questions";
|
||||
@@ -147,13 +146,6 @@ const program = new Commander.Command(packageJson.name)
|
||||
`
|
||||
|
||||
Select which vector database you would like to use, such as 'none', 'pg' or 'mongo'. The default option is not to use a vector database and use the local filesystem instead ('none').
|
||||
`,
|
||||
)
|
||||
.option(
|
||||
"--tools <tools>",
|
||||
`
|
||||
|
||||
Specify the tools you want to use by providing a comma-separated list. For example, 'google_search,wikipedia'. Use 'none' to not using any tools.
|
||||
`,
|
||||
)
|
||||
.allowUnknownOption()
|
||||
@@ -164,25 +156,6 @@ if (process.argv.includes("--no-frontend")) {
|
||||
if (process.argv.includes("--no-eslint")) {
|
||||
program.eslint = false;
|
||||
}
|
||||
if (process.argv.includes("--tools")) {
|
||||
if (program.tools === "none") {
|
||||
program.tools = [];
|
||||
} else {
|
||||
program.tools = program.tools.split(",");
|
||||
// Check if tools are available
|
||||
const toolsName = supportedTools.map((tool) => tool.name);
|
||||
program.tools.forEach((tool: string) => {
|
||||
if (!toolsName.includes(tool)) {
|
||||
console.error(
|
||||
`Error: Tool '${tool}' is not supported. Supported tools are: ${toolsName.join(
|
||||
", ",
|
||||
)}`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const packageManager = !!program.useNpm
|
||||
? "npm"
|
||||
@@ -283,7 +256,6 @@ async function run(): Promise<void> {
|
||||
externalPort: program.externalPort,
|
||||
postInstallAction: program.postInstallAction,
|
||||
dataSource: program.dataSource,
|
||||
tools: program.tools,
|
||||
});
|
||||
conf.set("preferences", preferences);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"dev": "ncc build ./index.ts -w -o dist/",
|
||||
"build": "npm run clean && ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register",
|
||||
"lint": "eslint . --ignore-pattern dist",
|
||||
"e2e": "playwright test",
|
||||
"e2e": "pnpm pack --pack-destination ./output && npm i -g ./output/create-llama-*.tgz && playwright test",
|
||||
"prepublishOnly": "cd ../../ && pnpm run build:release"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -10,7 +10,6 @@ import { COMMUNITY_OWNER, COMMUNITY_REPO } from "./helpers/constant";
|
||||
import { templatesDir } from "./helpers/dir";
|
||||
import { getAvailableLlamapackOptions } from "./helpers/llama-pack";
|
||||
import { getRepoRootFolders } from "./helpers/repo";
|
||||
import { supportedTools, toolsRequireConfig } from "./helpers/tools";
|
||||
|
||||
export type QuestionArgs = Omit<
|
||||
InstallAppArgs,
|
||||
@@ -71,7 +70,6 @@ const defaults: QuestionArgs = {
|
||||
type: "none",
|
||||
config: {},
|
||||
},
|
||||
tools: [],
|
||||
};
|
||||
|
||||
const handlers = {
|
||||
@@ -216,12 +214,7 @@ export const askQuestions = async (
|
||||
|
||||
const hasOpenAiKey = program.openAiKey || process.env["OPENAI_API_KEY"];
|
||||
const hasVectorDb = program.vectorDb && program.vectorDb !== "none";
|
||||
// Can run the app if all tools do not require configuration
|
||||
if (
|
||||
!hasVectorDb &&
|
||||
hasOpenAiKey &&
|
||||
!toolsRequireConfig(program.tools)
|
||||
) {
|
||||
if (!hasVectorDb && hasOpenAiKey) {
|
||||
actionChoices.push({
|
||||
title:
|
||||
"Generate code, install dependencies, and run the app (~2 min)",
|
||||
@@ -419,9 +412,9 @@ export const askQuestions = async (
|
||||
name: "model",
|
||||
message: "Which model would you like to use?",
|
||||
choices: [
|
||||
{ title: "gpt-3.5-turbo", value: "gpt-3.5-turbo-0125" },
|
||||
{ title: "gpt-4-turbo-preview", value: "gpt-4-turbo-preview" },
|
||||
{ title: "gpt-3.5-turbo", value: "gpt-3.5-turbo" },
|
||||
{ title: "gpt-4", value: "gpt-4" },
|
||||
{ title: "gpt-4-1106-preview", value: "gpt-4-1106-preview" },
|
||||
{
|
||||
title: "gpt-4-vision-preview",
|
||||
value: "gpt-4-vision-preview",
|
||||
@@ -570,30 +563,6 @@ export const askQuestions = async (
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!program.tools &&
|
||||
program.framework === "fastapi" &&
|
||||
program.engine === "context"
|
||||
) {
|
||||
if (ciInfo.isCI) {
|
||||
program.tools = getPrefOrDefault("tools");
|
||||
} else {
|
||||
const toolChoices = supportedTools.map((tool) => ({
|
||||
title: tool.display,
|
||||
value: tool.name,
|
||||
}));
|
||||
const { tools } = await prompts({
|
||||
type: "multiselect",
|
||||
name: "tools",
|
||||
message:
|
||||
"Would you like to build an agent using tools? If so, select the tools here, otherwise just press enter",
|
||||
choices: toolChoices,
|
||||
});
|
||||
program.tools = tools;
|
||||
preferences.tools = tools;
|
||||
}
|
||||
}
|
||||
|
||||
if (!program.openAiKey) {
|
||||
const { key } = await prompts(
|
||||
{
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import os
|
||||
|
||||
from typing import Any, Optional
|
||||
from llama_index.llms import LLM
|
||||
from llama_index.agent import AgentRunner
|
||||
|
||||
from app.engine.tools import ToolFactory
|
||||
from app.engine.index import get_index
|
||||
from llama_index.agent import ReActAgent
|
||||
from llama_index.tools.query_engine import QueryEngineTool
|
||||
|
||||
|
||||
def create_agent_from_llm(
|
||||
llm: Optional[LLM] = None,
|
||||
**kwargs: Any,
|
||||
) -> AgentRunner:
|
||||
from llama_index.agent import OpenAIAgent, ReActAgent
|
||||
from llama_index.llms.openai import OpenAI
|
||||
from llama_index.llms.openai_utils import is_function_calling_model
|
||||
|
||||
if isinstance(llm, OpenAI) and is_function_calling_model(llm.model):
|
||||
return OpenAIAgent.from_tools(
|
||||
llm=llm,
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
return ReActAgent.from_tools(
|
||||
llm=llm,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
tools = []
|
||||
|
||||
# Add query tool
|
||||
index = get_index()
|
||||
llm = index.service_context.llm
|
||||
query_engine = index.as_query_engine(similarity_top_k=3)
|
||||
query_engine_tool = QueryEngineTool.from_defaults(query_engine=query_engine)
|
||||
tools.append(query_engine_tool)
|
||||
|
||||
# Add additional tools
|
||||
tools += ToolFactory.from_env()
|
||||
|
||||
return create_agent_from_llm(
|
||||
llm=llm,
|
||||
tools=tools,
|
||||
verbose=True,
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
import json
|
||||
import importlib
|
||||
|
||||
from llama_index.tools.tool_spec.base import BaseToolSpec
|
||||
from llama_index.tools.function_tool import FunctionTool
|
||||
|
||||
|
||||
class ToolFactory:
|
||||
|
||||
@staticmethod
|
||||
def create_tool(tool_name: str, **kwargs) -> list[FunctionTool]:
|
||||
try:
|
||||
module_name = f"llama_hub.tools.{tool_name}.base"
|
||||
module = importlib.import_module(module_name)
|
||||
tool_cls_name = tool_name.title().replace("_", "") + "ToolSpec"
|
||||
tool_class = getattr(module, tool_cls_name)
|
||||
tool_spec: BaseToolSpec = tool_class(**kwargs)
|
||||
return tool_spec.to_tool_list()
|
||||
except (ImportError, AttributeError) as e:
|
||||
raise ValueError(f"Unsupported tool: {tool_name}") from e
|
||||
except TypeError as e:
|
||||
raise ValueError(
|
||||
f"Could not create tool: {tool_name}. With config: {kwargs}"
|
||||
) from e
|
||||
|
||||
@staticmethod
|
||||
def from_env() -> list[FunctionTool]:
|
||||
tools = []
|
||||
with open("tools_config.json", "r") as f:
|
||||
tool_configs = json.load(f)
|
||||
for name, config in tool_configs.items():
|
||||
tools += ToolFactory.create_tool(name, **config)
|
||||
return tools
|
||||
@@ -1,7 +0,0 @@
|
||||
from app.engine.index import get_index
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
return get_index().as_chat_engine(
|
||||
similarity_top_k=3, chat_mode="condense_plus_context"
|
||||
)
|
||||
@@ -9,7 +9,7 @@ from llama_index.vector_stores import MongoDBAtlasVectorSearch
|
||||
from app.engine.context import create_service_context
|
||||
|
||||
|
||||
def get_index():
|
||||
def get_chat_engine():
|
||||
service_context = create_service_context()
|
||||
logger = logging.getLogger("uvicorn")
|
||||
logger.info("Connecting to index from MongoDB...")
|
||||
@@ -20,4 +20,4 @@ def get_index():
|
||||
)
|
||||
index = VectorStoreIndex.from_vector_store(store, service_context)
|
||||
logger.info("Finished connecting to index from MongoDB.")
|
||||
return index
|
||||
return index.as_chat_engine(similarity_top_k=5, chat_mode="condense_plus_context")
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from app.engine.constants import STORAGE_DIR
|
||||
from app.engine.context import create_service_context
|
||||
from llama_index import (
|
||||
StorageContext,
|
||||
load_index_from_storage,
|
||||
)
|
||||
|
||||
from app.engine.constants import STORAGE_DIR
|
||||
from app.engine.context import create_service_context
|
||||
|
||||
def get_index():
|
||||
|
||||
def get_chat_engine():
|
||||
service_context = create_service_context()
|
||||
# check if storage already exists
|
||||
if not os.path.exists(STORAGE_DIR):
|
||||
@@ -22,4 +22,4 @@ def get_index():
|
||||
storage_context = StorageContext.from_defaults(persist_dir=STORAGE_DIR)
|
||||
index = load_index_from_storage(storage_context, service_context=service_context)
|
||||
logger.info(f"Finished loading index from {STORAGE_DIR}")
|
||||
return index
|
||||
return index.as_chat_engine(similarity_top_k=5, chat_mode="condense_plus_context")
|
||||
|
||||
@@ -6,11 +6,11 @@ from app.engine.context import create_service_context
|
||||
from app.engine.utils import init_pg_vector_store_from_env
|
||||
|
||||
|
||||
def get_index():
|
||||
def get_chat_engine():
|
||||
service_context = create_service_context()
|
||||
logger = logging.getLogger("uvicorn")
|
||||
logger.info("Connecting to index from PGVector...")
|
||||
store = init_pg_vector_store_from_env()
|
||||
index = VectorStoreIndex.from_vector_store(store, service_context)
|
||||
logger.info("Finished connecting to index from PGVector.")
|
||||
return index
|
||||
return index.as_chat_engine(similarity_top_k=5, chat_mode="condense_plus_context")
|
||||
|
||||
@@ -29,7 +29,7 @@ async function getDataSource(llm: LLM) {
|
||||
|
||||
export async function createChatEngine(llm: LLM) {
|
||||
const index = await getDataSource(llm);
|
||||
const retriever = index.asRetriever({ similarityTopK: 3 });
|
||||
const retriever = index.asRetriever({ similarityTopK: 5 });
|
||||
return new ContextChatEngine({
|
||||
chatModel: llm,
|
||||
retriever,
|
||||
|
||||
@@ -35,7 +35,7 @@ async function getDataSource(llm: LLM) {
|
||||
export async function createChatEngine(llm: LLM) {
|
||||
const index = await getDataSource(llm);
|
||||
const retriever = index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
retriever.similarityTopK = 5;
|
||||
|
||||
return new ContextChatEngine({
|
||||
chatModel: llm,
|
||||
|
||||
@@ -31,7 +31,7 @@ async function getDataSource(llm: LLM) {
|
||||
|
||||
export async function createChatEngine(llm: LLM) {
|
||||
const index = await getDataSource(llm);
|
||||
const retriever = index.asRetriever({ similarityTopK: 3 });
|
||||
const retriever = index.asRetriever({ similarityTopK: 5 });
|
||||
return new ContextChatEngine({
|
||||
chatModel: llm,
|
||||
retriever,
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
"moduleResolution": "node",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ from llama_index.chat_engine.types import BaseChatEngine
|
||||
from llama_index.llms.base import ChatMessage
|
||||
from llama_index.llms.types import MessageRole
|
||||
from pydantic import BaseModel
|
||||
from app.engine import get_chat_engine
|
||||
from app.engine.index import get_chat_engine
|
||||
|
||||
chat_router = r = APIRouter()
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from llama_index.chat_engine import SimpleChatEngine
|
||||
|
||||
from app.context import create_base_context
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
return SimpleChatEngine.from_defaults(service_context=create_base_context())
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
from llama_index.chat_engine import SimpleChatEngine
|
||||
|
||||
from app.context import create_base_context
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
return SimpleChatEngine.from_defaults(service_context=create_base_context())
|
||||
@@ -13,8 +13,6 @@ llama-index = "^0.9.19"
|
||||
pypdf = "^3.17.0"
|
||||
python-dotenv = "^1.0.0"
|
||||
docx2txt = "^0.8"
|
||||
llama-hub = "^0.0.77"
|
||||
wikipedia = "^1.4.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
"moduleResolution": "node",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import List
|
||||
from fastapi.responses import StreamingResponse
|
||||
from llama_index.chat_engine.types import BaseChatEngine
|
||||
|
||||
from app.engine import get_chat_engine
|
||||
from app.engine.index import get_chat_engine
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||
from llama_index.llms.base import ChatMessage
|
||||
from llama_index.llms.types import MessageRole
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from llama_index.chat_engine import SimpleChatEngine
|
||||
|
||||
from app.context import create_base_context
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
return SimpleChatEngine.from_defaults(service_context=create_base_context())
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
from llama_index.chat_engine import SimpleChatEngine
|
||||
|
||||
from app.context import create_base_context
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
return SimpleChatEngine.from_defaults(service_context=create_base_context())
|
||||
@@ -13,8 +13,6 @@ llama-index = "^0.9.19"
|
||||
pypdf = "^3.17.0"
|
||||
python-dotenv = "^1.0.0"
|
||||
docx2txt = "^0.8"
|
||||
llama-hub = "^0.0.77"
|
||||
wikipedia = "^1.4.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
"name": "next",
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
"@/*": ["./*"],
|
||||
},
|
||||
"forceConsistentCasingInFileNames": true
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
"exclude": ["node_modules"],
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo"
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
},
|
||||
"include": [
|
||||
"create-app.ts",
|
||||
"index.ts",
|
||||
"./helpers",
|
||||
"questions.ts",
|
||||
"package.json"
|
||||
"package.json",
|
||||
],
|
||||
"exclude": ["dist"]
|
||||
"exclude": ["dist"],
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ module.exports = {
|
||||
|
||||
"ASTRA_DB_APPLICATION_TOKEN",
|
||||
"ASTRA_DB_ENDPOINT",
|
||||
"ASTRA_DB_NAMESPACE",
|
||||
|
||||
"AZURE_OPENAI_KEY",
|
||||
"AZURE_OPENAI_ENDPOINT",
|
||||
|
||||
Generated
+1367
-1314
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -10,24 +10,24 @@
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
"incremental": true,
|
||||
"composite": true
|
||||
"composite": true,
|
||||
},
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./apps/docs/tsconfig.json"
|
||||
"path": "./apps/docs/tsconfig.json",
|
||||
},
|
||||
{
|
||||
"path": "./packages/core"
|
||||
"path": "./packages/core",
|
||||
},
|
||||
{
|
||||
"path": "./packages/create-llama"
|
||||
"path": "./packages/create-llama",
|
||||
},
|
||||
{
|
||||
"path": "./packages/create-llama/e2e"
|
||||
"path": "./packages/create-llama/e2e",
|
||||
},
|
||||
{
|
||||
"path": "./examples"
|
||||
}
|
||||
]
|
||||
"path": "./examples",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user