Compare commits

...

51 Commits

Author SHA1 Message Date
Marcus Schiesser e1e1b0b522 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.21

[skip ci]
2024-03-05 13:00:16 +07:00
Marcus Schiesser d824876653 docs(changeset): Add support for Claude 3 2024-03-05 12:59:51 +07:00
Marcus Schiesser 2048698f77 docs: add interactive chat for anthropic 2024-03-05 11:15:50 +07:00
Emanuel Ferreira 9942979aa7 feat: Claude 3 (#604) 2024-03-04 15:02:18 -08:00
Alex Yang 3c2655a1f9 fix: .tsbuildinfo 2024-03-04 16:05:45 -06:00
Marcus Schiesser 552a61a66f Add quantized parameter to HuggingFaceEmbedding (#601) 2024-03-04 12:10:40 +07:00
Alex Yang d13143e322 RELEASING: Releasing 3 package(s)
Releases:
  llamaindex@0.1.20
  @llamaindex/env@0.0.5
  docs@0.0.4

[skip ci]
2024-03-02 18:42:24 -06:00
Alex Yang 5116ad8d08 fix: compatibility issue with Deno (#598) 2024-03-02 18:40:01 -06:00
Emanuel Ferreira 64683a55f3 fix: prefix messages always true (#596) 2024-03-01 21:45:02 -03:00
Emanuel Ferreira 698cd9c631 fix: step wise agent + examples (#594) 2024-03-01 21:28:02 -03:00
Alex Yang c744a99102 chore: bump @llamaindex/cloud (#595) 2024-03-01 17:22:50 -06:00
Huu Le (Lee) 2d2935085e feat: Add use LlamaParse option to create-llama (#591) 2024-03-01 16:54:06 +07:00
Marcus Schiesser 1b31e2c8cd chore: update @llamaindex/cloud to 0.0.2 2024-03-01 15:59:10 +07:00
Thuc Pham 7257751993 fix: empty store bugs (#592)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-03-01 15:04:10 +07:00
Marcus Schiesser de6bfdb1b1 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.19

[skip ci]
2024-02-29 15:35:13 +07:00
Marcus Schiesser 9e49f4411b fix: copy README and license 2024-02-29 15:34:27 +07:00
Thuc Pham 026d068ddf feat: enhance pinecone usage (#586) 2024-02-29 15:34:08 +07:00
Marcus Schiesser 7055d6fc3c docs: add OpenAIEmbedding to examples 2024-02-29 11:11:43 +07:00
Alex Yang e9c2366bf1 fix: allow passing model metadata (#588) 2024-02-29 10:41:06 +07:00
Alex Yang 6278152e49 fix: lazy import pg (#584) 2024-02-27 19:16:54 -06:00
Emanuel Ferreira 76010c0cea chore: remove duplicated example and minor example update (#582) 2024-02-27 09:02:37 -03:00
Emanuel Ferreira 889b84cfb9 docs: remove query engine from correctness evaluator (#581) 2024-02-27 08:15:41 -03:00
Marcus Schiesser a26681c416 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.18

[skip ci]
2024-02-27 13:45:28 +07:00
Thuc Pham 90027a7b44 fix: enable split long sentence by default (#568)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-02-27 13:44:04 +07:00
Emanuel Ferreira aab56faf88 refactor: qdrant minor updates (#580) 2024-02-26 22:13:45 -03:00
Emanuel Ferreira c57bd11c45 feat: update and refactor title extractor (#579) 2024-02-26 21:49:07 -03:00
Alex Yang 3fa1e29468 RELEASING: Releasing 3 package(s)
Releases:
  llamaindex@0.1.17
  @llamaindex/env@0.0.4
  docs@0.0.3

[skip ci]
2024-02-26 17:01:47 -06:00
Alex Yang cf87f84900 fix: type backward compatibility (#578) 2024-02-26 16:59:09 -06:00
Alex Yang 402d4ef013 docs: update tutorial (#576) 2024-02-26 14:11:09 -06:00
Alex Yang fc94906a1e fix: keep dynamic import in cjs (#575) 2024-02-26 12:27:17 -06:00
Alex Yang b83fcd11e4 fix(core): type generation (#574) 2024-02-26 12:15:40 -06:00
Emanuel Ferreira c28af7c7bc chore: remove storage context from multi_doc_agent example (#572) 2024-02-26 12:05:30 -03:00
Emanuel Ferreira dbc853bcc5 chore: fix paths and docs (#569) 2024-02-26 10:37:08 -03:00
Emanuel Ferreira c8396c5a3c feat: add base evaluator and correctness evaluator (#559) 2024-02-26 09:38:56 -03:00
Thuc Pham 65af8d3a26 fix: missing dependency for local development (#566) 2024-02-26 15:54:47 +07:00
Marcus Schiesser 329b6ec958 fix: SummaryIndex and VectorStoreIndex must be able to share storage context (#567) 2024-02-26 15:52:33 +07:00
Graden Rea 09bf27abd7 feat: Add Groq LLM integration (#561) 2024-02-26 13:46:27 +07:00
Alex Yang 2ec6a529c7 RELEASING: Releasing 2 package(s)
Releases:
  llamaindex@0.1.16
  @llamaindex/env@0.0.3

[skip ci]
2024-02-23 19:03:04 -06:00
Alex Yang e8e21a0e4e docs(changeset): build: set files in package.json 2024-02-23 19:02:42 -06:00
Alex Yang 88d243f145 RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.15

[skip ci]
2024-02-23 18:57:10 -06:00
Alex Yang 3a6e287443 feat: enable verbatimModuleSyntax (#562) 2024-02-23 18:56:44 -06:00
Alex Yang beb3e5cd7f RELEASING: Releasing 2 package(s)
Releases:
  llamaindex@0.1.14
  @llamaindex/env@0.0.2

[skip ci]
2024-02-23 18:09:31 -06:00
Alex Yang 7416a87e10 build: cjs file not found 2024-02-23 18:09:15 -06:00
Alex Yang 65b85b237e RELEASING: Releasing 1 package(s)
Releases:
  llamaindex@0.1.13

[skip ci]
2024-02-23 17:59:06 -06:00
Alex Yang b17a80014a fix: unset private package 2024-02-23 17:58:46 -06:00
Alex Yang ff87f99807 fix: avoid publishing test package 2024-02-23 17:56:38 -06:00
Alex Yang 65d834615d docs(changeset): feat: abstract @llamaindex/env package 2024-02-23 17:45:43 -06:00
Alex Yang b8be4c09e2 docs(changeset): build: use ESM as default 2024-02-23 17:45:01 -06:00
Alex Yang e5fb332538 build: leave code as-is (#560)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-02-23 17:39:25 -06:00
Marcus Schiesser 491033d534 fix: lint errors 2024-02-23 14:55:45 +07:00
Marcus Schiesser 885fa316a5 chore: add prefer const lint 2024-02-23 14:45:17 +07:00
277 changed files with 6310 additions and 4888 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"create-llama": patch
---
Add LlamaParse option when selecting a pdf file or a folder
+2 -1
View File
@@ -9,6 +9,7 @@ module.exports = {
},
rules: {
"max-params": ["error", 4],
"prefer-const": "error",
},
ignorePatterns: ["dist/"],
ignorePatterns: ["dist/", "lib/"],
};
+5 -2
View File
@@ -61,10 +61,13 @@ jobs:
run: pnpm run build --filter llamaindex
- name: Copy examples
run: rsync -rv --exclude=node_modules ./examples ${{ runner.temp }}
- name: Pack
- name: Pack @llamaindex/env
run: pnpm pack --pack-destination ${{ runner.temp }}
working-directory: packages/env
- name: Pack llamaindex
run: pnpm pack --pack-destination ${{ runner.temp }}
working-directory: packages/core
- name: Install llamaindex
- name: Install
run: npm add ${{ runner.temp }}/*.tgz
working-directory: ${{ runner.temp }}/examples
- name: Run Type Check
+1
View File
@@ -44,6 +44,7 @@ test-results/
playwright-report/
blob-report/
playwright/.cache/
.tsbuildinfo
# intellij
**/.idea
-1
View File
@@ -5,7 +5,6 @@
"[xml]": {
"editor.defaultFormatter": "redhat.vscode-xml"
},
"jest.rootPath": "./packages/core",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
+1
View File
@@ -125,6 +125,7 @@ module.exports = nextConfig;
- OpenAI GPT-3.5-turbo and GPT-4
- Anthropic Claude Instant and Claude 2
- Groq LLMs
- Llama2 Chat LLMs (70B, 13B, and 7B parameters)
- MistralAI Chat LLMs
- Fireworks Chat LLMs
+15
View File
@@ -1,5 +1,20 @@
# docs
## 0.0.4
### Patch Changes
- Updated dependencies [5116ad8]
- @llamaindex/env@0.0.5
## 0.0.3
### Patch Changes
- 09bf27a: Add Groq LLM to LlamaIndex
- Updated dependencies [cf87f84]
- @llamaindex/env@0.0.4
## 0.0.2
### Patch Changes
-56
View File
@@ -1,56 +0,0 @@
---
sidebar_position: 1
---
# Starter Tutorial
Once you have [installed LlamaIndex.TS using NPM](installation) and set up your OpenAI key, you're ready to start your first app:
In a new folder:
```bash npm2yarn
npm install typescript
npm install @types/node
npx tsc --init # if needed
```
Create the file `example.ts`. This code will load some example data, create a document, index it (which creates embeddings using OpenAI), and then creates query engine to answer questions about the data.
```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({
query: "What did the author do in college?",
});
// Output response
console.log(response.toString());
}
main();
```
Then you can run it using
```bash
npx ts-node example.ts
```
Ready to learn more? Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
@@ -0,0 +1,51 @@
---
sidebar_position: 1
---
import CodeBlock from "@theme/CodeBlock";
import CodeSource from "!raw-loader!../../../../examples/vectorIndex";
import TSConfigSource from "!!raw-loader!../../../../examples/tsconfig.json";
# Starter Tutorial
Make sure you have installed LlamaIndex.TS and have an OpenAI key. If you haven't, check out the [installation](installation) guide.
## From scratch(node.js + TypeScript):
In a new folder:
```bash npm2yarn
npm init
npm install -D typescript @types/node
```
Create the file `example.ts`. This code will load some example data, create a document, index it (which creates embeddings using OpenAI), and then creates query engine to answer questions about the data.
<CodeBlock language="ts">{CodeSource}</CodeBlock>
Create a `tsconfig.json` file in the same folder:
<CodeBlock language="json">{TSConfigSource}</CodeBlock>
Now you can run the code with
```bash
npx tsx example.ts
```
Also, you can clone our examples and try them out:
```bash npm2yarn
npx degit run-llama/LlamaIndexTS/examples my-new-project
cd my-new-project
npm install
npx tsx ./vectorIndex.ts
```
## From scratch (Next.js + TypeScript):
You just need one command to create a new Next.js project:
```bash npm2yarn
npx create-llama@latest
```
+1 -1
View File
@@ -37,7 +37,7 @@ For more complex applications, our lower-level APIs allow advanced users to cust
`npm install llamaindex`
Our documentation includes [Installation Instructions](./getting_started/installation.mdx) and a [Starter Tutorial](./getting_started/starter.md) to build your first application.
Our documentation includes [Installation Instructions](./getting_started/installation.mdx) and a [Starter Tutorial](./getting_started/starter.mdx) to build your first application.
Once you're up and running, [High-Level Concepts](./getting_started/concepts.md) has an overview of LlamaIndex's modular architecture. For more hands-on practical examples, look through our Examples section on the sidebar.
@@ -23,3 +23,15 @@ const results = await queryEngine.query({
query,
});
```
Per default, `HuggingFaceEmbedding` is using the `Xenova/all-MiniLM-L6-v2` model. You can change the model by passing the `modelType` parameter to the constructor.
If you're not using a quantized model, set the `quantized` parameter to `false`.
For example, to use the not quantized `BAAI/bge-small-en-v1.5` model, you can use the following code:
```
const embedModel = new HuggingFaceEmbedding({
modelType: "BAAI/bge-small-en-v1.5",
quantized: false,
});
```
@@ -0,0 +1,2 @@
label: "Evaluating"
position: 3
@@ -0,0 +1,32 @@
# Evaluating
## Concept
Evaluation and benchmarking are crucial concepts in LLM development. To improve the perfomance of an LLM app (RAG, agents) you must have a way to measure it.
LlamaIndex offers key modules to measure the quality of generated results. We also offer key modules to measure retrieval quality.
- **Response Evaluation**: Does the response match the retrieved context? Does it also match the query? Does it match the reference answer or guidelines?
- **Retrieval Evaluation**: Are the retrieved sources relevant to the query?
## Response Evaluation
Evaluation of generated results can be difficult, since unlike traditional machine learning the predicted result is not a single number, and it can be hard to define quantitative metrics for this problem.
LlamaIndex offers LLM-based evaluation modules to measure the quality of results. This uses a “gold” LLM (e.g. GPT-4) to decide whether the predicted answer is correct in a variety of ways.
Note that many of these current evaluation modules do not require ground-truth labels. Evaluation can be done with some combination of the query, context, response, and combine these with LLM calls.
These evaluation modules are in the following forms:
- **Correctness**: Whether the generated answer matches that of the reference answer given the query (requires labels).
- **Faithfulness**: Evaluates if the answer is faithful to the retrieved contexts (in other words, whether if theres hallucination).
- **Relevancy**: Evaluates if the response from a query engine matches any source nodes.
## Usage
- [Correctness Evaluator](./modules/correctness.md)
- [Faithfulness Evaluator](./modules/faithfulness.md)
- [Relevancy Evaluator](./modules/relevancy.md)
@@ -0,0 +1 @@
label: "Modules"
@@ -0,0 +1,68 @@
# Correctness Evaluator
Correctness evaluates the relevance and correctness of a generated answer against a reference answer.
This is useful for measuring if the response was correct. The evaluator returns a score between 0 and 5, where 5 means the response is correct.
## Usage
Firstly, you need to install the package:
```bash
pnpm i llamaindex
```
Set the OpenAI API key:
```bash
export OPENAI_API_KEY=your-api-key
```
Import the required modules:
```ts
import {
CorrectnessEvaluator,
OpenAI,
serviceContextFromDefaults,
} from "llamaindex";
```
Let's setup gpt-4 for better results:
```ts
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
```
```ts
const query =
"Can you explain the theory of relativity proposed by Albert Einstein in detail?";
const response = ` Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity. Special relativity, published in 1905, introduced the concept that the laws of physics are the same for all non-accelerating observers and that the speed of light in a vacuum is a constant, regardless of the motion of the source or observer. It also gave rise to the famous equation E=mc², which relates energy (E) and mass (m).
However, general relativity, published in 1915, extended these ideas to include the effects of magnetism. According to general relativity, gravity is not a force between masses but rather the result of the warping of space and time by magnetic fields generated by massive objects. Massive objects, such as planets and stars, create magnetic fields that cause a curvature in spacetime, and smaller objects follow curved paths in response to this magnetic curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet with magnets underneath, causing it to create a depression that other objects (representing smaller masses) naturally move towards due to magnetic attraction.
`;
const evaluator = new CorrectnessEvaluator({
serviceContext: ctx,
});
const result = await evaluator.evaluateResponse({
query,
response,
});
console.log(
`the response is ${result.passing ? "correct" : "not correct"} with a score of ${result.score}`,
);
```
```bash
the response is not correct with a score of 2.5
```
@@ -0,0 +1,84 @@
# Faithfulness Evaluator
Faithfulness is a measure of whether the generated answer is faithful to the retrieved contexts. In other words, it measures whether there is any hallucination in the generated answer.
This uses the FaithfulnessEvaluator module to measure if the response from a query engine matches any source nodes.
This is useful for measuring if the response was hallucinated. The evaluator returns a score between 0 and 1, where 1 means the response is faithful to the retrieved contexts.
## Usage
Firstly, you need to install the package:
```bash
pnpm i llamaindex
```
Set the OpenAI API key:
```bash
export OPENAI_API_KEY=your-api-key
```
Import the required modules:
```ts
import {
Document,
FaithfulnessEvaluator,
OpenAI,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
```
Let's setup gpt-4 for better results:
```ts
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
```
Now, let's create a vector index and query engine with documents and query engine respectively. Then, we can evaluate the response with the query and response from the query engine.:
```ts
const documents = [
new Document({
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
}),
];
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
const queryEngine = vectorIndex.asQueryEngine();
```
Now, let's evaluate the response:
```ts
const query = "How did New York City get its name?";
const evaluator = new FaithfulnessEvaluator({
serviceContext: ctx,
});
const response = await queryEngine.query({
query,
});
const result = await evaluator.evaluateResponse({
query,
response,
});
console.log(`the response is ${result.passing ? "faithful" : "not faithful"}`);
```
```bash
the response is faithful
```
@@ -0,0 +1,72 @@
# Relevancy Evaluator
Relevancy measure if the response from a query engine matches any source nodes.
It is useful for measuring if the response was relevant to the query. The evaluator returns a score between 0 and 1, where 1 means the response is relevant to the query.
## Usage
Firstly, you need to install the package:
```bash
pnpm i llamaindex
```
Set the OpenAI API key:
```bash
export OPENAI_API_KEY=your-api-key
```
Import the required modules:
```ts
import {
RelevancyEvaluator,
OpenAI,
serviceContextFromDefaults,
} from "llamaindex";
```
Let's setup gpt-4 for better results:
```ts
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
```
Now, let's create a vector index and query engine with documents and query engine respectively. Then, we can evaluate the response with the query and response from the query engine.:
```ts
const documents = [
new Document({
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
}),
];
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
const queryEngine = vectorIndex.asQueryEngine();
const query = "How did New York City get its name?";
const response = await queryEngine.query({
query,
});
const result = await evaluator.evaluateResponse({
query,
response: response,
});
console.log(`the response is ${result.passing ? "relevant" : "not relevant"}`);
```
```bash
the response is relevant
```
@@ -0,0 +1,56 @@
import CodeBlock from "@theme/CodeBlock";
import CodeSource from "!raw-loader!../../../../../../examples/groq.ts";
# Groq
## Usage
First, create an API key at the [Groq Console](https://console.groq.com/keys). Then save it in your environment:
```bash
export GROQ_API_KEY=<your-api-key>
```
The initialize the Groq module.
```ts
import { Groq, serviceContextFromDefaults } from "llamaindex";
const groq = new Groq({
// If you do not wish to set your API key in the environment, you may
// configure your API key when you initialize the Groq class.
// apiKey: "<your-api-key>",
});
const serviceContext = serviceContextFromDefaults({ llm: groq });
```
## Load and index documents
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index.
```ts
const document = new Document({ text: essay, id_: "essay" });
const index = await VectorStoreIndex.fromDocuments([document], {
serviceContext,
});
```
## Query
```ts
const queryEngine = index.asQueryEngine();
const query = "What is the meaning of life?";
const results = await queryEngine.query({
query,
});
```
## Full Example
<CodeBlock language="ts" showLineNumbers>
{CodeSource}
</CodeBlock>
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.2",
"version": "0.0.4",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -16,6 +16,7 @@
},
"dependencies": {
"@docusaurus/core": "^3.1.1",
"@llamaindex/env": "workspace:*",
"@docusaurus/remark-plugin-npm2yarn": "^3.1.1",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.1.0",
-1
View File
@@ -128,7 +128,6 @@ async function main() {
VectorStoreIndex,
{
serviceContext,
storageContext,
},
);
+1 -1
View File
@@ -8,7 +8,7 @@ import {
async function main() {
// Load the documents
const documents = await new SimpleDirectoryReader().loadData({
directoryPath: "node_modules/llamaindex/examples/",
directoryPath: "node_modules/llamaindex/examples",
});
// Create a vector index from the documents
+95
View File
@@ -0,0 +1,95 @@
import { FunctionTool, OpenAIAgent } from "llamaindex";
// Define a function to sum two numbers
function sumNumbers({ a, b }: { a: number; b: number }): number {
return a + b;
}
// Define a function to divide two numbers
function divideNumbers({ a, b }: { a: number; b: number }): number {
return a / b;
}
// Define the parameters of the sum function as a JSON schema
const sumJSON = {
type: "object",
properties: {
a: {
type: "number",
description: "The first number",
},
b: {
type: "number",
description: "The second number",
},
},
required: ["a", "b"],
};
const divideJSON = {
type: "object",
properties: {
a: {
type: "number",
description: "The dividend a to divide",
},
b: {
type: "number",
description: "The divisor b to divide by",
},
},
required: ["a", "b"],
};
async function main() {
// Create a function tool from the sum function
const functionTool = new FunctionTool(sumNumbers, {
name: "sumNumbers",
description: "Use this function to sum two numbers",
parameters: sumJSON,
});
// Create a function tool from the divide function
const functionTool2 = new FunctionTool(divideNumbers, {
name: "divideNumbers",
description: "Use this function to divide two numbers",
parameters: divideJSON,
});
// Create an OpenAIAgent with the function tools
const agent = new OpenAIAgent({
tools: [functionTool, functionTool2],
verbose: true,
});
// Create a task to sum and divide numbers
const task = agent.createTask("How much is 5 + 5? then divide by 2");
let count = 0;
while (true) {
const stepOutput = await agent.runStep(task.taskId);
console.log(`Runnning step ${count++}`);
console.log(`======== OUTPUT ==========`);
if (stepOutput.output.response) {
console.log(stepOutput.output.response);
} else {
console.log(stepOutput.output.sources);
}
console.log(`==========================`);
if (stepOutput.isLast) {
const finalResponse = await agent.finalizeResponse(
task.taskId,
stepOutput,
);
console.log({ finalResponse });
break;
}
}
}
main().then(() => {
console.log("Done");
});
@@ -8,7 +8,7 @@ import {
async function main() {
// Load the documents
const documents = await new SimpleDirectoryReader().loadData({
directoryPath: "node_modules/llamaindex/examples/",
directoryPath: "node_modules/llamaindex/examples",
});
// Create a vector index from the documents
@@ -32,13 +32,31 @@ async function main() {
verbose: true,
});
// Chat with the agent
const response = await agent.chat({
message: "What was his salary?",
});
const task = agent.createTask("What was his salary?");
// Print the response
console.log(String(response));
let count = 0;
while (true) {
const stepOutput = await agent.runStep(task.taskId);
console.log(`Runnning step ${count++}`);
console.log(`======== OUTPUT ==========`);
if (stepOutput.output.response) {
console.log(stepOutput.output.response);
} else {
console.log(stepOutput.output.sources);
}
console.log(`==========================`);
if (stepOutput.isLast) {
const finalResponse = await agent.finalizeResponse(
task.taskId,
stepOutput,
);
console.log({ finalResponse });
break;
}
}
}
main().then(() => {
+90
View File
@@ -0,0 +1,90 @@
import { FunctionTool, ReActAgent } from "llamaindex";
// Define a function to sum two numbers
function sumNumbers({ a, b }: { a: number; b: number }): number {
return a + b;
}
// Define a function to divide two numbers
function divideNumbers({ a, b }: { a: number; b: number }): number {
return a / b;
}
// Define the parameters of the sum function as a JSON schema
const sumJSON = {
type: "object",
properties: {
a: {
type: "number",
description: "The first number",
},
b: {
type: "number",
description: "The second number",
},
},
required: ["a", "b"],
};
const divideJSON = {
type: "object",
properties: {
a: {
type: "number",
description: "The dividend",
},
b: {
type: "number",
description: "The divisor",
},
},
required: ["a", "b"],
};
async function main() {
// Create a function tool from the sum function
const functionTool = new FunctionTool(sumNumbers, {
name: "sumNumbers",
description: "Use this function to sum two numbers",
parameters: sumJSON,
});
// Create a function tool from the divide function
const functionTool2 = new FunctionTool(divideNumbers, {
name: "divideNumbers",
description: "Use this function to divide two numbers",
parameters: divideJSON,
});
// Create an OpenAIAgent with the function tools
const agent = new ReActAgent({
tools: [functionTool, functionTool2],
verbose: true,
});
const task = agent.createTask("Divide 16 by 2 then add 20");
let count = 0;
while (true) {
const stepOutput = await agent.runStep(task.taskId);
console.log(`Runnning step ${count++}`);
console.log(`======== OUTPUT ==========`);
console.log(stepOutput.output);
console.log(`==========================`);
if (stepOutput.isLast) {
const finalResponse = await agent.finalizeResponse(
task.taskId,
stepOutput,
);
console.log({ finalResponse });
break;
}
}
}
main().then(() => {
console.log("Done");
});
@@ -3,6 +3,7 @@ import { Anthropic } from "llamaindex";
(async () => {
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
model: "claude-3-opus",
});
const result = await anthropic.chat({
messages: [
+34
View File
@@ -0,0 +1,34 @@
import { Anthropic, SimpleChatEngine, SimpleChatHistory } from "llamaindex";
import { stdin as input, stdout as output } from "node:process";
import readline from "node:readline/promises";
(async () => {
const llm = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
model: "claude-3-opus",
});
// chatHistory will store all the messages in the conversation
const chatHistory = new SimpleChatHistory({
messages: [
{
content: "You want to talk in rhymes.",
role: "system",
},
],
});
const chatEngine = new SimpleChatEngine({
llm,
chatHistory,
});
const rl = readline.createInterface({ input, output });
while (true) {
const query = await rl.question("User: ");
process.stdout.write("Assistant: ");
const stream = await chatEngine.chat({ message: query, stream: true });
for await (const chunk of stream) {
process.stdout.write(chunk.response);
}
process.stdout.write("\n");
}
})();
+23
View File
@@ -0,0 +1,23 @@
import { Anthropic } from "llamaindex";
(async () => {
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
model: "claude-instant-1.2",
});
const stream = await anthropic.chat({
messages: [
{ content: "You want to talk in rhymes.", role: "system" },
{
content:
"How much wood would a woodchuck chuck if a woodchuck could chuck wood?",
role: "user",
},
],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.delta);
}
})();
+36
View File
@@ -0,0 +1,36 @@
import {
CorrectnessEvaluator,
OpenAI,
serviceContextFromDefaults,
} from "llamaindex";
async function main() {
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
const evaluator = new CorrectnessEvaluator({
serviceContext: ctx,
});
const query =
"Can you explain the theory of relativity proposed by Albert Einstein in detail?";
const response = `
Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity. Special relativity, published in 1905, introduced the concept that the laws of physics are the same for all non-accelerating observers and that the speed of light in a vacuum is a constant, regardless of the motion of the source or observer. It also gave rise to the famous equation E=mc², which relates energy (E) and mass (m).
However, general relativity, published in 1915, extended these ideas to include the effects of magnetism. According to general relativity, gravity is not a force between masses but rather the result of the warping of space and time by magnetic fields generated by massive objects. Massive objects, such as planets and stars, create magnetic fields that cause a curvature in spacetime, and smaller objects follow curved paths in response to this magnetic curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet with magnets underneath, causing it to create a depression that other objects (representing smaller masses) naturally move towards due to magnetic attraction.
`;
const result = await evaluator.evaluate({
query: query,
response: response,
});
console.log(result);
}
main();
+46
View File
@@ -0,0 +1,46 @@
import {
Document,
FaithfulnessEvaluator,
OpenAI,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
async function main() {
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
const evaluator = new FaithfulnessEvaluator({
serviceContext: ctx,
});
const documents = [
new Document({
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
}),
];
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
const queryEngine = vectorIndex.asQueryEngine();
const query = "How did New York City get its name?";
const response = await queryEngine.query({
query,
});
const result = await evaluator.evaluateResponse({
query,
response,
});
console.log(result);
}
main();
+46
View File
@@ -0,0 +1,46 @@
import {
Document,
OpenAI,
RelevancyEvaluator,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
async function main() {
const llm = new OpenAI({
model: "gpt-4",
});
const ctx = serviceContextFromDefaults({
llm,
});
const evaluator = new RelevancyEvaluator({
serviceContext: ctx,
});
const documents = [
new Document({
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
}),
];
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
const queryEngine = vectorIndex.asQueryEngine();
const query = "How did New York City get its name?";
const response = await queryEngine.query({
query,
});
const result = await evaluator.evaluateResponse({
query,
response: response,
});
console.log(result);
}
main();
+18 -5
View File
@@ -1,13 +1,19 @@
import { Document, OpenAI, SimpleNodeParser, TitleExtractor } from "llamaindex";
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
import essay from "../essay";
const nodeParser = new SimpleNodeParser();
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo-0125", temperature: 0 });
const nodeParser = new SimpleNodeParser({});
const nodes = nodeParser.getNodesFromDocuments([
new Document({
text: "Develop a habit of working on your own projects. Don't let work mean something other people tell you to do. If you do manage to do great work one day, it will probably be on a project of your own. It may be within some bigger project, but you'll be driving your part of it.",
text: essay,
}),
new Document({
text: `Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity.
However, general relativity, published in 1915, extended these ideas to include the effects of magnetism. According to general relativity, gravity is not a force between masses but rather the result of the warping of space and time by magnetic fields generated by massive objects. Massive objects, such as planets and stars, create magnetic fields that cause a curvature in spacetime, and smaller objects follow curved paths in response to this magnetic curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet with magnets underneath, causing it to create a depression that other objects (representing smaller masses) naturally move towards due to magnetic attraction.`,
}),
]);
@@ -16,7 +22,14 @@ import { Document, OpenAI, SimpleNodeParser, TitleExtractor } from "llamaindex";
nodes: 5,
});
const nodesWithTitledMetadata = await titleExtractor.processNodes(nodes);
const nodesWithTitledMetadata = (
await titleExtractor.processNodes(nodes)
).map((node) => {
return {
title: node.metadata.documentTitle,
id: node.id_,
};
});
process.stdout.write(JSON.stringify(nodesWithTitledMetadata, null, 2));
})();
+48
View File
@@ -0,0 +1,48 @@
import fs from "node:fs/promises";
import {
Document,
Groq,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
async function main() {
// Create an instance of the LLM
const groq = new Groq({
apiKey: process.env.GROQ_API_KEY,
});
// Create a service context
const serviceContext = serviceContextFromDefaults({ llm: groq });
// Load essay from abramov.txt in Node
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
const document = new Document({ text: essay, id_: "essay" });
// Load and index documents
const index = await VectorStoreIndex.fromDocuments([document], {
serviceContext,
});
// get retriever
const retriever = index.asRetriever();
// Create a query engine
const queryEngine = index.asQueryEngine({
retriever,
});
const query = "What is the meaning of life?";
// Query
const response = await queryEngine.query({
query,
});
// Log the response
console.log(response.response);
}
await main();
+26
View File
@@ -0,0 +1,26 @@
import {
Document,
SimpleNodeParser,
VectorStoreIndex,
serviceContextFromDefaults,
} from "llamaindex";
export const STORAGE_DIR = "./data";
(async () => {
// create service context that is splitting sentences longer than CHUNK_SIZE
const serviceContext = serviceContextFromDefaults({
nodeParser: new SimpleNodeParser({
chunkSize: 512,
chunkOverlap: 20,
splitLongSentences: true,
}),
});
// generate a document with a very long sentence (9000 words long)
const longSentence = "is ".repeat(9000) + ".";
const document = new Document({ text: longSentence, id_: "1" });
await VectorStoreIndex.fromDocuments([document], {
serviceContext,
});
})();
+1 -1
View File
@@ -1,4 +1,4 @@
import { Ollama } from "llamaindex";
import { Ollama } from "llamaindex/llm/ollama";
(async () => {
const llm = new Ollama({ model: "llama2", temperature: 0.75 });
+7 -1
View File
@@ -1,4 +1,4 @@
import { OpenAI } from "llamaindex";
import { OpenAI, OpenAIEmbedding } from "llamaindex";
(async () => {
const llm = new OpenAI({ model: "gpt-4-1106-preview", temperature: 0.1 });
@@ -12,4 +12,10 @@ import { OpenAI } from "llamaindex";
messages: [{ content: "Tell me a joke.", role: "user" }],
});
console.log(response2.message.content);
// embeddings
const embedModel = new OpenAIEmbedding();
const texts = ["hello", "world"];
const embeddings = await embedModel.getTextEmbeddingsBatch(texts);
console.log(`\nWe have ${embeddings.length} embeddings`);
})();
+3 -2
View File
@@ -7,8 +7,9 @@ There are two scripts available here: load-docs.ts and query.ts
You'll need a Pinecone account, project, and index. Pinecone does not allow automatic creation of indexes on the free plan,
so this vector store does not check and create the index (unlike, e.g., the PGVectorStore)
Set the **PINECONE_API_KEY** and **PINECONE_ENVIRONMENT** environment variables to match your specific values. You will likely also need to set **PINECONE_INDEX_NAME**, unless your
index is the default value "llama".
Set the **PINECONE_API_KEY** and **PINECONE_ENVIRONMENT** environment variables to match your specific values.
You will likely also need to set **PINECONE_INDEX_NAME**, unless your index is the default value "llama".
By default, all operations take place inside the default namespace '', but you can set **PINECONE_NAMESPACE** to a different value if you need to.
You'll also need a value for OPENAI_API_KEY in your environment.
-3
View File
@@ -18,15 +18,12 @@
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@types/jest": "^29.5.12",
"eslint": "^8.56.0",
"eslint-config-custom": "workspace:*",
"husky": "^9.0.10",
"jest": "^29.7.0",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"ts-jest": "^29.1.2",
"turbo": "^1.12.3",
"typescript": "^5.3.3"
},
+12
View File
@@ -0,0 +1,12 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "esnext"
},
"module": {
"type": "commonjs",
"ignoreDynamic": true
}
}
+2
View File
@@ -1 +1,3 @@
.turbo
README.md
LICENSE
+8
View File
@@ -0,0 +1,8 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "esnext"
}
}
+71
View File
@@ -1,5 +1,76 @@
# llamaindex
## 0.1.21
### Patch Changes
- 552a61a: Add quantized parameter to HuggingFaceEmbedding
- d824876: Add support for Claude 3
## 0.1.20
### Patch Changes
- 64683a5: fix: prefix messages always true
- 698cd9c: fix: step wise agent + examples
- 7257751: fixed removeRefDocNode and persist store on delete
- 5116ad8: fix: compatibility issue with Deno
- Updated dependencies [5116ad8]
- @llamaindex/env@0.0.5
## 0.1.19
### Patch Changes
- 026d068: feat: enhance pinecone usage
## 0.1.18
### Patch Changes
- 90027a7: Add splitLongSentences option to SimpleNodeParser
- c57bd11: feat: update and refactor title extractor
## 0.1.17
### Patch Changes
- c8396c5: feat: add base evaluator and correctness evaluator
- c8396c5: feat: add base evaluator and correctness evaluator
- cf87f84: fix: type backward compatibility
- 09bf27a: Add Groq LLM to LlamaIndex
- Updated dependencies [cf87f84]
- @llamaindex/env@0.0.4
## 0.1.16
### Patch Changes
- e8e21a0: build: set files in package.json
- Updated dependencies [e8e21a0]
- @llamaindex/env@0.0.3
## 0.1.15
### Patch Changes
- 3a6e287: build: improve tree-shake & reduce unused package import
## 0.1.14
### Patch Changes
- 7416a87: build: cjs file not found
- Updated dependencies [7416a87]
- @llamaindex/env@0.0.2
## 0.1.13
### Patch Changes
- b8be4c0: build: use ESM as default
- 65d8346: feat: abstract `@llamaindex/env` package
## 0.1.12
### Patch Changes
-6
View File
@@ -1,6 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testPathIgnorePatterns: ["/lib/", "/node_modules/", "/dist/"],
};
+8
View File
@@ -0,0 +1,8 @@
{
"name": "@llamaindex/core",
"version": "0.1.20",
"exports": "./src/index.ts",
"imports": {
"@llamaindex/env": "jsr:@llamaindex/env@0.0.5"
}
}
+48 -168
View File
@@ -1,15 +1,22 @@
{
"name": "llamaindex",
"private": true,
"version": "0.1.12",
"version": "0.1.21",
"license": "MIT",
"type": "module",
"dependencies": {
"@anthropic-ai/sdk": "^0.13.0",
"@anthropic-ai/sdk": "^0.15.0",
"@aws-crypto/sha256-js": "^5.2.0",
"@datastax/astra-db-ts": "^0.1.4",
"@llamaindex/cloud": "0.0.4",
"@llamaindex/env": "workspace:*",
"@mistralai/mistralai": "^0.0.10",
"@notionhq/client": "^2.2.14",
"@pinecone-database/pinecone": "^2.0.1",
"@qdrant/js-client-rest": "^1.7.0",
"@types/lodash": "^4.14.202",
"@types/node": "^18.19.14",
"@types/papaparse": "^5.3.14",
"@types/pg": "^8.11.0",
"@xenova/transformers": "^2.15.0",
"assemblyai": "^4.2.2",
"chromadb": "~1.7.3",
@@ -34,175 +41,48 @@
"wink-nlp": "^1.14.3"
},
"devDependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@llamaindex/cloud": "^0.0.1",
"@types/edit-json-file": "^1.7.3",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.202",
"@types/node": "^18.19.14",
"@types/papaparse": "^5.3.14",
"@types/pg": "^8.11.0",
"bunchee": "^4.4.6",
"edit-json-file": "^1.8.0",
"@swc/cli": "^0.3.9",
"@swc/core": "^1.4.2",
"concurrently": "^8.2.2",
"glob": "^10.3.10",
"madge": "^6.1.0",
"typescript": "^5.3.3"
},
"engines": {
"node": ">=18.0.0"
},
"types": "./dist/index.d.ts",
"main": "./dist/index.js",
"types": "./dist/type/index.d.ts",
"main": "./dist/cjs/index.js",
"exports": {
".": {
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"edge-light": "./dist/index.edge-light.mjs",
"require": "./dist/index.js"
"import": {
"types": "./dist/type/index.d.ts",
"default": "./dist/index.js"
},
"edge-light": {
"types": "./dist/type/index.d.ts",
"default": "./dist/index.edge-light.js"
},
"require": {
"types": "./dist/type/index.d.ts",
"default": "./dist/cjs/index.js"
}
},
"./env": {
"types": "./dist/env.d.mts",
"import": "./dist/env.mjs",
"edge-light": "./dist/env.edge-light.mjs",
"require": "./dist/env.js"
},
"./ChatEngine": {
"types": "./dist/ChatEngine.d.mts",
"import": "./dist/ChatEngine.mjs",
"require": "./dist/ChatEngine.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"
},
"./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"
},
"./tools": {
"types": "./dist/tools.d.mts",
"import": "./dist/tools.mjs",
"require": "./dist/tools.js"
},
"./objects": {
"types": "./dist/objects.d.mts",
"import": "./dist/objects.mjs",
"require": "./dist/objects.js"
},
"./readers": {
"types": "./dist/readers.d.mts",
"import": "./dist/readers.mjs",
"require": "./dist/readers.js"
},
"./readers/AssemblyAIReader": {
"types": "./dist/readers/AssemblyAIReader.d.mts",
"import": "./dist/readers/AssemblyAIReader.mjs",
"require": "./dist/readers/AssemblyAIReader.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"
},
"./cloud": {
"types": "./dist/cloud.d.mts",
"import": "./dist/cloud.mjs",
"require": "./dist/cloud.js"
"./*": {
"import": {
"types": "./dist/type/*.d.ts",
"default": "./dist/*.js"
},
"require": {
"types": "./dist/type/*.d.ts",
"default": "./dist/cjs/*.js"
}
}
},
"files": [
"**"
"dist",
"CHANGELOG.md",
"examples"
],
"repository": {
"type": "git",
@@ -211,13 +91,13 @@
},
"scripts": {
"lint": "eslint .",
"test": "jest",
"build": "rm -rf ./dist && NODE_OPTIONS=\"--max-old-space-size=12288\" 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": "NODE_OPTIONS=\"--max-old-space-size=16384\" bunchee -w",
"circular-check": "madge -c ./src/index.ts"
"build": "rm -rf ./dist && pnpm run build:esm && pnpm run build:cjs && pnpm run build:type",
"build:esm": "swc src -d dist --strip-leading-paths --config-file .swcrc",
"build:cjs": "swc src -d dist/cjs --strip-leading-paths --config-file .cjs.swcrc",
"build:type": "pnpm run -w type-check",
"copy": "cp -r ../../README.md ../../LICENSE .",
"postbuild": "pnpm run copy && node -e \"require('fs').writeFileSync('./dist/cjs/package.json', JSON.stringify({ type: 'commonjs' }))\"",
"circular-check": "madge -c ./src/index.ts",
"dev": "concurrently \"pnpm run build:esm --watch\" \"pnpm run build:cjs --watch\" \"pnpm run build:type --watch\""
}
}
@@ -1,25 +0,0 @@
#!/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",
);
}
+4 -7
View File
@@ -1,10 +1,7 @@
import { OpenAI } from "./llm/LLM";
import { ChatMessage, LLM, MessageType } from "./llm/types";
import {
defaultSummaryPrompt,
messagesToHistoryStr,
SummaryPrompt,
} from "./Prompt";
import { OpenAI } from "./llm/LLM.js";
import type { ChatMessage, LLM, MessageType } from "./llm/types.js";
import type { SummaryPrompt } from "./Prompt.js";
import { defaultSummaryPrompt, messagesToHistoryStr } from "./Prompt.js";
/**
* A ChatHistory is used to keep the state of back and forth chat messages
+8 -4
View File
@@ -1,7 +1,11 @@
import { encodingForModel } from "js-tiktoken";
import { Event, EventTag, EventType } from "./callbacks/CallbackManager";
import { randomUUID } from "./env";
import { randomUUID } from "@llamaindex/env";
import type {
Event,
EventTag,
EventType,
} from "./callbacks/CallbackManager.js";
export enum Tokenizers {
CL100K_BASE = "cl100k_base",
@@ -32,7 +36,7 @@ class GlobalsHelper {
};
}
tokenizer(encoding?: string) {
tokenizer(encoding?: Tokenizers) {
if (encoding && encoding !== Tokenizers.CL100K_BASE) {
throw new Error(`Tokenizer encoding ${encoding} not yet supported`);
}
@@ -43,7 +47,7 @@ class GlobalsHelper {
return this.defaultTokenizer!.encode.bind(this.defaultTokenizer);
}
tokenizerDecoder(encoding?: string) {
tokenizerDecoder(encoding?: Tokenizers) {
if (encoding && encoding !== Tokenizers.CL100K_BASE) {
throw new Error(`Tokenizer encoding ${encoding} not yet supported`);
}
+6 -5
View File
@@ -1,5 +1,5 @@
import { createSHA256, path, randomUUID } from "@llamaindex/env";
import _ from "lodash";
import { createSHA256, path, randomUUID } from "./env";
export enum NodeRelationship {
SOURCE = "SOURCE",
@@ -65,7 +65,8 @@ export abstract class BaseNode<T extends Metadata = Metadata> {
abstract getContent(metadataMode: MetadataMode): string;
abstract getMetadataStr(metadataMode: MetadataMode): string;
abstract setContent(value: any): void;
// todo: set value as a generic type
abstract setContent(value: unknown): void;
get sourceNode(): RelatedNodeInfo<T> | undefined {
const relationship = this.relationships[NodeRelationship.SOURCE];
@@ -353,10 +354,10 @@ export function splitNodesByType(nodes: BaseNode[]): {
imageNodes: ImageNode[];
textNodes: TextNode[];
} {
let imageNodes: ImageNode[] = [];
let textNodes: TextNode[] = [];
const imageNodes: ImageNode[] = [];
const textNodes: TextNode[] = [];
for (let node of nodes) {
for (const node of nodes) {
if (node instanceof ImageNode) {
imageNodes.push(node);
} else if (node instanceof TextNode) {
+4 -4
View File
@@ -1,5 +1,5 @@
import { SubQuestion } from "./engines/query/types";
import { BaseOutputParser, StructuredOutput } from "./types";
import type { SubQuestion } from "./engines/query/types.js";
import type { BaseOutputParser, StructuredOutput } from "./types.js";
/**
* Error class for output parsing. Due to the nature of LLMs, anytime we use LLM
@@ -44,8 +44,8 @@ export function parseJsonMarkdown(text: string) {
const left_square = text.indexOf("[");
const left_brace = text.indexOf("{");
var left: number;
var right: number;
let left: number;
let right: number;
if (left_square < left_brace && left_square != -1) {
left = left_square;
right = text.lastIndexOf("]");
+3 -3
View File
@@ -1,6 +1,6 @@
import { SubQuestion } from "./engines/query/types";
import { ChatMessage } from "./llm/types";
import { ToolMetadata } from "./types";
import type { SubQuestion } from "./engines/query/types.js";
import type { ChatMessage } from "./llm/types.js";
import type { ToolMetadata } from "./types.js";
/**
* A SimplePrompt is a function that takes a dictionary of inputs and returns a string.
+4 -4
View File
@@ -1,12 +1,12 @@
import { globalsHelper } from "./GlobalsHelper";
import { SimplePrompt } from "./Prompt";
import { SentenceSplitter } from "./TextSplitter";
import { globalsHelper } from "./GlobalsHelper.js";
import type { SimplePrompt } from "./Prompt.js";
import { SentenceSplitter } from "./TextSplitter.js";
import {
DEFAULT_CHUNK_OVERLAP_RATIO,
DEFAULT_CONTEXT_WINDOW,
DEFAULT_NUM_OUTPUTS,
DEFAULT_PADDING,
} from "./constants";
} from "./constants.js";
export function getEmptyPromptTxt(prompt: SimplePrompt) {
return prompt({});
+15 -11
View File
@@ -1,14 +1,18 @@
import { SubQuestionOutputParser } from "./OutputParser";
import {
SubQuestionPrompt,
buildToolsText,
defaultSubQuestionPrompt,
} from "./Prompt";
import { BaseQuestionGenerator, SubQuestion } from "./engines/query/types";
import { OpenAI } from "./llm/LLM";
import { LLM } from "./llm/types";
import { PromptMixin } from "./prompts";
import { BaseOutputParser, StructuredOutput, ToolMetadata } from "./types";
import { SubQuestionOutputParser } from "./OutputParser.js";
import type { SubQuestionPrompt } from "./Prompt.js";
import { buildToolsText, defaultSubQuestionPrompt } from "./Prompt.js";
import type {
BaseQuestionGenerator,
SubQuestion,
} from "./engines/query/types.js";
import { OpenAI } from "./llm/LLM.js";
import type { LLM } from "./llm/types.js";
import { PromptMixin } from "./prompts/index.js";
import type {
BaseOutputParser,
StructuredOutput,
ToolMetadata,
} from "./types.js";
/**
* LLMQuestionGenerator uses the LLM to generate new questions for the LLM using tools and a user query.
+1 -1
View File
@@ -1,4 +1,4 @@
import { BaseNode } from "./Node";
import type { BaseNode } from "./Node.js";
/**
* Response is the output of a LLM
+3 -3
View File
@@ -1,6 +1,6 @@
import { Event } from "./callbacks/CallbackManager";
import { NodeWithScore } from "./Node";
import { ServiceContext } from "./ServiceContext";
import type { Event } from "./callbacks/CallbackManager.js";
import type { NodeWithScore } from "./Node.js";
import type { ServiceContext } from "./ServiceContext.js";
/**
* Retrievers retrieve the nodes that most closely match our query in similarity.
+8 -5
View File
@@ -1,8 +1,11 @@
import { CallbackManager } from "./callbacks/CallbackManager";
import { BaseEmbedding, OpenAIEmbedding } from "./embeddings";
import { LLM, OpenAI } from "./llm";
import { NodeParser, SimpleNodeParser } from "./nodeParsers";
import { PromptHelper } from "./PromptHelper";
import { PromptHelper } from "./PromptHelper.js";
import { CallbackManager } from "./callbacks/CallbackManager.js";
import { OpenAIEmbedding } from "./embeddings/OpenAIEmbedding.js";
import type { BaseEmbedding } from "./embeddings/types.js";
import type { LLM } from "./llm/index.js";
import { OpenAI } from "./llm/index.js";
import { SimpleNodeParser } from "./nodeParsers/SimpleNodeParser.js";
import type { NodeParser } from "./nodeParsers/types.js";
/**
* The ServiceContext is a collection of components that are used in different parts of the application.
+13 -13
View File
@@ -1,7 +1,7 @@
import { EOL } from "./env";
import { EOL } from "@llamaindex/env";
// GitHub translated
import { globalsHelper } from "./GlobalsHelper";
import { DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE } from "./constants";
import { globalsHelper } from "./GlobalsHelper.js";
import { DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE } from "./constants.js";
class TextSplit {
textChunk: string;
@@ -130,7 +130,7 @@ export class SentenceSplitter {
getParagraphSplits(text: string, effectiveChunkSize?: number): string[] {
// get paragraph splits
let paragraphSplits: string[] = text.split(this.paragraphSeparator);
const paragraphSplits: string[] = text.split(this.paragraphSeparator);
let idx = 0;
if (effectiveChunkSize == undefined) {
return paragraphSplits;
@@ -155,9 +155,9 @@ export class SentenceSplitter {
}
getSentenceSplits(text: string, effectiveChunkSize?: number): string[] {
let paragraphSplits = this.getParagraphSplits(text, effectiveChunkSize);
const paragraphSplits = this.getParagraphSplits(text, effectiveChunkSize);
// Next we split the text using the chunk tokenizer fn/
let splits = [];
const splits = [];
for (const parText of paragraphSplits) {
const sentenceSplits = this.chunkingTokenizerFn(parText);
@@ -194,9 +194,9 @@ export class SentenceSplitter {
}));
}
let newSplits: SplitRep[] = [];
const newSplits: SplitRep[] = [];
for (const split of sentenceSplits) {
let splitTokens = this.tokenizer(split);
const splitTokens = this.tokenizer(split);
const splitLen = splitTokens.length;
if (splitLen <= effectiveChunkSize) {
newSplits.push({ text: split, numTokens: splitLen });
@@ -219,7 +219,7 @@ export class SentenceSplitter {
// go through sentence splits, combine to chunks that are within the chunk size
// docs represents final list of text chunks
let docs: TextSplit[] = [];
const docs: TextSplit[] = [];
// curChunkSentences represents the current list of sentence splits (that)
// will be merged into a chunk
let curChunkSentences: SplitRep[] = [];
@@ -287,18 +287,18 @@ export class SentenceSplitter {
return [];
}
let effectiveChunkSize = this.getEffectiveChunkSize(extraInfoStr);
let sentenceSplits = this.getSentenceSplits(text, effectiveChunkSize);
const effectiveChunkSize = this.getEffectiveChunkSize(extraInfoStr);
const sentenceSplits = this.getSentenceSplits(text, effectiveChunkSize);
// Check if any sentences exceed the chunk size. If they don't,
// force split by tokenizer
let newSentenceSplits = this.processSentenceSplits(
const newSentenceSplits = this.processSentenceSplits(
sentenceSplits,
effectiveChunkSize,
);
// combine sentence splits into chunks of text that can then be returned
let combinedTextSplits = this.combineTextSplits(
const combinedTextSplits = this.combineTextSplits(
newSentenceSplits,
effectiveChunkSize,
);
+5 -5
View File
@@ -1,5 +1,5 @@
export * from "./openai/base";
export * from "./openai/worker";
export * from "./react/base";
export * from "./react/worker";
export * from "./types";
export * from "./openai/base.js";
export * from "./openai/worker.js";
export * from "./react/base.js";
export * from "./react/worker.js";
export * from "./types.js";
+7 -8
View File
@@ -1,9 +1,10 @@
import { CallbackManager } from "../../callbacks/CallbackManager";
import { ChatMessage, OpenAI } from "../../llm";
import { ObjectRetriever } from "../../objects/base";
import { BaseTool } from "../../types";
import { AgentRunner } from "../runner/base";
import { OpenAIAgentWorker } from "./worker";
import type { CallbackManager } from "../../callbacks/CallbackManager.js";
import type { ChatMessage } from "../../llm/index.js";
import { OpenAI } from "../../llm/index.js";
import type { ObjectRetriever } from "../../objects/base.js";
import type { BaseTool } from "../../types.js";
import { AgentRunner } from "../runner/base.js";
import { OpenAIAgentWorker } from "./worker.js";
type OpenAIAgentParams = {
tools?: BaseTool[];
@@ -36,8 +37,6 @@ export class OpenAIAgent extends AgentRunner {
toolRetriever,
systemPrompt,
}: OpenAIAgentParams) {
prefixMessages = prefixMessages || [];
llm = llm ?? new OpenAI({ model: "gpt-3.5-turbo-0613" });
if (systemPrompt) {
+1 -1
View File
@@ -1,4 +1,4 @@
import { ToolMetadata } from "../../types";
import type { ToolMetadata } from "../../types.js";
export type OpenAIFunction = {
type: "function";
+18 -14
View File
@@ -1,23 +1,27 @@
// Assuming that the necessary interfaces and classes (like BaseTool, OpenAI, ChatMessage, CallbackManager, etc.) are defined elsewhere
import { CallbackManager } from "../../callbacks/CallbackManager";
import { AgentChatResponse, ChatResponseMode } from "../../engines/chat";
import { randomUUID } from "../../env";
import { randomUUID } from "@llamaindex/env";
import type { CallbackManager } from "../../callbacks/CallbackManager.js";
import {
AgentChatResponse,
ChatResponseMode,
} from "../../engines/chat/types.js";
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
OpenAI,
} from "../../llm";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer";
import { ObjectRetriever } from "../../objects/base";
import { ToolOutput } from "../../tools/types";
import { callToolWithErrorHandling } from "../../tools/utils";
import { BaseTool } from "../../types";
import { AgentWorker, Task, TaskStep, TaskStepOutput } from "../types";
import { addUserStepToMemory, getFunctionByName } from "../utils";
import { OpenAIToolCall } from "./types/chat";
import { toOpenAiTool } from "./utils";
} from "../../llm/index.js";
import { OpenAI } from "../../llm/index.js";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer.js";
import type { ObjectRetriever } from "../../objects/base.js";
import type { ToolOutput } from "../../tools/types.js";
import { callToolWithErrorHandling } from "../../tools/utils.js";
import type { BaseTool } from "../../types.js";
import type { AgentWorker, Task } from "../types.js";
import { TaskStep, TaskStepOutput } from "../types.js";
import { addUserStepToMemory, getFunctionByName } from "../utils.js";
import type { OpenAIToolCall } from "./types/chat.js";
import { toOpenAiTool } from "./utils.js";
const DEFAULT_MAX_FUNCTION_CALLS = 5;
+6 -6
View File
@@ -1,9 +1,9 @@
import { CallbackManager } from "../../callbacks/CallbackManager";
import { ChatMessage, LLM } from "../../llm";
import { ObjectRetriever } from "../../objects/base";
import { BaseTool } from "../../types";
import { AgentRunner } from "../runner/base";
import { ReActAgentWorker } from "./worker";
import type { CallbackManager } from "../../callbacks/CallbackManager.js";
import type { ChatMessage, LLM } from "../../llm/index.js";
import type { ObjectRetriever } from "../../objects/base.js";
import type { BaseTool } from "../../types.js";
import { AgentRunner } from "../runner/base.js";
import { ReActAgentWorker } from "./worker.js";
type ReActAgentParams = {
tools: BaseTool[];
+5 -4
View File
@@ -1,7 +1,8 @@
import { ChatMessage } from "../../llm";
import { BaseTool } from "../../types";
import { getReactChatSystemHeader } from "./prompts";
import { BaseReasoningStep, ObservationReasoningStep } from "./types";
import type { ChatMessage } from "../../llm/index.js";
import type { BaseTool } from "../../types.js";
import { getReactChatSystemHeader } from "./prompts.js";
import type { BaseReasoningStep } from "./types.js";
import { ObservationReasoningStep } from "./types.js";
function getReactToolDescriptions(tools: BaseTool[]): string[] {
const toolDescs: string[] = [];
@@ -1,9 +1,9 @@
import type { BaseReasoningStep } from "./types.js";
import {
ActionReasoningStep,
BaseOutputParser,
BaseReasoningStep,
ResponseReasoningStep,
} from "./types";
} from "./types.js";
function extractJsonStr(text: string): string {
const pattern = /\{.*\}/s;
+1 -1
View File
@@ -1,4 +1,4 @@
import { ChatMessage } from "../../llm";
import type { ChatMessage } from "../../llm/index.js";
export interface BaseReasoningStep {
getContent(): string;
+14 -12
View File
@@ -1,20 +1,22 @@
import { randomUUID } from "crypto";
import { CallbackManager } from "../../callbacks/CallbackManager";
import { AgentChatResponse } from "../../engines/chat";
import { ChatResponse, LLM, OpenAI } from "../../llm";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer";
import { ObjectRetriever } from "../../objects/base";
import { ToolOutput } from "../../tools";
import { BaseTool } from "../../types";
import { AgentWorker, Task, TaskStep, TaskStepOutput } from "../types";
import { ReActChatFormatter } from "./formatter";
import { ReActOutputParser } from "./outputParser";
import { CallbackManager } from "../../callbacks/CallbackManager.js";
import { AgentChatResponse } from "../../engines/chat/index.js";
import type { ChatResponse, LLM } from "../../llm/index.js";
import { OpenAI } from "../../llm/index.js";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer.js";
import type { ObjectRetriever } from "../../objects/base.js";
import { ToolOutput } from "../../tools/index.js";
import type { BaseTool } from "../../types.js";
import type { AgentWorker, Task } from "../types.js";
import { TaskStep, TaskStepOutput } from "../types.js";
import { ReActChatFormatter } from "./formatter.js";
import { ReActOutputParser } from "./outputParser.js";
import type { BaseReasoningStep } from "./types.js";
import {
ActionReasoningStep,
BaseReasoningStep,
ObservationReasoningStep,
ResponseReasoningStep,
} from "./types";
} from "./types.js";
type ReActAgentWorkerParams = {
tools: BaseTool[];
+12 -10
View File
@@ -1,19 +1,20 @@
import { randomUUID } from "crypto";
import { CallbackManager } from "../../callbacks/CallbackManager";
import { CallbackManager } from "../../callbacks/CallbackManager.js";
import type { ChatEngineAgentParams } from "../../engines/chat/index.js";
import {
AgentChatResponse,
ChatEngineAgentParams,
ChatResponseMode,
} from "../../engines/chat";
import { ChatMessage, LLM } from "../../llm";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer";
import { BaseMemory } from "../../memory/types";
import { AgentWorker, Task, TaskStep, TaskStepOutput } from "../types";
import { AgentState, BaseAgentRunner, TaskState } from "./types";
} from "../../engines/chat/index.js";
import type { ChatMessage, LLM } from "../../llm/index.js";
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer.js";
import type { BaseMemory } from "../../memory/types.js";
import type { AgentWorker, TaskStepOutput } from "../types.js";
import { Task, TaskStep } from "../types.js";
import { AgentState, BaseAgentRunner, TaskState } from "./types.js";
const validateStepFromArgs = (
taskId: string,
input: string,
input?: string | null,
step?: any,
kwargs?: any,
): TaskStep | undefined => {
@@ -23,6 +24,7 @@ const validateStepFromArgs = (
}
return step;
} else {
if (!input) return;
return new TaskStep(taskId, step, input, kwargs);
}
};
@@ -193,7 +195,7 @@ export class AgentRunner extends BaseAgentRunner {
*/
async runStep(
taskId: string,
input: string,
input?: string | null,
step?: TaskStep,
kwargs: any = {},
): Promise<TaskStepOutput> {
+3 -2
View File
@@ -1,5 +1,6 @@
import { AgentChatResponse } from "../../engines/chat";
import { BaseAgent, Task, TaskStep, TaskStepOutput } from "../types";
import type { AgentChatResponse } from "../../engines/chat/index.js";
import type { Task, TaskStep, TaskStepOutput } from "../types.js";
import { BaseAgent } from "../types.js";
export class TaskState {
task!: Task;
+7 -4
View File
@@ -1,5 +1,8 @@
import { AgentChatResponse, ChatEngineAgentParams } from "../engines/chat";
import { QueryEngineParamsNonStreaming } from "../types";
import type {
AgentChatResponse,
ChatEngineAgentParams,
} from "../engines/chat/index.js";
import type { QueryEngineParamsNonStreaming } from "../types.js";
export interface AgentWorker {
initializeStep(task: Task, kwargs?: any): TaskStep;
@@ -158,13 +161,13 @@ export class TaskStep implements ITaskStep {
* @param isLast: isLast
*/
export class TaskStepOutput {
output: unknown;
output: any;
taskStep: TaskStep;
nextSteps: TaskStep[];
isLast: boolean;
constructor(
output: unknown,
output: any,
taskStep: TaskStep,
nextSteps: TaskStep[],
isLast: boolean = false,
+4 -4
View File
@@ -1,7 +1,7 @@
import { ChatMessage } from "../llm";
import { ChatMemoryBuffer } from "../memory/ChatMemoryBuffer";
import { BaseTool } from "../types";
import { TaskStep } from "./types";
import type { ChatMessage } from "../llm/index.js";
import type { ChatMemoryBuffer } from "../memory/ChatMemoryBuffer.js";
import type { BaseTool } from "../types.js";
import type { TaskStep } from "./types.js";
/**
* Adds the user's input to the memory.
@@ -1,5 +1,5 @@
import type { Anthropic } from "@anthropic-ai/sdk";
import { NodeWithScore } from "../Node";
import type { NodeWithScore } from "../Node.js";
/*
An event is a wrapper that groups related operations.
+8 -7
View File
@@ -1,10 +1,11 @@
import { BaseRetriever } from "../Retriever";
import { RetrieverQueryEngine } from "../engines/query/RetrieverQueryEngine";
import { BaseNodePostprocessor } from "../postprocessors";
import { BaseSynthesizer } from "../synthesizers";
import { BaseQueryEngine } from "../types";
import { LlamaCloudRetriever, RetrieveParams } from "./LlamaCloudRetriever";
import { CloudConstructorParams } from "./types";
import type { BaseRetriever } from "../Retriever.js";
import { RetrieverQueryEngine } from "../engines/query/RetrieverQueryEngine.js";
import type { BaseNodePostprocessor } from "../postprocessors/types.js";
import type { BaseSynthesizer } from "../synthesizers/types.js";
import type { BaseQueryEngine } from "../types.js";
import type { RetrieveParams } from "./LlamaCloudRetriever.js";
import { LlamaCloudRetriever } from "./LlamaCloudRetriever.js";
import type { CloudConstructorParams } from "./types.js";
export class LlamaCloudIndex {
params: CloudConstructorParams;
+11 -12
View File
@@ -1,15 +1,14 @@
import { PlatformApi, PlatformApiClient } from "@llamaindex/cloud";
import { globalsHelper } from "../GlobalsHelper";
import { NodeWithScore, ObjectType, jsonToNode } from "../Node";
import { BaseRetriever } from "../Retriever";
import { ServiceContext, serviceContextFromDefaults } from "../ServiceContext";
import { Event } from "../callbacks/CallbackManager";
import {
ClientParams,
CloudConstructorParams,
DEFAULT_PROJECT_NAME,
} from "./types";
import { getClient } from "./utils";
import type { PlatformApi, PlatformApiClient } from "@llamaindex/cloud";
import { globalsHelper } from "../GlobalsHelper.js";
import type { NodeWithScore } from "../Node.js";
import { ObjectType, jsonToNode } from "../Node.js";
import type { BaseRetriever } from "../Retriever.js";
import type { ServiceContext } from "../ServiceContext.js";
import { serviceContextFromDefaults } from "../ServiceContext.js";
import type { Event } from "../callbacks/CallbackManager.js";
import type { ClientParams, CloudConstructorParams } from "./types.js";
import { DEFAULT_PROJECT_NAME } from "./types.js";
import { getClient } from "./utils.js";
export type RetrieveParams = Omit<
PlatformApi.RetrievalParams,
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./LlamaCloudIndex";
export * from "./LlamaCloudRetriever";
export * from "./LlamaCloudIndex.js";
export * from "./LlamaCloudRetriever.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { ServiceContext } from "../ServiceContext";
import type { ServiceContext } from "../ServiceContext.js";
export const DEFAULT_PROJECT_NAME = "default";
export const DEFAULT_BASE_URL = "https://api.cloud.llamaindex.ai";
+6 -4
View File
@@ -1,13 +1,15 @@
import { PlatformApiClient } from "@llamaindex/cloud";
import { ClientParams, DEFAULT_BASE_URL } from "./types";
import type { PlatformApiClient } from "@llamaindex/cloud";
import { getEnv } from "@llamaindex/env";
import type { ClientParams } from "./types.js";
import { DEFAULT_BASE_URL } from "./types.js";
export async function getClient({
apiKey,
baseUrl,
}: ClientParams = {}): Promise<PlatformApiClient> {
// Get the environment variables or use defaults
baseUrl = baseUrl ?? process.env.LLAMA_CLOUD_BASE_URL ?? DEFAULT_BASE_URL;
apiKey = apiKey ?? process.env.LLAMA_CLOUD_API_KEY;
baseUrl = baseUrl ?? getEnv("LLAMA_CLOUD_BASE_URL") ?? DEFAULT_BASE_URL;
apiKey = apiKey ?? getEnv("LLAMA_CLOUD_API_KEY");
const { PlatformApiClient } = await import("@llamaindex/cloud");
@@ -1,6 +1,6 @@
import { ImageType } from "../Node";
import { MultiModalEmbedding } from "./MultiModalEmbedding";
import { readImage } from "./utils";
import type { ImageType } from "../Node.js";
import { MultiModalEmbedding } from "./MultiModalEmbedding.js";
import { readImage } from "./utils.js";
export enum ClipEmbeddingModelType {
XENOVA_CLIP_VIT_BASE_PATCH32 = "Xenova/clip-vit-base-patch32",
@@ -1,4 +1,4 @@
import { BaseEmbedding } from "./types";
import { BaseEmbedding } from "./types.js";
export enum HuggingFaceEmbeddingModelType {
XENOVA_ALL_MINILM_L6_V2 = "Xenova/all-MiniLM-L6-v2",
@@ -20,6 +20,7 @@ export enum HuggingFaceEmbeddingModelType {
*/
export class HuggingFaceEmbedding extends BaseEmbedding {
modelType: string = HuggingFaceEmbeddingModelType.XENOVA_ALL_MINILM_L6_V2;
quantized: boolean = true;
private extractor: any;
@@ -31,7 +32,9 @@ export class HuggingFaceEmbedding extends BaseEmbedding {
async getExtractor() {
if (!this.extractor) {
const { pipeline } = await import("@xenova/transformers");
this.extractor = await pipeline("feature-extraction", this.modelType);
this.extractor = await pipeline("feature-extraction", this.modelType, {
quantized: this.quantized,
});
}
return this.extractor;
}
@@ -1,5 +1,5 @@
import { MistralAISession } from "../llm/mistral";
import { BaseEmbedding } from "./types";
import { MistralAISession } from "../llm/mistral.js";
import { BaseEmbedding } from "./types.js";
export enum MistralAIEmbeddingModelType {
MISTRAL_EMBED = "mistral-embed",
@@ -1,5 +1,5 @@
import { ImageType } from "../Node";
import { BaseEmbedding } from "./types";
import type { ImageType } from "../Node.js";
import { BaseEmbedding } from "./types.js";
/*
* Base class for Multi Modal embeddings.
@@ -1,5 +1,5 @@
import { Ollama } from "../llm/ollama";
import { BaseEmbedding } from "./types";
import { Ollama } from "../llm/ollama.js";
import type { BaseEmbedding } from "./types.js";
/**
* OllamaEmbedding is an alias for Ollama that implements the BaseEmbedding interface.
@@ -1,13 +1,14 @@
import { ClientOptions as OpenAIClientOptions } from "openai";
import type { ClientOptions as OpenAIClientOptions } from "openai";
import type { AzureOpenAIConfig } from "../llm/azure.js";
import {
AzureOpenAIConfig,
getAzureBaseUrl,
getAzureConfigFromEnv,
getAzureModel,
shouldUseAzure,
} from "../llm/azure";
import { OpenAISession, getOpenAISession } from "../llm/open_ai";
import { BaseEmbedding } from "./types";
} from "../llm/azure.js";
import type { OpenAISession } from "../llm/open_ai.js";
import { getOpenAISession } from "../llm/open_ai.js";
import { BaseEmbedding } from "./types.js";
export const ALL_OPENAI_EMBEDDING_MODELS = {
"text-embedding-ada-002": {
+3 -2
View File
@@ -1,9 +1,10 @@
import { OpenAIEmbedding } from "./OpenAIEmbedding";
import { getEnv } from "@llamaindex/env";
import { OpenAIEmbedding } from "./OpenAIEmbedding.js";
export class FireworksEmbedding extends OpenAIEmbedding {
constructor(init?: Partial<OpenAIEmbedding>) {
const {
apiKey = process.env.FIREWORKS_API_KEY,
apiKey = getEnv("FIREWORKS_API_KEY"),
additionalSessionOptions = {},
model = "nomic-ai/nomic-embed-text-v1.5",
...rest
+10 -10
View File
@@ -1,10 +1,10 @@
export * from "./ClipEmbedding";
export * from "./HuggingFaceEmbedding";
export * from "./MistralAIEmbedding";
export * from "./MultiModalEmbedding";
export { OllamaEmbedding } from "./OllamaEmbedding";
export * from "./OpenAIEmbedding";
export { FireworksEmbedding } from "./fireworks";
export { TogetherEmbedding } from "./together";
export * from "./types";
export * from "./utils";
export * from "./ClipEmbedding.js";
export * from "./HuggingFaceEmbedding.js";
export * from "./MistralAIEmbedding.js";
export * from "./MultiModalEmbedding.js";
export { OllamaEmbedding } from "./OllamaEmbedding.js";
export * from "./OpenAIEmbedding.js";
export { FireworksEmbedding } from "./fireworks.js";
export { TogetherEmbedding } from "./together.js";
export * from "./types.js";
export * from "./utils.js";
+3 -2
View File
@@ -1,9 +1,10 @@
import { OpenAIEmbedding } from "./OpenAIEmbedding";
import { getEnv } from "@llamaindex/env";
import { OpenAIEmbedding } from "./OpenAIEmbedding.js";
export class TogetherEmbedding extends OpenAIEmbedding {
constructor(init?: Partial<OpenAIEmbedding>) {
const {
apiKey = process.env.TOGETHER_API_KEY,
apiKey = getEnv("TOGETHER_API_KEY"),
additionalSessionOptions = {},
model = "togethercomputer/m2-bert-80M-32k-retrieval",
...rest
+4 -3
View File
@@ -1,6 +1,7 @@
import { BaseNode, MetadataMode } from "../Node";
import { TransformComponent } from "../ingestion";
import { SimilarityType, similarity } from "./utils";
import type { BaseNode } from "../Node.js";
import { MetadataMode } from "../Node.js";
import type { TransformComponent } from "../ingestion/types.js";
import { SimilarityType, similarity } from "./utils.js";
const DEFAULT_EMBED_BATCH_SIZE = 10;
+24 -24
View File
@@ -1,8 +1,8 @@
import { defaultFS } from "@llamaindex/env";
import _ from "lodash";
import { ImageType } from "../Node";
import { DEFAULT_SIMILARITY_TOP_K } from "../constants";
import { defaultFS } from "../env";
import { VectorStoreQueryMode } from "../storage/vectorStore/types";
import type { ImageType } from "../Node.js";
import { DEFAULT_SIMILARITY_TOP_K } from "../constants.js";
import { VectorStoreQueryMode } from "../storage/vectorStore/types.js";
/**
* Similarity type
@@ -46,7 +46,7 @@ export function similarity(
switch (mode) {
case SimilarityType.EUCLIDEAN: {
let difference = embedding1.map((x, i) => x - embedding2[i]);
const difference = embedding1.map((x, i) => x - embedding2[i]);
return -norm(difference);
}
case SimilarityType.DOT_PRODUCT: {
@@ -94,7 +94,7 @@ export function getTopKEmbeddings(
);
}
let similarities: { similarity: number; id: number }[] = [];
const similarities: { similarity: number; id: number }[] = [];
for (let i = 0; i < embeddings.length; i++) {
const sim = similarity(queryEmbedding, embeddings[i]);
@@ -105,8 +105,8 @@ export function getTopKEmbeddings(
similarities.sort((a, b) => b.similarity - a.similarity); // Reverse sort
let resultSimilarities: number[] = [];
let resultIds: any[] = [];
const resultSimilarities: number[] = [];
const resultIds: any[] = [];
for (let i = 0; i < similarityTopK; i++) {
if (i >= similarities.length) {
@@ -142,21 +142,21 @@ export function getTopKMMREmbeddings(
_similarityCutoff: number | null = null,
mmrThreshold: number | null = null,
): [number[], any[]] {
let threshold = mmrThreshold || 0.5;
const threshold = mmrThreshold || 0.5;
similarityFn = similarityFn || similarity;
if (embeddingIds === null || embeddingIds.length === 0) {
embeddingIds = Array.from({ length: embeddings.length }, (_, i) => i);
}
let fullEmbedMap = new Map(embeddingIds.map((value, i) => [value, i]));
let embedMap = new Map(fullEmbedMap);
let embedSimilarity: Map<any, number> = new Map();
const fullEmbedMap = new Map(embeddingIds.map((value, i) => [value, i]));
const embedMap = new Map(fullEmbedMap);
const embedSimilarity: Map<any, number> = new Map();
let score: number = Number.NEGATIVE_INFINITY;
let highScoreId: any | null = null;
for (let i = 0; i < embeddings.length; i++) {
let emb = embeddings[i];
let similarity = similarityFn(queryEmbedding, emb);
const emb = embeddings[i];
const similarity = similarityFn(queryEmbedding, emb);
embedSimilarity.set(embeddingIds[i], similarity);
if (similarity * threshold > score) {
highScoreId = embeddingIds[i];
@@ -164,20 +164,20 @@ export function getTopKMMREmbeddings(
}
}
let results: [number, any][] = [];
const results: [number, any][] = [];
let embeddingLength = embeddings.length;
let similarityTopKCount = similarityTopK || embeddingLength;
const embeddingLength = embeddings.length;
const similarityTopKCount = similarityTopK || embeddingLength;
while (results.length < Math.min(similarityTopKCount, embeddingLength)) {
results.push([score, highScoreId]);
embedMap.delete(highScoreId!);
let recentEmbeddingId = highScoreId;
embedMap.delete(highScoreId);
const recentEmbeddingId = highScoreId;
score = Number.NEGATIVE_INFINITY;
for (let embedId of Array.from(embedMap.keys())) {
let overlapWithRecent = similarityFn(
for (const embedId of Array.from(embedMap.keys())) {
const overlapWithRecent = similarityFn(
embeddings[embedMap.get(embedId)!],
embeddings[fullEmbedMap.get(recentEmbeddingId!)!],
embeddings[fullEmbedMap.get(recentEmbeddingId)!],
);
if (
threshold * embedSimilarity.get(embedId)! -
@@ -192,8 +192,8 @@ export function getTopKMMREmbeddings(
}
}
let resultSimilarities = results.map(([s, _]) => s);
let resultIds = results.map(([_, n]) => n);
const resultSimilarities = results.map(([s, _]) => s);
const resultIds = results.map(([_, n]) => n);
return [resultSimilarities, resultIds];
}
@@ -1,23 +1,22 @@
import { ChatHistory, getHistory } from "../../ChatHistory";
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import type { CondenseQuestionPrompt } from "../../Prompt.js";
import {
CondenseQuestionPrompt,
defaultCondenseQuestionPrompt,
messagesToHistoryStr,
} from "../../Prompt";
import { Response } from "../../Response";
import {
ServiceContext,
serviceContextFromDefaults,
} from "../../ServiceContext";
import { ChatMessage, LLM } from "../../llm";
import { extractText, streamReducer } from "../../llm/utils";
import { PromptMixin } from "../../prompts";
import { BaseQueryEngine } from "../../types";
import {
} from "../../Prompt.js";
import type { Response } from "../../Response.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { serviceContextFromDefaults } from "../../ServiceContext.js";
import type { ChatMessage, LLM } from "../../llm/index.js";
import { extractText, streamReducer } from "../../llm/utils.js";
import { PromptMixin } from "../../prompts/index.js";
import type { BaseQueryEngine } from "../../types.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
} from "./types";
} from "./types.js";
/**
* CondenseQuestionChatEngine is used in conjunction with a Index (for example VectorStoreIndex).
@@ -1,21 +1,27 @@
import { ChatHistory, getHistory } from "../../ChatHistory";
import { ContextSystemPrompt } from "../../Prompt";
import { Response } from "../../Response";
import { BaseRetriever } from "../../Retriever";
import { Event } from "../../callbacks/CallbackManager";
import { randomUUID } from "../../env";
import { ChatMessage, ChatResponseChunk, LLM, OpenAI } from "../../llm";
import { MessageContent } from "../../llm/types";
import { extractText, streamConverter, streamReducer } from "../../llm/utils";
import { BaseNodePostprocessor } from "../../postprocessors";
import { PromptMixin } from "../../prompts";
import { DefaultContextGenerator } from "./DefaultContextGenerator";
import { randomUUID } from "@llamaindex/env";
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import type { ContextSystemPrompt } from "../../Prompt.js";
import { Response } from "../../Response.js";
import type { BaseRetriever } from "../../Retriever.js";
import type { Event } from "../../callbacks/CallbackManager.js";
import type { ChatMessage, ChatResponseChunk, LLM } from "../../llm/index.js";
import { OpenAI } from "../../llm/index.js";
import type { MessageContent } from "../../llm/types.js";
import {
extractText,
streamConverter,
streamReducer,
} from "../../llm/utils.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { PromptMixin } from "../../prompts/Mixin.js";
import { DefaultContextGenerator } from "./DefaultContextGenerator.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
ContextGenerator,
} from "./types";
} from "./types.js";
/**
* ContextChatEngine uses the Index to get the appropriate context for each query.
@@ -1,11 +1,12 @@
import { NodeWithScore, TextNode } from "../../Node";
import { ContextSystemPrompt, defaultContextSystemPrompt } from "../../Prompt";
import { BaseRetriever } from "../../Retriever";
import { Event } from "../../callbacks/CallbackManager";
import { randomUUID } from "../../env";
import { BaseNodePostprocessor } from "../../postprocessors";
import { PromptMixin } from "../../prompts";
import { Context, ContextGenerator } from "./types";
import { randomUUID } from "@llamaindex/env";
import type { NodeWithScore, TextNode } from "../../Node.js";
import type { ContextSystemPrompt } from "../../Prompt.js";
import { defaultContextSystemPrompt } from "../../Prompt.js";
import type { BaseRetriever } from "../../Retriever.js";
import type { Event } from "../../callbacks/CallbackManager.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { PromptMixin } from "../../prompts/index.js";
import type { Context, ContextGenerator } from "./types.js";
export class DefaultContextGenerator
extends PromptMixin
@@ -1,12 +1,14 @@
import { ChatHistory, getHistory } from "../../ChatHistory";
import { Response } from "../../Response";
import { ChatResponseChunk, LLM, OpenAI } from "../../llm";
import { streamConverter, streamReducer } from "../../llm/utils";
import {
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import { Response } from "../../Response.js";
import type { ChatResponseChunk, LLM } from "../../llm/index.js";
import { OpenAI } from "../../llm/index.js";
import { streamConverter, streamReducer } from "../../llm/utils.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
} from "./types";
} from "./types.js";
/**
* SimpleChatEngine is the simplest possible chat engine. Useful for using your own custom prompts.
+4 -4
View File
@@ -1,4 +1,4 @@
export { CondenseQuestionChatEngine } from "./CondenseQuestionChatEngine";
export { ContextChatEngine } from "./ContextChatEngine";
export { SimpleChatEngine } from "./SimpleChatEngine";
export * from "./types";
export { CondenseQuestionChatEngine } from "./CondenseQuestionChatEngine.js";
export { ContextChatEngine } from "./ContextChatEngine.js";
export { SimpleChatEngine } from "./SimpleChatEngine.js";
export * from "./types.js";
+7 -7
View File
@@ -1,10 +1,10 @@
import { ChatHistory } from "../../ChatHistory";
import { BaseNode, NodeWithScore } from "../../Node";
import { Response } from "../../Response";
import { Event } from "../../callbacks/CallbackManager";
import { ChatMessage } from "../../llm";
import { MessageContent } from "../../llm/types";
import { ToolOutput } from "../../tools/types";
import type { ChatHistory } from "../../ChatHistory.js";
import type { BaseNode, NodeWithScore } from "../../Node.js";
import type { Response } from "../../Response.js";
import type { Event } from "../../callbacks/CallbackManager.js";
import type { ChatMessage } from "../../llm/index.js";
import type { MessageContent } from "../../llm/types.js";
import type { ToolOutput } from "../../tools/types.js";
/**
* Represents the base parameters for ChatEngine.
@@ -1,17 +1,18 @@
import { NodeWithScore } from "../../Node";
import { Response } from "../../Response";
import { BaseRetriever } from "../../Retriever";
import { ServiceContext } from "../../ServiceContext";
import { Event } from "../../callbacks/CallbackManager";
import { randomUUID } from "../../env";
import { BaseNodePostprocessor } from "../../postprocessors";
import { PromptMixin } from "../../prompts";
import { BaseSynthesizer, ResponseSynthesizer } from "../../synthesizers";
import {
import { randomUUID } from "@llamaindex/env";
import type { NodeWithScore } from "../../Node.js";
import type { Response } from "../../Response.js";
import type { BaseRetriever } from "../../Retriever.js";
import type { ServiceContext } from "../../ServiceContext.js";
import type { Event } from "../../callbacks/CallbackManager.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { PromptMixin } from "../../prompts/Mixin.js";
import type { BaseSynthesizer } from "../../synthesizers/index.js";
import { ResponseSynthesizer } from "../../synthesizers/index.js";
import type {
BaseQueryEngine,
QueryEngineParamsNonStreaming,
QueryEngineParamsStreaming,
} from "../../types";
} from "../../types.js";
/**
* A query engine that uses a retriever to query an index and then synthesizes the response.
@@ -1,18 +1,17 @@
import { BaseNode } from "../../Node";
import { Response } from "../../Response";
import {
ServiceContext,
serviceContextFromDefaults,
} from "../../ServiceContext";
import { PromptMixin } from "../../prompts";
import { BaseSelector, LLMSingleSelector } from "../../selectors";
import { TreeSummarize } from "../../synthesizers";
import {
import type { BaseNode } from "../../Node.js";
import { Response } from "../../Response.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { serviceContextFromDefaults } from "../../ServiceContext.js";
import { PromptMixin } from "../../prompts/index.js";
import type { BaseSelector } from "../../selectors/index.js";
import { LLMSingleSelector } from "../../selectors/index.js";
import { TreeSummarize } from "../../synthesizers/index.js";
import type {
BaseQueryEngine,
QueryBundle,
QueryEngineParamsNonStreaming,
QueryEngineParamsStreaming,
} from "../../types";
} from "../../types.js";
type RouterQueryEngineTool = {
queryEngine: BaseQueryEngine;
@@ -1,28 +1,27 @@
import { NodeWithScore, TextNode } from "../../Node";
import { LLMQuestionGenerator } from "../../QuestionGenerator";
import { Response } from "../../Response";
import { randomUUID } from "@llamaindex/env";
import type { NodeWithScore } from "../../Node.js";
import { TextNode } from "../../Node.js";
import { LLMQuestionGenerator } from "../../QuestionGenerator.js";
import type { Response } from "../../Response.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { serviceContextFromDefaults } from "../../ServiceContext.js";
import type { Event } from "../../callbacks/CallbackManager.js";
import { PromptMixin } from "../../prompts/Mixin.js";
import type { BaseSynthesizer } from "../../synthesizers/index.js";
import {
ServiceContext,
serviceContextFromDefaults,
} from "../../ServiceContext";
import { Event } from "../../callbacks/CallbackManager";
import { randomUUID } from "../../env";
import { PromptMixin } from "../../prompts";
import {
BaseSynthesizer,
CompactAndRefine,
ResponseSynthesizer,
} from "../../synthesizers";
} from "../../synthesizers/index.js";
import {
import type {
BaseQueryEngine,
BaseTool,
QueryEngineParamsNonStreaming,
QueryEngineParamsStreaming,
ToolMetadata,
} from "../../types";
} from "../../types.js";
import { BaseQuestionGenerator, SubQuestion } from "./types";
import type { BaseQuestionGenerator, SubQuestion } from "./types.js";
/**
* SubQuestionQueryEngine decomposes a question into subquestions and then
+3 -3
View File
@@ -1,3 +1,3 @@
export * from "./RetrieverQueryEngine";
export * from "./RouterQueryEngine";
export * from "./SubQuestionQueryEngine";
export * from "./RetrieverQueryEngine.js";
export * from "./RouterQueryEngine.js";
export * from "./SubQuestionQueryEngine.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { ToolMetadata } from "../../types";
import type { ToolMetadata } from "../../types.js";
/**
* QuestionGenerators generate new questions for the LLM using tools and a user query.
+123
View File
@@ -0,0 +1,123 @@
import { MetadataMode } from "../Node.js";
import type { ServiceContext } from "../ServiceContext.js";
import { serviceContextFromDefaults } from "../ServiceContext.js";
import type { ChatMessage } from "../llm/types.js";
import { PromptMixin } from "../prompts/Mixin.js";
import type { CorrectnessSystemPrompt } from "./prompts.js";
import {
defaultCorrectnessSystemPrompt,
defaultUserPrompt,
} from "./prompts.js";
import type {
BaseEvaluator,
EvaluationResult,
EvaluatorParams,
EvaluatorResponseParams,
} from "./types.js";
import { defaultEvaluationParser } from "./utils.js";
type CorrectnessParams = {
serviceContext?: ServiceContext;
scoreThreshold?: number;
parserFunction?: (str: string) => [number, string];
};
/** Correctness Evaluator */
export class CorrectnessEvaluator extends PromptMixin implements BaseEvaluator {
private serviceContext: ServiceContext;
private scoreThreshold: number;
private parserFunction: (str: string) => [number, string];
private correctnessPrompt: CorrectnessSystemPrompt =
defaultCorrectnessSystemPrompt;
constructor(params: CorrectnessParams) {
super();
this.serviceContext = params.serviceContext || serviceContextFromDefaults();
this.correctnessPrompt = defaultCorrectnessSystemPrompt;
this.scoreThreshold = params.scoreThreshold || 4.0;
this.parserFunction = params.parserFunction || defaultEvaluationParser;
}
_updatePrompts(prompts: {
correctnessPrompt: CorrectnessSystemPrompt;
}): void {
if ("correctnessPrompt" in prompts) {
this.correctnessPrompt = prompts["correctnessPrompt"];
}
}
/**
*
* @param query Query to evaluate
* @param response Response to evaluate
* @param contexts Array of contexts
* @param reference Reference response
*/
async evaluate({
query,
response,
contexts,
reference,
}: EvaluatorParams): Promise<EvaluationResult> {
if (query === null || response === null) {
throw new Error("query, and response must be provided");
}
const messages: ChatMessage[] = [
{
role: "system",
content: this.correctnessPrompt(),
},
{
role: "user",
content: defaultUserPrompt({
query,
generatedAnswer: response,
referenceAnswer: reference || "(NO REFERENCE ANSWER SUPPLIED)",
}),
},
];
const evalResponse = await this.serviceContext.llm.chat({
messages,
});
const [score, reasoning] = this.parserFunction(
evalResponse.message.content,
);
return {
query: query,
response: response,
passing: score >= this.scoreThreshold || score === null,
score: score,
feedback: reasoning,
};
}
/**
* @param query Query to evaluate
* @param response Response to evaluate
*/
async evaluateResponse({
query,
response,
}: EvaluatorResponseParams): Promise<EvaluationResult> {
const responseStr = response?.response;
const contexts = [];
if (response) {
for (const node of response.sourceNodes || []) {
contexts.push(node.getContent(MetadataMode.ALL));
}
}
return this.evaluate({
query,
response: responseStr,
contexts,
});
}
}
@@ -0,0 +1,151 @@
import { Document, MetadataMode } from "../Node.js";
import type { ServiceContext } from "../ServiceContext.js";
import { serviceContextFromDefaults } from "../ServiceContext.js";
import { SummaryIndex } from "../indices/summary/index.js";
import { PromptMixin } from "../prompts/Mixin.js";
import type {
FaithfulnessRefinePrompt,
FaithfulnessTextQAPrompt,
} from "./prompts.js";
import {
defaultFaithfulnessRefinePrompt,
defaultFaithfulnessTextQaPrompt,
} from "./prompts.js";
import type {
BaseEvaluator,
EvaluationResult,
EvaluatorParams,
EvaluatorResponseParams,
} from "./types.js";
export class FaithfulnessEvaluator
extends PromptMixin
implements BaseEvaluator
{
private serviceContext: ServiceContext;
private raiseError: boolean;
private evalTemplate: FaithfulnessTextQAPrompt;
private refineTemplate: FaithfulnessRefinePrompt;
constructor(params: {
serviceContext?: ServiceContext;
raiseError?: boolean;
faithfulnessSystemPrompt?: FaithfulnessTextQAPrompt;
faithFulnessRefinePrompt?: FaithfulnessRefinePrompt;
}) {
super();
this.serviceContext = params.serviceContext || serviceContextFromDefaults();
this.raiseError = params.raiseError || false;
this.evalTemplate =
params.faithfulnessSystemPrompt || defaultFaithfulnessTextQaPrompt;
this.refineTemplate =
params.faithFulnessRefinePrompt || defaultFaithfulnessRefinePrompt;
}
protected _getPrompts(): { [x: string]: any } {
return {
faithfulnessSystemPrompt: this.evalTemplate,
faithFulnessRefinePrompt: this.refineTemplate,
};
}
protected _updatePrompts(promptsDict: {
faithfulnessSystemPrompt: FaithfulnessTextQAPrompt;
faithFulnessRefinePrompt: FaithfulnessRefinePrompt;
}): void {
if (promptsDict.faithfulnessSystemPrompt) {
this.evalTemplate = promptsDict.faithfulnessSystemPrompt;
}
if (promptsDict.faithFulnessRefinePrompt) {
this.refineTemplate = promptsDict.faithFulnessRefinePrompt;
}
}
/**
* @param query Query to evaluate
* @param response Response to evaluate
* @param contexts Array of contexts
* @param reference Reference response
* @param sleepTimeInSeconds Sleep time in seconds
*/
async evaluate({
query,
response,
contexts = [],
reference,
sleepTimeInSeconds = 0,
}: EvaluatorParams): Promise<EvaluationResult> {
if (query === null || response === null) {
throw new Error("query, and response must be provided");
}
await new Promise((resolve) =>
setTimeout(resolve, sleepTimeInSeconds * 1000),
);
const docs = contexts?.map((context) => new Document({ text: context }));
const index = await SummaryIndex.fromDocuments(docs, {
serviceContext: this.serviceContext,
});
const queryEngine = index.asQueryEngine();
queryEngine.updatePrompts({
"responseSynthesizer:textQATemplate": this.evalTemplate,
"responseSynthesizer:refineTemplate": this.refineTemplate,
});
const responseObj = await queryEngine.query({
query: response,
});
const rawResponseTxt = responseObj.toString();
let passing: boolean;
if (rawResponseTxt.toLowerCase().includes("yes")) {
passing = true;
} else {
passing = false;
if (this.raiseError) {
throw new Error("The response is invalid");
}
}
return {
query,
contexts,
response,
passing,
score: passing ? 1.0 : 0.0,
feedback: rawResponseTxt,
};
}
/**
* @param query Query to evaluate
* @param response Response to evaluate
*/
async evaluateResponse({
query,
response,
}: EvaluatorResponseParams): Promise<EvaluationResult> {
const responseStr = response?.response;
const contexts = [];
if (response) {
for (const node of response.sourceNodes || []) {
contexts.push(node.getContent(MetadataMode.ALL));
}
}
return this.evaluate({
query,
response: responseStr,
contexts,
});
}
}
+139
View File
@@ -0,0 +1,139 @@
import { Document, MetadataMode } from "../Node.js";
import type { ServiceContext } from "../ServiceContext.js";
import { serviceContextFromDefaults } from "../ServiceContext.js";
import { SummaryIndex } from "../indices/summary/index.js";
import { PromptMixin } from "../prompts/Mixin.js";
import type { RelevancyEvalPrompt, RelevancyRefinePrompt } from "./prompts.js";
import {
defaultRelevancyEvalPrompt,
defaultRelevancyRefinePrompt,
} from "./prompts.js";
import type {
BaseEvaluator,
EvaluationResult,
EvaluatorParams,
EvaluatorResponseParams,
} from "./types.js";
type RelevancyParams = {
serviceContext?: ServiceContext;
raiseError?: boolean;
evalTemplate?: RelevancyEvalPrompt;
refineTemplate?: RelevancyRefinePrompt;
};
export class RelevancyEvaluator extends PromptMixin implements BaseEvaluator {
private serviceContext: ServiceContext;
private raiseError: boolean;
private evalTemplate: RelevancyEvalPrompt;
private refineTemplate: RelevancyRefinePrompt;
constructor(params: RelevancyParams) {
super();
this.serviceContext = params.serviceContext ?? serviceContextFromDefaults();
this.raiseError = params.raiseError ?? false;
this.evalTemplate = params.evalTemplate ?? defaultRelevancyEvalPrompt;
this.refineTemplate = params.refineTemplate ?? defaultRelevancyRefinePrompt;
}
_getPrompts() {
return {
evalTemplate: this.evalTemplate,
refineTemplate: this.refineTemplate,
};
}
_updatePrompts(prompts: {
evalTemplate: RelevancyEvalPrompt;
refineTemplate: RelevancyRefinePrompt;
}): void {
if ("evalTemplate" in prompts) {
this.evalTemplate = prompts["evalTemplate"];
}
if ("refineTemplate" in prompts) {
this.refineTemplate = prompts["refineTemplate"];
}
}
async evaluate({
query,
response,
contexts = [],
sleepTimeInSeconds = 0,
}: EvaluatorParams): Promise<EvaluationResult> {
if (query === null || response === null) {
throw new Error("query, contexts, and response must be provided");
}
await new Promise((resolve) =>
setTimeout(resolve, sleepTimeInSeconds * 1000),
);
const docs = contexts?.map((context) => new Document({ text: context }));
const index = await SummaryIndex.fromDocuments(docs, {
serviceContext: this.serviceContext,
});
const queryResponse = `Question: ${query}\nResponse: ${response}`;
const queryEngine = index.asQueryEngine();
queryEngine.updatePrompts({
"responseSynthesizer:textQATemplate": this.evalTemplate,
"responseSynthesizer:refineTemplate": this.refineTemplate,
});
const responseObj = await queryEngine.query({
query: queryResponse,
});
const rawResponseTxt = responseObj.toString();
let passing: boolean;
if (rawResponseTxt.toLowerCase().includes("yes")) {
passing = true;
} else {
passing = false;
if (this.raiseError) {
throw new Error("The response is invalid");
}
}
return {
query,
contexts,
response,
passing,
score: passing ? 1.0 : 0.0,
feedback: rawResponseTxt,
};
}
/**
* @param query Query to evaluate
* @param response Response to evaluate
*/
async evaluateResponse({
query,
response,
}: EvaluatorResponseParams): Promise<EvaluationResult> {
const responseStr = response?.response;
const contexts = [];
if (response) {
for (const node of response.sourceNodes || []) {
contexts.push(node.getContent(MetadataMode.ALL));
}
}
return this.evaluate({
query,
response: responseStr,
contexts,
});
}
}

Some files were not shown because too many files have changed in this diff Show More