mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-03 19:19:08 -04:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76deca7fea | |||
| f326ab86d2 | |||
| ca8d9709e0 | |||
| e0af059221 | |||
| 8bf5b4acfd | |||
| 93a003baa0 | |||
| 5d9b0bd3f0 | |||
| 9a5525e1b3 | |||
| 7dce3d28d3 | |||
| d4c1482c1c | |||
| 3a96a483a6 | |||
| 7467fce2d4 | |||
| 06af08cac4 | |||
| 83ebdfb1c5 | |||
| 835b1ac000 | |||
| f10b41dbc1 | |||
| 41fe871e2f | |||
| 321c39ddc7 | |||
| f7f1af0139 | |||
| a8c9c279d6 | |||
| eece129831 | |||
| 80e4f51a83 | |||
| 22ff0837c3 | |||
| 74d7e05bcb | |||
| 1feb23bb83 | |||
| 08c55ec258 | |||
| 394e797567 | |||
| 6c3e5d08b8 | |||
| 6e19482814 | |||
| 42eb73a08f |
@@ -0,0 +1,28 @@
|
||||
name: Publish Preview
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
pre_release:
|
||||
name: Pre Release
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Pre Release
|
||||
run: pnpx pkg-pr-new publish ./packages/*
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v3
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Publish @llamaindex/env
|
||||
run: npx jsr publish
|
||||
working-directory: packages/env
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish @llamaindex/llamaindex
|
||||
run: npx jsr publish --allow-slow-types
|
||||
working-directory: packages/llamaindex
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -58,9 +58,11 @@ jobs:
|
||||
|
||||
# Refs: https://github.com/changesets/changesets/issues/421
|
||||
- name: Update lock file
|
||||
continue-on-error: true
|
||||
run: pnpm install --lockfile-only
|
||||
|
||||
- name: Commit lock file
|
||||
continue-on-error: true
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore: update lock file"
|
||||
|
||||
@@ -128,6 +128,12 @@ jobs:
|
||||
run: pnpm run build
|
||||
- name: Copy examples
|
||||
run: rsync -rv --exclude=node_modules ./examples ${{ runner.temp }}
|
||||
- name: Pack @llamaindex/cloud
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/cloud
|
||||
- name: Pack @llamaindex/core
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/core
|
||||
- name: Pack @llamaindex/env
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/env
|
||||
|
||||
@@ -48,3 +48,6 @@ playwright/.cache/
|
||||
|
||||
# intellij
|
||||
**/.idea
|
||||
|
||||
# generated API
|
||||
packages/cloud/src/client
|
||||
|
||||
@@ -76,7 +76,7 @@ main();
|
||||
node --import tsx ./main.ts
|
||||
```
|
||||
|
||||
### Next.js
|
||||
### React Server Component (Next.js, Waku, Redwood.JS...)
|
||||
|
||||
First, you will need to add a llamaindex plugin to your Next.js project.
|
||||
|
||||
@@ -154,40 +154,6 @@ export async function chatWithAgent(
|
||||
}
|
||||
```
|
||||
|
||||
### Cloudflare Workers
|
||||
|
||||
```ts
|
||||
// src/index.ts
|
||||
export default {
|
||||
async fetch(
|
||||
request: Request,
|
||||
env: Env,
|
||||
ctx: ExecutionContext,
|
||||
): Promise<Response> {
|
||||
const { setEnvs } = await import("@llamaindex/env");
|
||||
// set environment variables so that the OpenAIAgent can use them
|
||||
setEnvs(env);
|
||||
const { OpenAIAgent } = await import("llamaindex");
|
||||
const agent = new OpenAIAgent({
|
||||
tools: [],
|
||||
});
|
||||
const responseStream = await agent.chat({
|
||||
stream: true,
|
||||
message: "Hello? What is the weather today?",
|
||||
});
|
||||
const textEncoder = new TextEncoder();
|
||||
const response = responseStream.pipeThrough(
|
||||
new TransformStream({
|
||||
transform: (chunk, controller) => {
|
||||
controller.enqueue(textEncoder.encode(chunk.response.delta));
|
||||
},
|
||||
}),
|
||||
);
|
||||
return new Response(response);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Playground
|
||||
|
||||
Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# docs
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Gemini Agent
|
||||
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import CodeSourceGemini from "!raw-loader!../../../../examples/gemini/agent.ts";
|
||||
|
||||
<CodeBlock language="ts">{CodeSourceGemini}</CodeBlock>
|
||||
@@ -12,12 +12,14 @@ An “agent” is an automated reasoning and decision engine. It takes in a user
|
||||
LlamaIndex.TS comes with a few built-in agents, but you can also create your own. The built-in agents include:
|
||||
|
||||
- OpenAI Agent
|
||||
- Anthropic Agent
|
||||
- Anthropic Agent both via Anthropic and Bedrock (in `@llamaIndex/community`)
|
||||
- Gemini Agent
|
||||
- ReACT Agent
|
||||
|
||||
## Examples
|
||||
|
||||
- [OpenAI Agent](../../examples/agent.mdx)
|
||||
- [Gemini Agent](../../examples/agent_gemini.mdx)
|
||||
|
||||
## Api References
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Settings.llm = new Bedrock({
|
||||
});
|
||||
```
|
||||
|
||||
Currently only supports Anthropic models:
|
||||
Currently only supports Anthropic and Meta models:
|
||||
|
||||
```ts
|
||||
ANTHROPIC_CLAUDE_INSTANT_1 = "anthropic.claude-instant-v1";
|
||||
@@ -25,6 +25,10 @@ ANTHROPIC_CLAUDE_3_SONNET = "anthropic.claude-3-sonnet-20240229-v1:0";
|
||||
ANTHROPIC_CLAUDE_3_HAIKU = "anthropic.claude-3-haiku-20240307-v1:0";
|
||||
ANTHROPIC_CLAUDE_3_OPUS = "anthropic.claude-3-opus-20240229-v1:0"; // available on us-west-2
|
||||
ANTHROPIC_CLAUDE_3_5_SONNET = "anthropic.claude-3-5-sonnet-20240620-v1:0";
|
||||
META_LLAMA2_13B_CHAT = "meta.llama2-13b-chat-v1";
|
||||
META_LLAMA2_70B_CHAT = "meta.llama2-70b-chat-v1";
|
||||
META_LLAMA3_8B_INSTRUCT = "meta.llama3-8b-instruct-v1:0";
|
||||
META_LLAMA3_70B_INSTRUCT = "meta.llama3-70b-instruct-v1:0";
|
||||
```
|
||||
|
||||
Sonnet, Haiku and Opus are multimodal, image_url only supports base64 data url format, e.g. `data:image/jpeg;base64,SGVsbG8sIFdvcmxkIQ==`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.29",
|
||||
"version": "0.0.38",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ make sure you have basic knowledge of the [LlamaIndexTS](https://ts.llamaindex.a
|
||||
# export your API key
|
||||
export OPENAI_API_KEY="sk-..."
|
||||
|
||||
npx ts-node ./chatEngine.ts
|
||||
npx tsx ./chatEngine.ts
|
||||
```
|
||||
|
||||
## Build your own RAG app
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import "dotenv/config";
|
||||
|
||||
import {
|
||||
DefaultAzureCredential,
|
||||
getBearerTokenProvider,
|
||||
} from "@azure/identity";
|
||||
import { AzureDynamicSessionTool, OpenAI, ReActAgent } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
const credential = new DefaultAzureCredential();
|
||||
const azureADTokenProvider = getBearerTokenProvider(
|
||||
credential,
|
||||
"https://cognitiveservices.azure.com/.default",
|
||||
);
|
||||
|
||||
const azure = {
|
||||
azureADTokenProvider,
|
||||
deployment: process.env.AZURE_OPENAI_DEPLOYMENT ?? "gpt-35-turbo",
|
||||
};
|
||||
|
||||
// configure LLM model
|
||||
const llm = new OpenAI({
|
||||
azure,
|
||||
});
|
||||
|
||||
const azureDynamicSession = new AzureDynamicSessionTool();
|
||||
|
||||
// Create an ReActAgent with the azure dynamic session tool
|
||||
const agent = new ReActAgent({
|
||||
llm,
|
||||
tools: [azureDynamicSession],
|
||||
// verbose: true,
|
||||
systemPrompt: `You are a Python interpreter.
|
||||
- You are given tasks to complete and you run python code to solve them.
|
||||
- The python code runs by the python runtime. Every time you call $(interpreter) tool, the python code is executed in a separate cell. It's okay to make multiple calls to $(interpreter).
|
||||
- You can run any python code you want in a secure environment.
|
||||
- For images, return the full URL, not the base64 data.
|
||||
- Return any image content as an HTML tag with the src attribute set to the URL of the image.`,
|
||||
});
|
||||
|
||||
// Chat with the agent
|
||||
const response = await agent.chat({
|
||||
message:
|
||||
"plot a chart of 5 random numbers and save it to /mnt/data/chart.png",
|
||||
stream: false,
|
||||
});
|
||||
|
||||
// Print the response
|
||||
console.log({ response });
|
||||
}
|
||||
|
||||
void main().then(() => {
|
||||
console.log("Done");
|
||||
});
|
||||
@@ -24,7 +24,7 @@ Here are two sample scripts which work well with the sample data in the Astra Po
|
||||
|
||||
Loads and queries a simple vectorstore with some documents about Astra DB
|
||||
|
||||
run `ts-node astradb/example`
|
||||
run `tsx astradb/example`
|
||||
|
||||
## Movie Reviews Example
|
||||
|
||||
@@ -32,10 +32,10 @@ run `ts-node astradb/example`
|
||||
|
||||
This sample loads the same dataset of movie reviews as the Astra Portal sample dataset. (Feel free to load the data in your the Astra Data Explorer to compare)
|
||||
|
||||
run `npx ts-node astradb/load`
|
||||
run `npx tsx astradb/load`
|
||||
|
||||
### Use RAG to Query the data
|
||||
|
||||
Check out your data in the Astra Data Explorer and change the sample query as you see fit.
|
||||
|
||||
run `npx ts-node astradb/query`
|
||||
run `npx tsx astradb/query`
|
||||
|
||||
@@ -6,7 +6,7 @@ Export your OpenAI API Key using `export OPEN_API_KEY=insert your api key here`
|
||||
|
||||
If you haven't installed chromadb, run `pip install chromadb`. Start the server using `chroma run`.
|
||||
|
||||
Now, open a new terminal window and inside `examples`, run `pnpm dlx ts-node chromadb/test.ts`.
|
||||
Now, open a new terminal window and inside `examples`, run `pnpm dlx tsx chromadb/test.ts`.
|
||||
|
||||
Here's the output for the input query `Tell me about Godfrey Cheshire's rating of La Sapienza.`:
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export LLAMA_CLOUD_BASE_URL="https://api.staging.llamaindex.ai"
|
||||
This example is using the managed index named `test` from the project `default` to create a chat engine.
|
||||
|
||||
```shell
|
||||
pnpx ts-node cloud/chat.ts
|
||||
pnpx tsx cloud/chat.ts
|
||||
```
|
||||
|
||||
## Query Engine
|
||||
@@ -29,7 +29,7 @@ pnpx ts-node cloud/chat.ts
|
||||
This example shows how to use the managed index with a query engine.
|
||||
|
||||
```shell
|
||||
pnpx ts-node cloud/query.ts
|
||||
pnpx tsx cloud/query.ts
|
||||
```
|
||||
|
||||
## Pipeline
|
||||
@@ -37,5 +37,5 @@ pnpx ts-node cloud/query.ts
|
||||
This example shows how to create a managed index with a pipeline.
|
||||
|
||||
```shell
|
||||
pnpx ts-node cloud/pipeline.ts
|
||||
pnpx tsx cloud/pipeline.ts
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ContextChatEngine, LlamaCloudIndex } from "llamaindex";
|
||||
async function main() {
|
||||
const index = new LlamaCloudIndex({
|
||||
name: "test",
|
||||
projectName: "default",
|
||||
projectName: "Default",
|
||||
baseUrl: process.env.LLAMA_CLOUD_BASE_URL,
|
||||
apiKey: process.env.LLAMA_CLOUD_API_KEY,
|
||||
});
|
||||
@@ -19,10 +19,10 @@ async function main() {
|
||||
while (true) {
|
||||
const query = await rl.question("User: ");
|
||||
const stream = await chatEngine.chat({ message: query, stream: true });
|
||||
console.log();
|
||||
for await (const chunk of stream) {
|
||||
process.stdout.write(chunk.response);
|
||||
}
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { FunctionTool, Gemini, GEMINI_MODEL, LLMAgent } from "llamaindex";
|
||||
|
||||
const sumNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
{
|
||||
name: "sumNumbers",
|
||||
description: "Use this function to sum two numbers",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
description: "The first number",
|
||||
},
|
||||
b: {
|
||||
type: "number",
|
||||
description: "The second number",
|
||||
},
|
||||
},
|
||||
required: ["a", "b"],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const divideNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
{
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
parameters: {
|
||||
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() {
|
||||
const gemini = new Gemini({
|
||||
model: GEMINI_MODEL.GEMINI_PRO,
|
||||
});
|
||||
const agent = new LLMAgent({
|
||||
llm: gemini,
|
||||
tools: [sumNumbers, divideNumbers],
|
||||
});
|
||||
|
||||
const response = await agent.chat({
|
||||
message: "How much is 5 + 5? then divide by 2",
|
||||
});
|
||||
|
||||
console.log(response.message);
|
||||
}
|
||||
|
||||
void main().then(() => {
|
||||
console.log("Done");
|
||||
});
|
||||
@@ -25,10 +25,10 @@ Here are two sample scripts which work with loading and querying data from a Mil
|
||||
|
||||
This sample loads the same dataset of movie reviews as sample dataset. You can install https://github.com/zilliztech/attu to inspect the loaded data.
|
||||
|
||||
run `npx ts-node milvus/load`
|
||||
run `npx tsx milvus/load`
|
||||
|
||||
## Use RAG to Query the data
|
||||
|
||||
Check out your data in Attu and change the sample query as you see fit.
|
||||
|
||||
run `npx ts-node milvus/query`
|
||||
run `npx tsx milvus/query`
|
||||
|
||||
@@ -34,7 +34,7 @@ MONGODB_COLLECTION=tiny_tweets_collection
|
||||
You are now ready to import our ready-made data set into Mongo. This is the file `tinytweets.json`, a selection of approximately 1000 tweets from @seldo on Twitter in mid-2019. With your environment set up you can do this by running
|
||||
|
||||
```
|
||||
npx ts-node mongodb/1_import.ts
|
||||
npx tsx mongodb/1_import.ts
|
||||
```
|
||||
|
||||
If you don't want to use tweets, you can replace `json_file` with any other array of JSON objects, but you will need to modify some code later to make sure the correct field gets indexed. There is no LlamaIndex-specific code here; you can load your data into Mongo any way you want to.
|
||||
@@ -59,7 +59,7 @@ MONGODB_VECTOR_INDEX=tiny_tweets_vector_index
|
||||
If the data you're indexing is the tweets we gave you, you're ready to go:
|
||||
|
||||
```bash
|
||||
npx ts-node mongodb/2_load_and_index.ts
|
||||
npx tsx mongodb/2_load_and_index.ts
|
||||
```
|
||||
|
||||
> Note: this script is running a couple of minutes and currently doesn't show any progress.
|
||||
@@ -112,7 +112,7 @@ Now you're ready to query your data!
|
||||
You can do this by running
|
||||
|
||||
```bash
|
||||
npx ts-node mongodb/3_query.ts
|
||||
npx tsx mongodb/3_query.ts
|
||||
```
|
||||
|
||||
This sets up a connection to Atlas just like `2_load_and_index.ts` did, then it creates a [query engine](https://docs.llamaindex.ai/en/stable/understanding/querying/querying.html#getting-started) and runs a query against it.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"version": "0.0.6",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"@azure/identity": "^4.2.1",
|
||||
"@datastax/astra-db-ts": "^1.2.1",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^2.2.2",
|
||||
@@ -18,7 +19,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.15.6",
|
||||
"typescript": "^5.5.2"
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ Read and follow the instructions in the README.md file located one directory up
|
||||
|
||||
To import documents and save the embedding vectors to your database:
|
||||
|
||||
> `npx ts-node pg-vector-store/load-docs.ts data`
|
||||
> `npx tsx pg-vector-store/load-docs.ts data`
|
||||
|
||||
where data is the directory containing your input files. Using the `data` directory in the example above will read all of the files in that directory using the LlamaIndexTS default readers for each file type.
|
||||
|
||||
@@ -45,6 +45,6 @@ where data is the directory containing your input files. Using the `data` direct
|
||||
|
||||
To query using the resulting vector store:
|
||||
|
||||
> `npx ts-node pg-vector-store/query.ts`
|
||||
> `npx tsx pg-vector-store/query.ts`
|
||||
|
||||
The script will prompt for a question, then process and present the answer using the PGVectorStore data and your OpenAI API key. It will continue to prompt until you enter `q`, `quit` or `exit` as the next query.
|
||||
|
||||
@@ -19,7 +19,7 @@ Read and follow the instructions in the README.md file located one directory up
|
||||
|
||||
To import documents and save the embedding vectors to your database:
|
||||
|
||||
> `npx ts-node pinecone-vector-store/load-docs.ts data`
|
||||
> `npx tsx pinecone-vector-store/load-docs.ts data`
|
||||
|
||||
where data is the directory containing your input files. Using the _data_ directory in the example above will read all of the files in that directory using the llamaindexTS default readers for each file type.
|
||||
|
||||
@@ -29,6 +29,6 @@ where data is the directory containing your input files. Using the _data_ direct
|
||||
|
||||
To query using the resulting vector store:
|
||||
|
||||
> `npx ts-node pinecone-vector-store/query.ts`
|
||||
> `npx tsx pinecone-vector-store/query.ts`
|
||||
|
||||
The script will prompt for a question, then process and present the answer using the PineconeVectorStore data and your OpenAI API key. It will continue to prompt until you enter `q`, `quit` or `exit` as the next query.
|
||||
|
||||
@@ -8,4 +8,4 @@ Add your OpenAI API Key into a file called `.env` in the parent folder of this d
|
||||
OPEN_API_KEY=sk-you-key
|
||||
```
|
||||
|
||||
Now, open a new terminal window and inside `examples`, run `npx ts-node qdrantdb/preFilters.ts`.
|
||||
Now, open a new terminal window and inside `examples`, run `npx tsx qdrantdb/preFilters.ts`.
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { TextFileReader } from "llamaindex/readers/TextFileReader";
|
||||
|
||||
class ZipReader extends FileReader {
|
||||
loadDataAsContent(fileContent: Buffer): Promise<Document<Metadata>[]> {
|
||||
loadDataAsContent(fileContent: Uint8Array): Promise<Document<Metadata>[]> {
|
||||
throw new Error("Implement me");
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -12,10 +12,9 @@
|
||||
"e2e": "turbo run e2e",
|
||||
"test": "turbo run test",
|
||||
"type-check": "tsc -b --diagnostics",
|
||||
"release": "pnpm run check-minor-version && pnpm run build:release && changeset publish",
|
||||
"release-snapshot": "pnpm run check-minor-version && pnpm run build:release && changeset publish --tag snapshot",
|
||||
"check-minor-version": "node ./scripts/check-minor-version.mjs",
|
||||
"new-version": "changeset version && pnpm run check-minor-version && pnpm format:write && pnpm run build:release",
|
||||
"release": "pnpm run build:release && changeset publish",
|
||||
"release-snapshot": "pnpm run build:release && changeset publish --tag snapshot",
|
||||
"new-version": "changeset version && pnpm format:write && pnpm run build:release",
|
||||
"new-snapshot": "pnpm run build:release && changeset version --snapshot"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -24,14 +23,14 @@
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "^14.2.4",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-turbo": "^1.13.4",
|
||||
"eslint-config-turbo": "^2.0.5",
|
||||
"eslint-plugin-react": "7.34.1",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.7",
|
||||
"madge": "^7.0.0",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"turbo": "^1.13.4",
|
||||
"turbo": "^2.0.5",
|
||||
"typescript": "^5.5.2"
|
||||
},
|
||||
"packageManager": "pnpm@9.4.0",
|
||||
@@ -40,6 +39,9 @@
|
||||
"trim": "1.0.1",
|
||||
"@babel/traverse": "7.23.2",
|
||||
"protobufjs": "7.2.6"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"bunchee@5.2.1": "patches/bunchee@5.2.1.patch"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
|
||||
@@ -1,5 +1,80 @@
|
||||
# @llamaindex/autotool-02-next-example
|
||||
|
||||
## 0.1.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
- @llamaindex/autotool@1.0.0
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/autotool-02-next-example",
|
||||
"private": true,
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.22",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"unplugin": "^1.10.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"llamaindex": "^0.4.3",
|
||||
"llamaindex": "^0.4.12",
|
||||
"openai": "^4",
|
||||
"typescript": "^4"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f326ab8: chore: bump version
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 321c39d: fix: generate api as class
|
||||
@@ -0,0 +1,18 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
> LlamaCloud is a new generation of managed parsing, ingestion, and retrieval services, designed to bring production-grade context-augmentation to your LLM and RAG applications.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { OpenAPI } from "@llamaindex/cloud/api";
|
||||
OpenAPI.TOKEN = "YOUR_API_KEY";
|
||||
OpenAPI.BASE = "https://api.cloud.llamaindex.ai/";
|
||||
// ...
|
||||
```
|
||||
|
||||
For more information, see the [API documentation](https://docs.cloud.llamaindex.ai/).
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,18 @@
|
||||
import { defineConfig } from "@hey-api/openapi-ts";
|
||||
|
||||
export default defineConfig({
|
||||
// you can download this file to get the latest version of the OpenAPI document
|
||||
// @link https://api.cloud.llamaindex.ai/api/openapi.json
|
||||
input: "./openapi.json",
|
||||
output: {
|
||||
path: "./src/client",
|
||||
format: "prettier",
|
||||
lint: "eslint",
|
||||
},
|
||||
services: {
|
||||
asClass: true,
|
||||
},
|
||||
types: {
|
||||
enums: "javascript",
|
||||
},
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@llamaindex/cloud",
|
||||
"version": "0.1.2",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"generate": "pnpm dlx @hey-api/openapi-ts",
|
||||
"build": "pnpm run generate && bunchee"
|
||||
},
|
||||
"files": [
|
||||
"openapi.json",
|
||||
"dist"
|
||||
],
|
||||
"exports": {
|
||||
"./openapi.json": "./openapi.json",
|
||||
"./api": {
|
||||
"require": {
|
||||
"types": "./dist/api.d.cts",
|
||||
"default": "./dist/api.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/api.d.ts",
|
||||
"default": "./dist/api.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/api.d.ts",
|
||||
"default": "./dist/api.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/himself65/LlamaIndexTS.git",
|
||||
"directory": "packages/cloud"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hey-api/openapi-ts": "^0.48.0",
|
||||
"bunchee": "^5.2.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./client";
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist/type",
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo",
|
||||
"emitDeclarationOnly": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"lib": ["DOM", "ESNext"]
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -1,5 +1,72 @@
|
||||
# @llamaindex/community
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f326ab8: chore: bump version
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
## Current Features:
|
||||
|
||||
- Bedrock support for the Anthropic Claude Models [usage](https://ts.llamaindex.ai/modules/llms/available_llms/bedrock)
|
||||
- Bedrock support for the Meta LLama 2 and 3 Models [usage](https://ts.llamaindex.ai/modules/llms/available_llms/bedrock)
|
||||
|
||||
## LICENSE
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "@llamaindex/community",
|
||||
"version": "0.0.5",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./type": "./src/type.ts"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/community",
|
||||
"description": "Community package for LlamaIndexTS",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.16",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,53 +1,34 @@
|
||||
import {
|
||||
BedrockRuntimeClient,
|
||||
type BedrockRuntimeClientConfig,
|
||||
InvokeModelCommand,
|
||||
InvokeModelWithResponseStreamCommand,
|
||||
ResponseStream,
|
||||
type BedrockRuntimeClientConfig,
|
||||
type InvokeModelCommandInput,
|
||||
type InvokeModelWithResponseStreamCommandInput,
|
||||
} from "@aws-sdk/client-bedrock-runtime";
|
||||
import type {
|
||||
BaseTool,
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
ChatResponseChunk,
|
||||
CompletionResponse,
|
||||
LLMChatParamsNonStreaming,
|
||||
LLMChatParamsStreaming,
|
||||
LLMCompletionParamsNonStreaming,
|
||||
LLMCompletionParamsStreaming,
|
||||
LLMMetadata,
|
||||
PartialToolCall,
|
||||
ToolCall,
|
||||
ToolCallLLMMessageOptions,
|
||||
} from "llamaindex";
|
||||
import { ToolCallLLM, streamConverter, wrapLLMEvent } from "llamaindex";
|
||||
import type {
|
||||
AnthropicNoneStreamingResponse,
|
||||
AnthropicTextContent,
|
||||
StreamEvent,
|
||||
ToolBlock,
|
||||
ToolChoice,
|
||||
} from "./types.js";
|
||||
import { streamConverter, ToolCallLLM, wrapLLMEvent } from "llamaindex";
|
||||
import {
|
||||
mapBaseToolsToAnthropicTools,
|
||||
mapChatMessagesToAnthropicMessages,
|
||||
mapMessageContentToMessageContentDetails,
|
||||
toUtf8,
|
||||
} from "./utils.js";
|
||||
|
||||
export type BedrockAdditionalChatOptions = { toolChoice: ToolChoice };
|
||||
type BedrockAdditionalChatOptions,
|
||||
type BedrockChatStreamResponse,
|
||||
Provider,
|
||||
} from "./provider";
|
||||
import { PROVIDERS } from "./providers";
|
||||
import { mapMessageContentToMessageContentDetails } from "./utils.js";
|
||||
|
||||
export type BedrockChatParamsStreaming = LLMChatParamsStreaming<
|
||||
BedrockAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>;
|
||||
|
||||
export type BedrockChatStreamResponse = AsyncIterable<
|
||||
ChatResponseChunk<ToolCallLLMMessageOptions>
|
||||
>;
|
||||
|
||||
export type BedrockChatParamsNonStreaming = LLMChatParamsNonStreaming<
|
||||
BedrockAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
@@ -151,174 +132,6 @@ export const TOOL_CALL_MODELS = [
|
||||
BEDROCK_MODELS.ANTHROPIC_CLAUDE_3_5_SONNET,
|
||||
];
|
||||
|
||||
abstract class Provider<ProviderStreamEvent extends {} = {}> {
|
||||
abstract getTextFromResponse(response: Record<string, any>): string;
|
||||
|
||||
abstract getToolsFromResponse<T extends {} = {}>(
|
||||
response: Record<string, any>,
|
||||
): T[];
|
||||
|
||||
getStreamingEventResponse(
|
||||
response: Record<string, any>,
|
||||
): ProviderStreamEvent | undefined {
|
||||
return response.chunk?.bytes
|
||||
? (JSON.parse(toUtf8(response.chunk?.bytes)) as ProviderStreamEvent)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
async *reduceStream(
|
||||
stream: AsyncIterable<ResponseStream>,
|
||||
): BedrockChatStreamResponse {
|
||||
yield* streamConverter(stream, (response) => {
|
||||
return {
|
||||
delta: this.getTextFromStreamResponse(response),
|
||||
raw: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getTextFromStreamResponse(response: Record<string, any>): string {
|
||||
return this.getTextFromResponse(response);
|
||||
}
|
||||
|
||||
abstract getRequestBody<T extends ChatMessage>(
|
||||
metadata: LLMMetadata,
|
||||
messages: T[],
|
||||
tools?: BaseTool[],
|
||||
options?: BedrockAdditionalChatOptions,
|
||||
): InvokeModelCommandInput | InvokeModelWithResponseStreamCommandInput;
|
||||
}
|
||||
|
||||
class AnthropicProvider extends Provider<StreamEvent> {
|
||||
getResultFromResponse(
|
||||
response: Record<string, any>,
|
||||
): AnthropicNoneStreamingResponse {
|
||||
return JSON.parse(toUtf8(response.body));
|
||||
}
|
||||
|
||||
getToolsFromResponse<AnthropicToolContent>(
|
||||
response: Record<string, any>,
|
||||
): AnthropicToolContent[] {
|
||||
const result = this.getResultFromResponse(response);
|
||||
return result.content
|
||||
.filter((item) => item.type === "tool_use")
|
||||
.map((item) => item as AnthropicToolContent);
|
||||
}
|
||||
|
||||
getTextFromResponse(response: Record<string, any>): string {
|
||||
const result = this.getResultFromResponse(response);
|
||||
return result.content
|
||||
.filter((item) => item.type === "text")
|
||||
.map((item) => (item as AnthropicTextContent).text)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
getTextFromStreamResponse(response: Record<string, any>): string {
|
||||
const event = this.getStreamingEventResponse(response);
|
||||
if (event?.type === "content_block_delta") {
|
||||
if (event.delta.type === "text_delta") return event.delta.text;
|
||||
if (event.delta.type === "input_json_delta")
|
||||
return event.delta.partial_json;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async *reduceStream(
|
||||
stream: AsyncIterable<ResponseStream>,
|
||||
): BedrockChatStreamResponse {
|
||||
let collecting = [];
|
||||
let tool: ToolBlock | undefined = undefined;
|
||||
// #TODO this should be broken down into a separate consumer
|
||||
for await (const response of stream) {
|
||||
const event = this.getStreamingEventResponse(response);
|
||||
if (
|
||||
event?.type === "content_block_start" &&
|
||||
event.content_block.type === "tool_use"
|
||||
) {
|
||||
tool = event.content_block;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
event?.type === "content_block_delta" &&
|
||||
event.delta.type === "input_json_delta"
|
||||
) {
|
||||
collecting.push(event.delta.partial_json);
|
||||
}
|
||||
|
||||
let options: undefined | ToolCallLLMMessageOptions = undefined;
|
||||
if (tool && collecting.length) {
|
||||
const input = collecting.filter((item) => item).join("");
|
||||
// We have all we need to parse the tool_use json
|
||||
if (event?.type === "content_block_stop") {
|
||||
options = {
|
||||
toolCall: [
|
||||
{
|
||||
id: tool.id,
|
||||
name: tool.name,
|
||||
input: JSON.parse(input),
|
||||
} as ToolCall,
|
||||
],
|
||||
};
|
||||
// reset the collection/tool
|
||||
collecting = [];
|
||||
tool = undefined;
|
||||
} else {
|
||||
options = {
|
||||
toolCall: [
|
||||
{
|
||||
id: tool.id,
|
||||
name: tool.name,
|
||||
input,
|
||||
} as PartialToolCall,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
const delta = this.getTextFromStreamResponse(response);
|
||||
if (!delta && !options) continue;
|
||||
|
||||
yield {
|
||||
delta,
|
||||
options,
|
||||
raw: response,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
getRequestBody<T extends ChatMessage<ToolCallLLMMessageOptions>>(
|
||||
metadata: LLMMetadata,
|
||||
messages: T[],
|
||||
tools?: BaseTool[],
|
||||
options?: BedrockAdditionalChatOptions,
|
||||
): InvokeModelCommandInput | InvokeModelWithResponseStreamCommandInput {
|
||||
const extra: Record<string, unknown> = {};
|
||||
if (options?.toolChoice) {
|
||||
extra["tool_choice"] = options?.toolChoice;
|
||||
}
|
||||
const mapped = mapChatMessagesToAnthropicMessages(messages);
|
||||
return {
|
||||
modelId: metadata.model,
|
||||
contentType: "application/json",
|
||||
accept: "application/json",
|
||||
body: JSON.stringify({
|
||||
anthropic_version: "bedrock-2023-05-31",
|
||||
messages: mapped,
|
||||
tools: mapBaseToolsToAnthropicTools(tools),
|
||||
max_tokens: metadata.maxTokens,
|
||||
temperature: metadata.temperature,
|
||||
top_p: metadata.topP,
|
||||
...extra,
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Other providers could go here
|
||||
const PROVIDERS: { [key: string]: Provider } = {
|
||||
anthropic: new AnthropicProvider(),
|
||||
};
|
||||
|
||||
const getProvider = (model: string): Provider => {
|
||||
const providerName = model.split(".")[0];
|
||||
if (!(providerName in PROVIDERS)) {
|
||||
@@ -373,6 +186,10 @@ export class Bedrock extends ToolCallLLM<BedrockAdditionalChatOptions> {
|
||||
this.temperature = temperature ?? DEFAULT_BEDROCK_PARAMS.temperature;
|
||||
this.topP = topP ?? DEFAULT_BEDROCK_PARAMS.topP;
|
||||
this.client = new BedrockRuntimeClient(params);
|
||||
|
||||
if (!this.supportToolCall) {
|
||||
console.warn(`The model "${this.model}" doesn't support ToolCall`);
|
||||
}
|
||||
}
|
||||
|
||||
get supportToolCall(): boolean {
|
||||
@@ -402,10 +219,13 @@ export class Bedrock extends ToolCallLLM<BedrockAdditionalChatOptions> {
|
||||
);
|
||||
const command = new InvokeModelCommand(input);
|
||||
const response = await this.client.send(command);
|
||||
const tools = this.provider.getToolsFromResponse(response);
|
||||
const options: ToolCallLLMMessageOptions = tools.length
|
||||
? { toolCall: tools }
|
||||
: {};
|
||||
let options: ToolCallLLMMessageOptions = {};
|
||||
if (this.supportToolCall) {
|
||||
const tools = this.provider.getToolsFromResponse(response);
|
||||
if (tools.length) {
|
||||
options = { toolCall: tools };
|
||||
}
|
||||
}
|
||||
return {
|
||||
raw: response,
|
||||
message: {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
type InvokeModelCommandInput,
|
||||
type InvokeModelWithResponseStreamCommandInput,
|
||||
ResponseStream,
|
||||
} from "@aws-sdk/client-bedrock-runtime";
|
||||
import {
|
||||
type BaseTool,
|
||||
type ChatMessage,
|
||||
type ChatResponseChunk,
|
||||
type LLMMetadata,
|
||||
streamConverter,
|
||||
type ToolCallLLMMessageOptions,
|
||||
} from "llamaindex";
|
||||
import type { ToolChoice } from "./types";
|
||||
import { toUtf8 } from "./utils";
|
||||
|
||||
export type BedrockAdditionalChatOptions = { toolChoice: ToolChoice };
|
||||
|
||||
export type BedrockChatStreamResponse = AsyncIterable<
|
||||
ChatResponseChunk<ToolCallLLMMessageOptions>
|
||||
>;
|
||||
|
||||
export abstract class Provider<ProviderStreamEvent extends {} = {}> {
|
||||
abstract getTextFromResponse(response: Record<string, any>): string;
|
||||
|
||||
abstract getToolsFromResponse<T extends {} = {}>(
|
||||
response: Record<string, any>,
|
||||
): T[];
|
||||
|
||||
getStreamingEventResponse(
|
||||
response: Record<string, any>,
|
||||
): ProviderStreamEvent | undefined {
|
||||
return response.chunk?.bytes
|
||||
? (JSON.parse(toUtf8(response.chunk?.bytes)) as ProviderStreamEvent)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
async *reduceStream(
|
||||
stream: AsyncIterable<ResponseStream>,
|
||||
): BedrockChatStreamResponse {
|
||||
yield* streamConverter(stream, (response) => {
|
||||
return {
|
||||
delta: this.getTextFromStreamResponse(response),
|
||||
raw: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getTextFromStreamResponse(response: Record<string, any>): string {
|
||||
return this.getTextFromResponse(response);
|
||||
}
|
||||
|
||||
abstract getRequestBody<T extends ChatMessage>(
|
||||
metadata: LLMMetadata,
|
||||
messages: T[],
|
||||
tools?: BaseTool[],
|
||||
options?: BedrockAdditionalChatOptions,
|
||||
): InvokeModelCommandInput | InvokeModelWithResponseStreamCommandInput;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import {
|
||||
type InvokeModelCommandInput,
|
||||
type InvokeModelWithResponseStreamCommandInput,
|
||||
ResponseStream,
|
||||
} from "@aws-sdk/client-bedrock-runtime";
|
||||
import type {
|
||||
BaseTool,
|
||||
ChatMessage,
|
||||
LLMMetadata,
|
||||
PartialToolCall,
|
||||
ToolCall,
|
||||
ToolCallLLMMessageOptions,
|
||||
} from "llamaindex";
|
||||
import {
|
||||
type BedrockAdditionalChatOptions,
|
||||
type BedrockChatStreamResponse,
|
||||
Provider,
|
||||
} from "../provider";
|
||||
import type {
|
||||
AnthropicNoneStreamingResponse,
|
||||
AnthropicStreamEvent,
|
||||
AnthropicTextContent,
|
||||
ToolBlock,
|
||||
} from "../types";
|
||||
import {
|
||||
mapBaseToolsToAnthropicTools,
|
||||
mapChatMessagesToAnthropicMessages,
|
||||
toUtf8,
|
||||
} from "../utils";
|
||||
|
||||
export class AnthropicProvider extends Provider<AnthropicStreamEvent> {
|
||||
getResultFromResponse(
|
||||
response: Record<string, any>,
|
||||
): AnthropicNoneStreamingResponse {
|
||||
return JSON.parse(toUtf8(response.body));
|
||||
}
|
||||
|
||||
getToolsFromResponse<AnthropicToolContent>(
|
||||
response: Record<string, any>,
|
||||
): AnthropicToolContent[] {
|
||||
const result = this.getResultFromResponse(response);
|
||||
return result.content
|
||||
.filter((item) => item.type === "tool_use")
|
||||
.map((item) => item as AnthropicToolContent);
|
||||
}
|
||||
|
||||
getTextFromResponse(response: Record<string, any>): string {
|
||||
const result = this.getResultFromResponse(response);
|
||||
return result.content
|
||||
.filter((item) => item.type === "text")
|
||||
.map((item) => (item as AnthropicTextContent).text)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
getTextFromStreamResponse(response: Record<string, any>): string {
|
||||
const event = this.getStreamingEventResponse(response);
|
||||
if (event?.type === "content_block_delta") {
|
||||
if (event.delta.type === "text_delta") return event.delta.text;
|
||||
if (event.delta.type === "input_json_delta")
|
||||
return event.delta.partial_json;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async *reduceStream(
|
||||
stream: AsyncIterable<ResponseStream>,
|
||||
): BedrockChatStreamResponse {
|
||||
let collecting = [];
|
||||
let tool: ToolBlock | undefined = undefined;
|
||||
// #TODO this should be broken down into a separate consumer
|
||||
for await (const response of stream) {
|
||||
const event = this.getStreamingEventResponse(response);
|
||||
if (
|
||||
event?.type === "content_block_start" &&
|
||||
event.content_block.type === "tool_use"
|
||||
) {
|
||||
tool = event.content_block;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
event?.type === "content_block_delta" &&
|
||||
event.delta.type === "input_json_delta"
|
||||
) {
|
||||
collecting.push(event.delta.partial_json);
|
||||
}
|
||||
|
||||
let options: undefined | ToolCallLLMMessageOptions = undefined;
|
||||
if (tool && collecting.length) {
|
||||
const input = collecting.filter((item) => item).join("");
|
||||
// We have all we need to parse the tool_use json
|
||||
if (event?.type === "content_block_stop") {
|
||||
options = {
|
||||
toolCall: [
|
||||
{
|
||||
id: tool.id,
|
||||
name: tool.name,
|
||||
input: JSON.parse(input),
|
||||
} as ToolCall,
|
||||
],
|
||||
};
|
||||
// reset the collection/tool
|
||||
collecting = [];
|
||||
tool = undefined;
|
||||
} else {
|
||||
options = {
|
||||
toolCall: [
|
||||
{
|
||||
id: tool.id,
|
||||
name: tool.name,
|
||||
input,
|
||||
} as PartialToolCall,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
const delta = this.getTextFromStreamResponse(response);
|
||||
if (!delta && !options) continue;
|
||||
|
||||
yield {
|
||||
delta,
|
||||
options,
|
||||
raw: response,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
getRequestBody<T extends ChatMessage<ToolCallLLMMessageOptions>>(
|
||||
metadata: LLMMetadata,
|
||||
messages: T[],
|
||||
tools?: BaseTool[],
|
||||
options?: BedrockAdditionalChatOptions,
|
||||
): InvokeModelCommandInput | InvokeModelWithResponseStreamCommandInput {
|
||||
const extra: Record<string, unknown> = {};
|
||||
if (options?.toolChoice) {
|
||||
extra["tool_choice"] = options?.toolChoice;
|
||||
}
|
||||
const mapped = mapChatMessagesToAnthropicMessages(messages);
|
||||
return {
|
||||
modelId: metadata.model,
|
||||
contentType: "application/json",
|
||||
accept: "application/json",
|
||||
body: JSON.stringify({
|
||||
anthropic_version: "bedrock-2023-05-31",
|
||||
messages: mapped,
|
||||
tools: mapBaseToolsToAnthropicTools(tools),
|
||||
max_tokens: metadata.maxTokens,
|
||||
temperature: metadata.temperature,
|
||||
top_p: metadata.topP,
|
||||
...extra,
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Provider } from "../provider";
|
||||
import { AnthropicProvider } from "./anthropic";
|
||||
import { MetaProvider } from "./meta";
|
||||
|
||||
// Other providers should go here
|
||||
export const PROVIDERS: { [key: string]: Provider } = {
|
||||
anthropic: new AnthropicProvider(),
|
||||
meta: new MetaProvider(),
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
import type {
|
||||
InvokeModelCommandInput,
|
||||
InvokeModelWithResponseStreamCommandInput,
|
||||
} from "@aws-sdk/client-bedrock-runtime";
|
||||
import type { ChatMessage, LLMMetadata } from "llamaindex";
|
||||
import type { MetaNoneStreamingResponse, MetaStreamEvent } from "../types";
|
||||
import {
|
||||
mapChatMessagesToMetaLlama2Messages,
|
||||
mapChatMessagesToMetaLlama3Messages,
|
||||
toUtf8,
|
||||
} from "../utils";
|
||||
|
||||
import { Provider } from "../provider";
|
||||
|
||||
export class MetaProvider extends Provider<MetaStreamEvent> {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getResultFromResponse(
|
||||
response: Record<string, any>,
|
||||
): MetaNoneStreamingResponse {
|
||||
return JSON.parse(toUtf8(response.body));
|
||||
}
|
||||
|
||||
getToolsFromResponse(_response: Record<string, any>): never {
|
||||
throw new Error("Not supported by this provider.");
|
||||
}
|
||||
|
||||
getTextFromResponse(response: Record<string, any>): string {
|
||||
const result = this.getResultFromResponse(response);
|
||||
return result.generation;
|
||||
}
|
||||
|
||||
getTextFromStreamResponse(response: Record<string, any>): string {
|
||||
const event = this.getStreamingEventResponse(response);
|
||||
if (event?.generation) {
|
||||
return event.generation;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
getRequestBody<T extends ChatMessage>(
|
||||
metadata: LLMMetadata,
|
||||
messages: T[],
|
||||
): InvokeModelCommandInput | InvokeModelWithResponseStreamCommandInput {
|
||||
let promptFunction: (messages: ChatMessage[]) => string;
|
||||
|
||||
if (metadata.model.startsWith("meta.llama3")) {
|
||||
promptFunction = mapChatMessagesToMetaLlama3Messages;
|
||||
} else if (metadata.model.startsWith("meta.llama2")) {
|
||||
promptFunction = mapChatMessagesToMetaLlama2Messages;
|
||||
} else {
|
||||
throw new Error(`Meta model ${metadata.model} is not supported`);
|
||||
}
|
||||
|
||||
return {
|
||||
modelId: metadata.model,
|
||||
contentType: "application/json",
|
||||
accept: "application/json",
|
||||
body: JSON.stringify({
|
||||
prompt: promptFunction(messages),
|
||||
max_gen_len: metadata.maxTokens,
|
||||
temperature: metadata.temperature,
|
||||
top_p: metadata.topP,
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ export type ToolChoice =
|
||||
| { type: "auto" }
|
||||
| { type: "tool"; name: string };
|
||||
|
||||
export type StreamEvent =
|
||||
export type AnthropicStreamEvent =
|
||||
| { type: "message_start"; message: Message }
|
||||
| ContentBlockStart
|
||||
| ContentBlockDelta
|
||||
@@ -93,6 +93,8 @@ export type AnthropicContent =
|
||||
| AnthropicToolContent
|
||||
| AnthropicToolResultContent;
|
||||
|
||||
export type MetaTextContent = string;
|
||||
|
||||
export type AnthropicTextContent = {
|
||||
type: "text";
|
||||
text: string;
|
||||
@@ -133,6 +135,11 @@ export type AnthropicMessage = {
|
||||
content: AnthropicContent[];
|
||||
};
|
||||
|
||||
export type MetaMessage = {
|
||||
role: "user" | "assistant" | "system";
|
||||
content: MetaTextContent;
|
||||
};
|
||||
|
||||
export type AnthropicNoneStreamingResponse = {
|
||||
id: string;
|
||||
type: "message";
|
||||
@@ -143,3 +150,16 @@ export type AnthropicNoneStreamingResponse = {
|
||||
stop_sequence?: string;
|
||||
usage: { input_tokens: number; output_tokens: number };
|
||||
};
|
||||
|
||||
type MetaResponse = {
|
||||
generation: string;
|
||||
prompt_token_count: number;
|
||||
generation_token_count: number;
|
||||
stop_reason: "stop" | "length";
|
||||
};
|
||||
|
||||
export type MetaStreamEvent = MetaResponse & {
|
||||
"amazon-bedrock-invocationMetrics": InvocationMetrics;
|
||||
};
|
||||
|
||||
export type MetaNoneStreamingResponse = MetaResponse;
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
JSONObject,
|
||||
MessageContent,
|
||||
MessageContentDetail,
|
||||
MessageContentTextDetail,
|
||||
ToolCallLLMMessageOptions,
|
||||
ToolMetadata,
|
||||
} from "llamaindex";
|
||||
@@ -13,6 +14,7 @@ import type {
|
||||
AnthropicMediaTypes,
|
||||
AnthropicMessage,
|
||||
AnthropicTextContent,
|
||||
MetaMessage,
|
||||
} from "./types.js";
|
||||
|
||||
const ACCEPTED_IMAGE_MIME_TYPES = [
|
||||
@@ -148,6 +150,85 @@ export const mapChatMessagesToAnthropicMessages = <
|
||||
return mergeNeighboringSameRoleMessages(mapped);
|
||||
};
|
||||
|
||||
export const mapChatMessagesToMetaMessages = <T extends ChatMessage>(
|
||||
messages: T[],
|
||||
): MetaMessage[] => {
|
||||
return messages.map((msg) => {
|
||||
let content: string;
|
||||
if (typeof msg.content === "string") {
|
||||
content = msg.content;
|
||||
} else {
|
||||
content = (msg.content[0] as MessageContentTextDetail).text;
|
||||
}
|
||||
return {
|
||||
role:
|
||||
msg.role === "assistant"
|
||||
? "assistant"
|
||||
: msg.role === "user"
|
||||
? "user"
|
||||
: "system",
|
||||
content,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Documentation at https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3
|
||||
*/
|
||||
export const mapChatMessagesToMetaLlama3Messages = <T extends ChatMessage>(
|
||||
messages: T[],
|
||||
): string => {
|
||||
const mapped = mapChatMessagesToMetaMessages(messages).map((message) => {
|
||||
const text = message.content;
|
||||
return `<|start_header_id|>${message.role}<|end_header_id|>\n${text}\n<|eot_id|>\n`;
|
||||
});
|
||||
return (
|
||||
"<|begin_of_text|>" +
|
||||
mapped.join("\n") +
|
||||
"\n<|start_header_id|>assistant<|end_header_id|>\n"
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Documentation at https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-2
|
||||
*/
|
||||
export const mapChatMessagesToMetaLlama2Messages = <T extends ChatMessage>(
|
||||
messages: T[],
|
||||
): string => {
|
||||
const mapped = mapChatMessagesToMetaMessages(messages);
|
||||
let output = "<s>";
|
||||
let insideInst = false;
|
||||
let needsStartAgain = false;
|
||||
for (const message of mapped) {
|
||||
if (needsStartAgain) {
|
||||
output += "<s>";
|
||||
needsStartAgain = false;
|
||||
}
|
||||
const text = message.content;
|
||||
if (message.role === "system") {
|
||||
if (!insideInst) {
|
||||
output += "[INST] ";
|
||||
insideInst = true;
|
||||
}
|
||||
output += `<<SYS>>\n${text}\n<</SYS>>\n`;
|
||||
} else if (message.role === "user") {
|
||||
output += text;
|
||||
if (insideInst) {
|
||||
output += " [/INST]";
|
||||
insideInst = false;
|
||||
}
|
||||
} else if (message.role === "assistant") {
|
||||
if (insideInst) {
|
||||
output += " [/INST]";
|
||||
insideInst = false;
|
||||
}
|
||||
output += ` ${text} </s>\n`;
|
||||
needsStartAgain = true;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
export const mapTextContent = (text: string): AnthropicTextContent => {
|
||||
return { type: "text", text };
|
||||
};
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# @llamaindex/core
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f326ab8: chore: bump version
|
||||
- Updated dependencies [f326ab8]
|
||||
- @llamaindex/env@0.1.8
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f10b41d: fix: release files
|
||||
- Updated dependencies [41fe871]
|
||||
- @llamaindex/env@0.1.7
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"name": "@llamaindex/core",
|
||||
"type": "module",
|
||||
"version": "0.0.3",
|
||||
"description": "LlamaIndex Core Module",
|
||||
"exports": {
|
||||
"./llms": {
|
||||
"require": {
|
||||
"types": "./dist/llms/index.d.cts",
|
||||
"default": "./dist/llms/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/llms/index.d.ts",
|
||||
"default": "./dist/llms/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/llms/index.d.ts",
|
||||
"default": "./dist/llms/index.js"
|
||||
}
|
||||
},
|
||||
"./decorator": {
|
||||
"require": {
|
||||
"types": "./dist/decorator/index.d.cts",
|
||||
"default": "./dist/decorator/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/decorator/index.d.ts",
|
||||
"default": "./dist/decorator/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/decorator/index.d.ts",
|
||||
"default": "./dist/decorator/index.js"
|
||||
}
|
||||
},
|
||||
"./global": {
|
||||
"require": {
|
||||
"types": "./dist/global/index.d.cts",
|
||||
"default": "./dist/global/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/global/index.d.ts",
|
||||
"default": "./dist/global/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/global/index.d.ts",
|
||||
"default": "./dist/global/index.js"
|
||||
}
|
||||
},
|
||||
"./schema": {
|
||||
"require": {
|
||||
"types": "./dist/schema/index.d.cts",
|
||||
"default": "./dist/schema/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/schema/index.d.ts",
|
||||
"default": "./dist/schema/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/schema/index.d.ts",
|
||||
"default": "./dist/schema/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "bunchee --watch",
|
||||
"build": "bunchee"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"directory": "packages/core",
|
||||
"url": "https://github.com/himself65/LlamaIndexTS.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "^8.16.0",
|
||||
"bunchee": "^5.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"@types/node": "^20.14.9",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import type { BaseNode } from "../../Node.js";
|
||||
import { getChunkSize } from "../settings/chunk-size.js";
|
||||
import { Settings } from "../global";
|
||||
import type { BaseNode } from "../schema/node";
|
||||
|
||||
const emitOnce = false;
|
||||
|
||||
export function chunkSizeCheck<
|
||||
This extends BaseNode,
|
||||
This extends { id_: string },
|
||||
Args extends any[],
|
||||
Return,
|
||||
>(
|
||||
@@ -17,7 +17,7 @@ export function chunkSizeCheck<
|
||||
) {
|
||||
return function (this: This, ...args: Args) {
|
||||
const content = contentGetter.call(this, ...args);
|
||||
const chunkSize = getChunkSize();
|
||||
const chunkSize = Settings.chunkSize;
|
||||
const enableChunkSizeCheck = getEnv("ENABLE_CHUNK_SIZE_CHECK") === "true";
|
||||
if (
|
||||
enableChunkSizeCheck &&
|
||||
@@ -25,7 +25,7 @@ export function chunkSizeCheck<
|
||||
content.length > chunkSize
|
||||
) {
|
||||
console.warn(
|
||||
`Node (${this.id_}) is larger than chunk size: ${content.length}`,
|
||||
`Node (${this.id_}) is larger than chunk size: ${content.length} > ${chunkSize}`,
|
||||
);
|
||||
if (!emitOnce) {
|
||||
console.warn(
|
||||
@@ -0,0 +1 @@
|
||||
export { Settings } from "./settings";
|
||||
@@ -0,0 +1,17 @@
|
||||
import {
|
||||
getChunkSize,
|
||||
setChunkSize,
|
||||
withChunkSize,
|
||||
} from "./settings/chunk-size";
|
||||
|
||||
export const Settings = {
|
||||
get chunkSize(): number | undefined {
|
||||
return getChunkSize();
|
||||
},
|
||||
set chunkSize(chunkSize: number | undefined) {
|
||||
setChunkSize(chunkSize);
|
||||
},
|
||||
withChunkSize<Result>(chunkSize: number, fn: () => Result): Result {
|
||||
return withChunkSize(chunkSize, fn);
|
||||
},
|
||||
};
|
||||
+4
-2
@@ -1,14 +1,16 @@
|
||||
import { AsyncLocalStorage } from "@llamaindex/env";
|
||||
|
||||
const chunkSizeAsyncLocalStorage = new AsyncLocalStorage<number | undefined>();
|
||||
const globalChunkSize: number | null = null;
|
||||
let globalChunkSize: number | null = null;
|
||||
|
||||
export function getChunkSize(): number | undefined {
|
||||
return globalChunkSize ?? chunkSizeAsyncLocalStorage.getStore();
|
||||
}
|
||||
|
||||
export function setChunkSize(chunkSize: number | undefined) {
|
||||
chunkSizeAsyncLocalStorage.enterWith(chunkSize);
|
||||
if (chunkSize !== undefined) {
|
||||
globalChunkSize = chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
export function withChunkSize<Result>(
|
||||
@@ -0,0 +1,9 @@
|
||||
export type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
||||
|
||||
export type JSONValue = string | number | boolean | JSONObject | JSONArray;
|
||||
|
||||
export type JSONObject = {
|
||||
[key: string]: JSONValue;
|
||||
};
|
||||
|
||||
export type JSONArray = Array<JSONValue>;
|
||||
@@ -0,0 +1,31 @@
|
||||
export type {
|
||||
BaseTool,
|
||||
BaseToolWithCall,
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
ChatResponseChunk,
|
||||
CompletionResponse,
|
||||
LLM,
|
||||
LLMChat,
|
||||
LLMChatParamsBase,
|
||||
LLMChatParamsNonStreaming,
|
||||
LLMChatParamsStreaming,
|
||||
LLMCompletionParamsBase,
|
||||
LLMCompletionParamsNonStreaming,
|
||||
LLMCompletionParamsStreaming,
|
||||
LLMMetadata,
|
||||
MessageContent,
|
||||
MessageContentDetail,
|
||||
MessageContentImageDetail,
|
||||
MessageContentTextDetail,
|
||||
MessageType,
|
||||
PartialToolCall,
|
||||
TextChatMessage,
|
||||
ToolCall,
|
||||
ToolCallLLMMessageOptions,
|
||||
ToolCallOptions,
|
||||
ToolMetadata,
|
||||
ToolOutput,
|
||||
ToolResult,
|
||||
ToolResultOptions,
|
||||
} from "./type";
|
||||
@@ -0,0 +1,245 @@
|
||||
import type { Tokenizers } from "@llamaindex/env";
|
||||
import type { JSONSchemaType } from "ajv";
|
||||
import type { JSONObject, JSONValue } from "../global/type";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface LLMChat<
|
||||
AdditionalChatOptions extends object = object,
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
chat(
|
||||
params:
|
||||
| LLMChatParamsStreaming<AdditionalChatOptions>
|
||||
| LLMChatParamsNonStreaming<AdditionalChatOptions>,
|
||||
): Promise<
|
||||
| ChatResponse<AdditionalMessageOptions>
|
||||
| AsyncIterable<ChatResponseChunk<AdditionalMessageOptions>>
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified language model interface
|
||||
*/
|
||||
export interface LLM<
|
||||
AdditionalChatOptions extends object = object,
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends LLMChat<AdditionalChatOptions> {
|
||||
metadata: LLMMetadata;
|
||||
/**
|
||||
* Get a chat response from the LLM
|
||||
*/
|
||||
chat(
|
||||
params: LLMChatParamsStreaming<
|
||||
AdditionalChatOptions,
|
||||
AdditionalMessageOptions
|
||||
>,
|
||||
): Promise<AsyncIterable<ChatResponseChunk>>;
|
||||
chat(
|
||||
params: LLMChatParamsNonStreaming<
|
||||
AdditionalChatOptions,
|
||||
AdditionalMessageOptions
|
||||
>,
|
||||
): Promise<ChatResponse<AdditionalMessageOptions>>;
|
||||
|
||||
/**
|
||||
* Get a prompt completion from the LLM
|
||||
*/
|
||||
complete(
|
||||
params: LLMCompletionParamsStreaming,
|
||||
): Promise<AsyncIterable<CompletionResponse>>;
|
||||
complete(
|
||||
params: LLMCompletionParamsNonStreaming,
|
||||
): Promise<CompletionResponse>;
|
||||
}
|
||||
|
||||
export type MessageType = "user" | "assistant" | "system" | "memory";
|
||||
|
||||
export type TextChatMessage<AdditionalMessageOptions extends object = object> =
|
||||
{
|
||||
content: string;
|
||||
role: MessageType;
|
||||
options?: undefined | AdditionalMessageOptions;
|
||||
};
|
||||
|
||||
export type ChatMessage<AdditionalMessageOptions extends object = object> = {
|
||||
content: MessageContent;
|
||||
role: MessageType;
|
||||
options?: undefined | AdditionalMessageOptions;
|
||||
};
|
||||
|
||||
export interface ChatResponse<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
message: ChatMessage<AdditionalMessageOptions>;
|
||||
/**
|
||||
* Raw response from the LLM
|
||||
*
|
||||
* If LLM response an iterable of chunks, this will be an array of those chunks
|
||||
*/
|
||||
raw: object | null;
|
||||
}
|
||||
|
||||
export type ChatResponseChunk<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> = {
|
||||
raw: object | null;
|
||||
delta: string;
|
||||
options?: undefined | AdditionalMessageOptions;
|
||||
};
|
||||
|
||||
export interface CompletionResponse {
|
||||
text: string;
|
||||
/**
|
||||
* Raw response from the LLM
|
||||
*
|
||||
* It's possible that this is `null` if the LLM response an iterable of chunks
|
||||
*/
|
||||
raw: object | null;
|
||||
}
|
||||
|
||||
export type LLMMetadata = {
|
||||
model: string;
|
||||
temperature: number;
|
||||
topP: number;
|
||||
maxTokens?: number;
|
||||
contextWindow: number;
|
||||
tokenizer: Tokenizers | undefined;
|
||||
};
|
||||
|
||||
export interface LLMChatParamsBase<
|
||||
AdditionalChatOptions extends object = object,
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
messages: ChatMessage<AdditionalMessageOptions>[];
|
||||
additionalChatOptions?: AdditionalChatOptions;
|
||||
tools?: BaseTool[];
|
||||
}
|
||||
|
||||
export interface LLMChatParamsStreaming<
|
||||
AdditionalChatOptions extends object = object,
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends LLMChatParamsBase<AdditionalChatOptions, AdditionalMessageOptions> {
|
||||
stream: true;
|
||||
}
|
||||
|
||||
export interface LLMChatParamsNonStreaming<
|
||||
AdditionalChatOptions extends object = object,
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends LLMChatParamsBase<AdditionalChatOptions, AdditionalMessageOptions> {
|
||||
stream?: false;
|
||||
}
|
||||
|
||||
export interface LLMCompletionParamsBase {
|
||||
prompt: MessageContent;
|
||||
}
|
||||
|
||||
export interface LLMCompletionParamsStreaming extends LLMCompletionParamsBase {
|
||||
stream: true;
|
||||
}
|
||||
|
||||
export interface LLMCompletionParamsNonStreaming
|
||||
extends LLMCompletionParamsBase {
|
||||
stream?: false | null;
|
||||
}
|
||||
|
||||
export type MessageContentTextDetail = {
|
||||
type: "text";
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type MessageContentImageDetail = {
|
||||
type: "image_url";
|
||||
image_url: { url: string };
|
||||
};
|
||||
|
||||
export type MessageContentDetail =
|
||||
| MessageContentTextDetail
|
||||
| MessageContentImageDetail;
|
||||
|
||||
/**
|
||||
* Extended type for the content of a message that allows for multi-modal messages.
|
||||
*/
|
||||
export type MessageContent = string | MessageContentDetail[];
|
||||
|
||||
export type ToolCall = {
|
||||
name: string;
|
||||
input: JSONObject;
|
||||
id: string;
|
||||
};
|
||||
|
||||
// happened in streaming response, the tool call is not ready yet
|
||||
export type PartialToolCall = {
|
||||
name: string;
|
||||
id: string;
|
||||
// input is not ready yet, JSON.parse(input) will throw an error
|
||||
input: string;
|
||||
};
|
||||
|
||||
export type ToolResult = {
|
||||
id: string;
|
||||
result: string;
|
||||
isError: boolean;
|
||||
};
|
||||
|
||||
export type ToolCallOptions = {
|
||||
toolCall: (ToolCall | PartialToolCall)[];
|
||||
};
|
||||
|
||||
export type ToolResultOptions = {
|
||||
toolResult: ToolResult;
|
||||
};
|
||||
|
||||
export type ToolCallLLMMessageOptions =
|
||||
| ToolResultOptions
|
||||
| ToolCallOptions
|
||||
| {};
|
||||
|
||||
type Known =
|
||||
| { [key: string]: Known }
|
||||
| [Known, ...Known[]]
|
||||
| Known[]
|
||||
| number
|
||||
| string
|
||||
| boolean
|
||||
| null;
|
||||
|
||||
export type ToolMetadata<
|
||||
Parameters extends Record<string, unknown> = Record<string, unknown>,
|
||||
> = {
|
||||
description: string;
|
||||
name: string;
|
||||
/**
|
||||
* OpenAI uses JSON Schema to describe the parameters that a tool can take.
|
||||
* @link https://json-schema.org/understanding-json-schema
|
||||
*/
|
||||
parameters?: Parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple Tool interface. Likely to change.
|
||||
*/
|
||||
export interface BaseTool<Input = any> {
|
||||
/**
|
||||
* This could be undefined if the implementation is not provided,
|
||||
* which might be the case when communicating with a llm.
|
||||
*
|
||||
* @return {JSONValue | Promise<JSONValue>} The output of the tool.
|
||||
*/
|
||||
call?: (input: Input) => JSONValue | Promise<JSONValue>;
|
||||
metadata: // if user input any, we cannot check the schema
|
||||
Input extends Known ? ToolMetadata<JSONSchemaType<Input>> : ToolMetadata;
|
||||
}
|
||||
|
||||
export type BaseToolWithCall<Input = any> = Omit<BaseTool<Input>, "call"> & {
|
||||
call: NonNullable<Pick<BaseTool<Input>, "call">["call"]>;
|
||||
};
|
||||
|
||||
export type ToolOutput = {
|
||||
tool: BaseTool | undefined;
|
||||
// all of existing function calling LLMs only support object input
|
||||
input: JSONObject;
|
||||
output: JSONValue;
|
||||
isError: boolean;
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./node";
|
||||
export * from "./zod";
|
||||
@@ -0,0 +1,452 @@
|
||||
import { createSHA256, path, randomUUID } from "@llamaindex/env";
|
||||
import { chunkSizeCheck, lazyInitHash } from "../decorator";
|
||||
|
||||
export enum NodeRelationship {
|
||||
SOURCE = "SOURCE",
|
||||
PREVIOUS = "PREVIOUS",
|
||||
NEXT = "NEXT",
|
||||
PARENT = "PARENT",
|
||||
CHILD = "CHILD",
|
||||
}
|
||||
|
||||
export enum ObjectType {
|
||||
TEXT = "TEXT",
|
||||
IMAGE = "IMAGE",
|
||||
INDEX = "INDEX",
|
||||
DOCUMENT = "DOCUMENT",
|
||||
IMAGE_DOCUMENT = "IMAGE_DOCUMENT",
|
||||
}
|
||||
|
||||
export enum MetadataMode {
|
||||
ALL = "ALL",
|
||||
EMBED = "EMBED",
|
||||
LLM = "LLM",
|
||||
NONE = "NONE",
|
||||
}
|
||||
|
||||
export type Metadata = Record<string, any>;
|
||||
|
||||
export interface RelatedNodeInfo<T extends Metadata = Metadata> {
|
||||
nodeId: string;
|
||||
nodeType?: ObjectType;
|
||||
metadata: T;
|
||||
hash?: string;
|
||||
}
|
||||
|
||||
export type RelatedNodeType<T extends Metadata = Metadata> =
|
||||
| RelatedNodeInfo<T>
|
||||
| RelatedNodeInfo<T>[];
|
||||
|
||||
export type BaseNodeParams<T extends Metadata = Metadata> = {
|
||||
id_?: string;
|
||||
metadata?: T;
|
||||
excludedEmbedMetadataKeys?: string[];
|
||||
excludedLlmMetadataKeys?: string[];
|
||||
relationships?: Partial<Record<NodeRelationship, RelatedNodeType<T>>>;
|
||||
hash?: string;
|
||||
embedding?: number[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic abstract class for retrievable nodes
|
||||
*/
|
||||
export abstract class BaseNode<T extends Metadata = Metadata> {
|
||||
/**
|
||||
* The unique ID of the Node/Document. The trailing underscore is here
|
||||
* to avoid collisions with the id keyword in Python.
|
||||
*
|
||||
* Set to a UUID by default.
|
||||
*/
|
||||
id_: string;
|
||||
embedding?: number[];
|
||||
|
||||
// Metadata fields
|
||||
metadata: T;
|
||||
excludedEmbedMetadataKeys: string[];
|
||||
excludedLlmMetadataKeys: string[];
|
||||
relationships: Partial<Record<NodeRelationship, RelatedNodeType<T>>>;
|
||||
|
||||
@lazyInitHash
|
||||
accessor hash: string = "";
|
||||
|
||||
protected constructor(init?: BaseNodeParams<T>) {
|
||||
const {
|
||||
id_,
|
||||
metadata,
|
||||
excludedEmbedMetadataKeys,
|
||||
excludedLlmMetadataKeys,
|
||||
relationships,
|
||||
hash,
|
||||
embedding,
|
||||
} = init || {};
|
||||
this.id_ = id_ ?? randomUUID();
|
||||
this.metadata = metadata ?? ({} as T);
|
||||
this.excludedEmbedMetadataKeys = excludedEmbedMetadataKeys ?? [];
|
||||
this.excludedLlmMetadataKeys = excludedLlmMetadataKeys ?? [];
|
||||
this.relationships = relationships ?? {};
|
||||
this.embedding = embedding;
|
||||
}
|
||||
|
||||
abstract get type(): ObjectType;
|
||||
|
||||
abstract getContent(metadataMode: MetadataMode): string;
|
||||
|
||||
abstract getMetadataStr(metadataMode: MetadataMode): string;
|
||||
|
||||
// todo: set value as a generic type
|
||||
abstract setContent(value: unknown): void;
|
||||
|
||||
get sourceNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.SOURCE];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Source object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get prevNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.PREVIOUS];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error(
|
||||
"Previous object must be a single RelatedNodeInfo object",
|
||||
);
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get nextNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.NEXT];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Next object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get parentNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.PARENT];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Parent object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get childNodes(): RelatedNodeInfo<T>[] | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.CHILD];
|
||||
|
||||
if (!Array.isArray(relationship)) {
|
||||
throw new Error(
|
||||
"Child object must be a an array of RelatedNodeInfo objects",
|
||||
);
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
abstract generateHash(): string;
|
||||
|
||||
getEmbedding(): number[] {
|
||||
if (this.embedding === undefined) {
|
||||
throw new Error("Embedding not set");
|
||||
}
|
||||
|
||||
return this.embedding;
|
||||
}
|
||||
|
||||
asRelatedNodeInfo(): RelatedNodeInfo<T> {
|
||||
return {
|
||||
nodeId: this.id_,
|
||||
metadata: this.metadata,
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by built in JSON.stringify (see https://javascript.info/json)
|
||||
* Properties are read-only as they are not deep-cloned (not necessary for stringification).
|
||||
* @see toMutableJSON - use to return a mutable JSON instead
|
||||
*/
|
||||
toJSON(): Record<string, any> {
|
||||
return {
|
||||
...this,
|
||||
type: this.type,
|
||||
// hash is an accessor property, so it's not included in the rest operator
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
|
||||
clone(): BaseNode {
|
||||
return jsonToNode(this.toMutableJSON()) as BaseNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the object to a JSON representation.
|
||||
* Properties can be safely modified as a deep clone of the properties are created.
|
||||
* @return {Record<string, any>} - The JSON representation of the object.
|
||||
*/
|
||||
toMutableJSON(): Record<string, any> {
|
||||
return structuredClone(this.toJSON());
|
||||
}
|
||||
}
|
||||
|
||||
export type TextNodeParams<T extends Metadata = Metadata> =
|
||||
BaseNodeParams<T> & {
|
||||
text?: string;
|
||||
textTemplate?: string;
|
||||
startCharIdx?: number;
|
||||
endCharIdx?: number;
|
||||
metadataSeparator?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextNode is the default node type for text. Most common node type in LlamaIndex.TS
|
||||
*/
|
||||
export class TextNode<T extends Metadata = Metadata> extends BaseNode<T> {
|
||||
text: string;
|
||||
textTemplate: string;
|
||||
|
||||
startCharIdx?: number;
|
||||
endCharIdx?: number;
|
||||
// textTemplate: NOTE write your own formatter if needed
|
||||
// metadataTemplate: NOTE write your own formatter if needed
|
||||
metadataSeparator: string;
|
||||
|
||||
constructor(init: TextNodeParams<T> = {}) {
|
||||
super(init);
|
||||
const { text, textTemplate, startCharIdx, endCharIdx, metadataSeparator } =
|
||||
init;
|
||||
this.text = text ?? "";
|
||||
this.textTemplate = textTemplate ?? "";
|
||||
if (startCharIdx) {
|
||||
this.startCharIdx = startCharIdx;
|
||||
}
|
||||
if (endCharIdx) {
|
||||
this.endCharIdx = endCharIdx;
|
||||
}
|
||||
this.metadataSeparator = metadataSeparator ?? "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash of the text node.
|
||||
* The ID is not part of the hash as it can change independent of content.
|
||||
* @returns
|
||||
*/
|
||||
generateHash() {
|
||||
const hashFunction = createSHA256();
|
||||
hashFunction.update(`type=${this.type}`);
|
||||
hashFunction.update(
|
||||
`startCharIdx=${this.startCharIdx} endCharIdx=${this.endCharIdx}`,
|
||||
);
|
||||
hashFunction.update(this.getContent(MetadataMode.ALL));
|
||||
return hashFunction.digest();
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.TEXT;
|
||||
}
|
||||
|
||||
@chunkSizeCheck
|
||||
getContent(metadataMode: MetadataMode = MetadataMode.NONE): string {
|
||||
const metadataStr = this.getMetadataStr(metadataMode).trim();
|
||||
return `${metadataStr}\n\n${this.text}`.trim();
|
||||
}
|
||||
|
||||
getMetadataStr(metadataMode: MetadataMode): string {
|
||||
if (metadataMode === MetadataMode.NONE) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const usableMetadataKeys = new Set(Object.keys(this.metadata).sort());
|
||||
if (metadataMode === MetadataMode.LLM) {
|
||||
for (const key of this.excludedLlmMetadataKeys) {
|
||||
usableMetadataKeys.delete(key);
|
||||
}
|
||||
} else if (metadataMode === MetadataMode.EMBED) {
|
||||
for (const key of this.excludedEmbedMetadataKeys) {
|
||||
usableMetadataKeys.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
return [...usableMetadataKeys]
|
||||
.map((key) => `${key}: ${this.metadata[key]}`)
|
||||
.join(this.metadataSeparator);
|
||||
}
|
||||
|
||||
setContent(value: string) {
|
||||
this.text = value;
|
||||
this.hash = this.generateHash();
|
||||
}
|
||||
|
||||
getNodeInfo() {
|
||||
return { start: this.startCharIdx, end: this.endCharIdx };
|
||||
}
|
||||
|
||||
getText() {
|
||||
return this.getContent(MetadataMode.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
export type IndexNodeParams<T extends Metadata = Metadata> =
|
||||
TextNodeParams<T> & {
|
||||
indexId: string;
|
||||
};
|
||||
|
||||
export class IndexNode<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
indexId: string;
|
||||
|
||||
constructor(init?: IndexNodeParams<T>) {
|
||||
super(init);
|
||||
const { indexId } = init || {};
|
||||
this.indexId = indexId ?? "";
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A document is just a special text node with a docId.
|
||||
*/
|
||||
export class Document<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
constructor(init?: TextNodeParams<T>) {
|
||||
super(init);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.DOCUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
export function jsonToNode(json: any, type?: ObjectType) {
|
||||
if (!json.type && !type) {
|
||||
throw new Error("Node type not found");
|
||||
}
|
||||
const nodeType = type || json.type;
|
||||
|
||||
switch (nodeType) {
|
||||
case ObjectType.TEXT:
|
||||
return new TextNode(json);
|
||||
case ObjectType.INDEX:
|
||||
return new IndexNode(json);
|
||||
case ObjectType.DOCUMENT:
|
||||
return new Document(json);
|
||||
case ObjectType.IMAGE_DOCUMENT:
|
||||
return new ImageDocument(json);
|
||||
default:
|
||||
throw new Error(`Invalid node type: ${nodeType}`);
|
||||
}
|
||||
}
|
||||
|
||||
export type ImageType = string | Blob | URL;
|
||||
|
||||
export type ImageNodeParams<T extends Metadata = Metadata> =
|
||||
TextNodeParams<T> & {
|
||||
image: ImageType;
|
||||
};
|
||||
|
||||
export class ImageNode<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
image: ImageType; // image as blob
|
||||
|
||||
constructor(init: ImageNodeParams<T>) {
|
||||
super(init);
|
||||
const { image } = init;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.IMAGE;
|
||||
}
|
||||
|
||||
getUrl(): URL {
|
||||
// id_ stores the relative path, convert it to the URL of the file
|
||||
const absPath = path.resolve(this.id_);
|
||||
return new URL(`file://${absPath}`);
|
||||
}
|
||||
|
||||
// Calculates the image part of the hash
|
||||
private generateImageHash() {
|
||||
const hashFunction = createSHA256();
|
||||
|
||||
if (this.image instanceof Blob) {
|
||||
// TODO: ideally we should use the blob's content to calculate the hash:
|
||||
// hashFunction.update(new Uint8Array(await this.image.arrayBuffer()));
|
||||
// as this is async, we're using the node's ID for the time being
|
||||
hashFunction.update(this.id_);
|
||||
} else if (this.image instanceof URL) {
|
||||
hashFunction.update(this.image.toString());
|
||||
} else if (typeof this.image === "string") {
|
||||
hashFunction.update(this.image);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unknown image type: ${typeof this.image}. Can't calculate hash`,
|
||||
);
|
||||
}
|
||||
|
||||
return hashFunction.digest();
|
||||
}
|
||||
|
||||
generateHash() {
|
||||
const hashFunction = createSHA256();
|
||||
// calculates hash based on hash of both components (image and text)
|
||||
hashFunction.update(super.generateHash());
|
||||
hashFunction.update(this.generateImageHash());
|
||||
|
||||
return hashFunction.digest();
|
||||
}
|
||||
}
|
||||
|
||||
export class ImageDocument<T extends Metadata = Metadata> extends ImageNode<T> {
|
||||
constructor(init: ImageNodeParams<T>) {
|
||||
super(init);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.IMAGE_DOCUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node with a similarity score
|
||||
*/
|
||||
export interface NodeWithScore<T extends Metadata = Metadata> {
|
||||
node: BaseNode<T>;
|
||||
score?: number;
|
||||
}
|
||||
|
||||
export enum ModalityType {
|
||||
TEXT = "TEXT",
|
||||
IMAGE = "IMAGE",
|
||||
}
|
||||
|
||||
type NodesByType = {
|
||||
[P in ModalityType]?: BaseNode[];
|
||||
};
|
||||
|
||||
export function splitNodesByType(nodes: BaseNode[]): NodesByType {
|
||||
const result: NodesByType = {};
|
||||
|
||||
for (const node of nodes) {
|
||||
let type: ModalityType;
|
||||
if (node instanceof ImageNode) {
|
||||
type = ModalityType.IMAGE;
|
||||
} else if (node instanceof TextNode) {
|
||||
type = ModalityType.TEXT;
|
||||
} else {
|
||||
throw new Error(`Unknown node type: ${node.type}`);
|
||||
}
|
||||
if (type in result) {
|
||||
result[type]?.push(node);
|
||||
} else {
|
||||
result[type] = [node];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const anyFunctionSchema = z.function(z.tuple([]).rest(z.any()), z.any());
|
||||
|
||||
export const toolMetadataSchema = z.object({
|
||||
description: z.string(),
|
||||
name: z.string(),
|
||||
parameters: z.record(z.any()),
|
||||
});
|
||||
|
||||
export const baseToolSchema = z.object({
|
||||
call: anyFunctionSchema.optional(),
|
||||
metadata: toolMetadataSchema,
|
||||
});
|
||||
|
||||
export const baseToolWithCallSchema = baseToolSchema.extend({
|
||||
call: z.function(),
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Settings } from "@llamaindex/core/global";
|
||||
import { TextNode } from "@llamaindex/core/schema";
|
||||
import { env } from "process";
|
||||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
describe("chunkSizeCheck", () => {
|
||||
afterEach(() => {
|
||||
Settings.chunkSize = undefined;
|
||||
env.ENABLE_CHUNK_SIZE_CHECK = undefined;
|
||||
});
|
||||
|
||||
test("should warn when content is larger than chunk size", () => {
|
||||
env.ENABLE_CHUNK_SIZE_CHECK = "true";
|
||||
|
||||
let message = "";
|
||||
const consoleMock = vi
|
||||
.spyOn(console, "warn")
|
||||
.mockImplementation((msg) => (message += msg + "\n"));
|
||||
|
||||
Settings.chunkSize = 0;
|
||||
const node = new TextNode();
|
||||
expect(message).toEqual("");
|
||||
node.setContent("a".repeat(1024));
|
||||
expect(message).toContain("is larger than chunk size");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@llamaindex/core-tests",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"vitest": "^1.6.0"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Document, TextNode } from "llamaindex/Node";
|
||||
import { Document, TextNode } from "@llamaindex/core/schema";
|
||||
import { beforeEach, describe, expect, test } from "vitest";
|
||||
|
||||
describe("Document", () => {
|
||||
@@ -50,7 +50,6 @@ describe("TextNode", () => {
|
||||
`
|
||||
{
|
||||
"embedding": undefined,
|
||||
"endCharIdx": undefined,
|
||||
"excludedEmbedMetadataKeys": [],
|
||||
"excludedLlmMetadataKeys": [],
|
||||
"hash": "Z6SWgFPlalaeblMGQGw0KS3qKgmZdEWXKfzEp/K+QN0=",
|
||||
@@ -62,7 +61,6 @@ describe("TextNode", () => {
|
||||
"metadataSeparator": "
|
||||
",
|
||||
"relationships": {},
|
||||
"startCharIdx": undefined,
|
||||
"text": "Hello World",
|
||||
"textTemplate": "",
|
||||
"type": "TEXT",
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./lib",
|
||||
"module": "node16",
|
||||
"moduleResolution": "node16",
|
||||
"target": "ESNext"
|
||||
},
|
||||
"include": ["./**/*.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "../../env/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist/type",
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo",
|
||||
"emitDeclarationOnly": true,
|
||||
"moduleResolution": "Bundler",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Vendored
+12
@@ -1,5 +1,17 @@
|
||||
# @llamaindex/env
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f326ab8: chore: bump version
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 41fe871: Add support for azure dynamic session tool
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Vendored
-10
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "@llamaindex/env",
|
||||
"version": "0.1.6",
|
||||
"exports": {
|
||||
".": "./src/index.edge-light.ts"
|
||||
},
|
||||
"publish": {
|
||||
"include": ["LICENSE", "README.md", "src/**/*", "jsr.json"]
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/env",
|
||||
"description": "environment wrapper, supports all JS environment including node, deno, bun, edge runtime, and cloudflare worker",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.8",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
Vendored
+2
-1
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
import { createWriteStream } from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
export { fs };
|
||||
export { createWriteStream, fs };
|
||||
|
||||
Vendored
+6
-1
@@ -15,12 +15,14 @@ import { ok } from "node:assert";
|
||||
import { createHash, randomUUID } from "node:crypto";
|
||||
import { EOL } from "node:os";
|
||||
import path from "node:path";
|
||||
import { Readable } from "node:stream";
|
||||
import {
|
||||
ReadableStream,
|
||||
TransformStream,
|
||||
WritableStream,
|
||||
} from "node:stream/web";
|
||||
import { fs } from "./fs/node.js";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { createWriteStream, fs } from "./fs/node.js";
|
||||
import type { SHA256 } from "./polyfill.js";
|
||||
|
||||
export function createSHA256(): SHA256 {
|
||||
@@ -38,11 +40,14 @@ export function createSHA256(): SHA256 {
|
||||
export { Tokenizers, tokenizers, type Tokenizer } from "./tokenizers/node.js";
|
||||
export { AsyncLocalStorage, CustomEvent, getEnv, setEnvs } from "./utils.js";
|
||||
export {
|
||||
createWriteStream,
|
||||
EOL,
|
||||
fileURLToPath,
|
||||
fs,
|
||||
ok,
|
||||
path,
|
||||
randomUUID,
|
||||
Readable,
|
||||
ReadableStream,
|
||||
TransformStream,
|
||||
WritableStream,
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# @llamaindex/experimental
|
||||
|
||||
## 0.0.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "@llamaindex/experimental",
|
||||
"version": "0.0.5",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./type": "./src/type.ts"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/experimental",
|
||||
"description": "Experimental package for LlamaIndexTS",
|
||||
"version": "0.0.38",
|
||||
"version": "0.0.47",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,5 +1,72 @@
|
||||
# llamaindex
|
||||
|
||||
## 0.4.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f326ab8: chore: bump version
|
||||
- Updated dependencies [f326ab8]
|
||||
- @llamaindex/cloud@0.1.2
|
||||
- @llamaindex/core@0.0.3
|
||||
- @llamaindex/env@0.1.8
|
||||
|
||||
## 0.4.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8bf5b4a: fix: llama parse input spreadsheet
|
||||
|
||||
## 0.4.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7dce3d2: fix: disable External Filters for Gemini
|
||||
|
||||
## 0.4.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3a96a48: fix: anthroipic image input
|
||||
|
||||
## 0.4.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 83ebdfb: fix: next.js build error
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 41fe871: Add support for azure dynamic session tool
|
||||
- 321c39d: fix: generate api as class
|
||||
- f7f1af0: fix: throw error when no pipeline found
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [f10b41d]
|
||||
- Updated dependencies [321c39d]
|
||||
- @llamaindex/env@0.1.7
|
||||
- @llamaindex/core@0.0.2
|
||||
- @llamaindex/cloud@0.1.1
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1feb23b: feat: Gemini tool calling for agent support
|
||||
- 08c55ec: Add metadata to PDFs and use Uint8Array for readers content
|
||||
|
||||
## 0.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 6c3e5d0: fix: switch to correct reference for a static function
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 42eb73a: Fix IngestionPipeline not working without vectorStores
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# @llamaindex/cloudflare-worker-agent-test
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloudflare-worker-agent-test",
|
||||
"version": "0.0.22",
|
||||
"version": "0.0.31",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# @llamaindex/next-agent-test
|
||||
|
||||
## 0.1.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.1.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.1.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.1.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.1.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.1.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-agent-test",
|
||||
"version": "0.1.22",
|
||||
"version": "0.1.31",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use server";
|
||||
import { createStreamableUI } from "ai/rsc";
|
||||
import type { ChatMessage } from "llamaindex";
|
||||
import { OpenAIAgent } from "llamaindex";
|
||||
import type { ChatMessage } from "llamaindex/llm/types";
|
||||
|
||||
export async function chatWithAgent(
|
||||
question: string,
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# test-edge-runtime
|
||||
|
||||
## 0.1.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.1.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.1.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.1.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.1.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.1.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/nextjs-edge-runtime-test",
|
||||
"version": "0.1.21",
|
||||
"version": "0.1.30",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,72 @@
|
||||
# @llamaindex/next-node-runtime
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 83ebdfb: fix: next.js build error
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-node-runtime-test",
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.12",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
"use server";
|
||||
import {
|
||||
OpenAI,
|
||||
OpenAIAgent,
|
||||
QueryEngineTool,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import { HuggingFaceEmbedding } from "llamaindex/embeddings/HuggingFaceEmbedding";
|
||||
import { SimpleDirectoryReader } from "llamaindex/readers/SimpleDirectoryReader";
|
||||
|
||||
Settings.llm = new OpenAI({
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
apiKey: process.env.NEXT_PUBLIC_OPENAI_KEY ?? "FAKE_KEY_TO_PASS_TESTS",
|
||||
model: "gpt-4o",
|
||||
});
|
||||
Settings.embedModel = new HuggingFaceEmbedding({
|
||||
modelType: "BAAI/bge-small-en-v1.5",
|
||||
quantized: false,
|
||||
});
|
||||
Settings.callbackManager.on("llm-tool-call", (event) => {
|
||||
console.log(event.detail.payload);
|
||||
});
|
||||
Settings.callbackManager.on("llm-tool-result", (event) => {
|
||||
console.log(event.detail.payload);
|
||||
});
|
||||
|
||||
export async function getOpenAIModelRequest(query: string) {
|
||||
try {
|
||||
const currentDir = __dirname;
|
||||
|
||||
// load our data and create a query engine
|
||||
const reader = new SimpleDirectoryReader();
|
||||
const documents = await reader.loadData(currentDir);
|
||||
const index = await VectorStoreIndex.fromDocuments(documents);
|
||||
const retriever = index.asRetriever({
|
||||
similarityTopK: 10,
|
||||
});
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
});
|
||||
|
||||
// define the query engine as a tool
|
||||
const tools = [
|
||||
new QueryEngineTool({
|
||||
queryEngine: queryEngine,
|
||||
metadata: {
|
||||
name: "deployment_details_per_env",
|
||||
description: `This tool can answer detailed questions about deployments happened in various environments.`,
|
||||
},
|
||||
}),
|
||||
];
|
||||
// create the agent
|
||||
const agent = new OpenAIAgent({ tools });
|
||||
|
||||
const { response } = await agent.chat({
|
||||
message: query,
|
||||
});
|
||||
return {
|
||||
message: response,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
errors: "Error Calling OpenAI Model",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { getOpenAIModelRequest } from "@/actions/openai";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
// POST /api/openai
|
||||
export async function POST(request: NextRequest) {
|
||||
const body = await request.json();
|
||||
const content = await getOpenAIModelRequest(body.query);
|
||||
|
||||
return NextResponse.json(content, { status: 200 });
|
||||
}
|
||||
@@ -1,5 +1,71 @@
|
||||
# @llamaindex/waku-query-engine-test
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f326ab8]
|
||||
- llamaindex@0.4.12
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8bf5b4a]
|
||||
- llamaindex@0.4.11
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7dce3d2]
|
||||
- llamaindex@0.4.10
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3a96a48]
|
||||
- llamaindex@0.4.9
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [83ebdfb]
|
||||
- llamaindex@0.4.8
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [41fe871]
|
||||
- Updated dependencies [321c39d]
|
||||
- Updated dependencies [f7f1af0]
|
||||
- llamaindex@0.4.7
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1feb23b]
|
||||
- Updated dependencies [08c55ec]
|
||||
- llamaindex@0.4.6
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6c3e5d0]
|
||||
- llamaindex@0.4.5
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [42eb73a]
|
||||
- llamaindex@0.4.4
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/waku-query-engine-test",
|
||||
"version": "0.0.22",
|
||||
"version": "0.0.31",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
LLMChatParamsStreaming,
|
||||
LLMCompletionParamsNonStreaming,
|
||||
LLMCompletionParamsStreaming,
|
||||
} from "llamaindex/llm/types";
|
||||
} from "llamaindex";
|
||||
import { extractText } from "llamaindex/llm/utils";
|
||||
import { deepStrictEqual, strictEqual } from "node:assert";
|
||||
import { llmCompleteMockStorage } from "../../node/utils.js";
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@llamaindex/llamaindex",
|
||||
"version": "0.4.3",
|
||||
"exports": "./src/index.ts",
|
||||
"imports": {
|
||||
"@llamaindex/env": "jsr:@llamaindex/env@0.1.6"
|
||||
},
|
||||
"publish": {
|
||||
"include": ["LICENSE", "README.md", "src/**/*", "jsr.json"]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "llamaindex",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.12",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
@@ -22,17 +22,20 @@
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.21.1",
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"@azure/identity": "^4.2.1",
|
||||
"@datastax/astra-db-ts": "^1.2.1",
|
||||
"@google-cloud/vertexai": "^1.2.0",
|
||||
"@google/generative-ai": "^0.12.0",
|
||||
"@grpc/grpc-js": "^1.10.8",
|
||||
"@huggingface/inference": "^2.7.0",
|
||||
"@llamaindex/cloud": "0.0.7",
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"@mistralai/mistralai": "^0.4.0",
|
||||
"@pinecone-database/pinecone": "^2.2.2",
|
||||
"@qdrant/js-client-rest": "^1.9.0",
|
||||
"@types/lodash": "^4.17.5",
|
||||
"@types/lodash": "^4.17.4",
|
||||
"@types/node": "^20.14.5",
|
||||
"@types/papaparse": "^5.3.14",
|
||||
"@types/pg": "^8.11.6",
|
||||
"@xenova/transformers": "^2.17.2",
|
||||
@@ -60,7 +63,8 @@
|
||||
"tiktoken": "^1.0.15",
|
||||
"unpdf": "^0.10.1",
|
||||
"wikipedia": "^2.1.2",
|
||||
"wink-nlp": "^2.3.0"
|
||||
"wink-nlp": "^2.3.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@notionhq/client": "^2.2.15"
|
||||
@@ -148,7 +152,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/core"
|
||||
"directory": "packages/llamaindex"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ChatMessage, LLM, MessageType } from "@llamaindex/core/llms";
|
||||
import { tokenizers, type Tokenizer } from "@llamaindex/env";
|
||||
import type { SummaryPrompt } from "./Prompt.js";
|
||||
import { defaultSummaryPrompt, messagesToHistoryStr } from "./Prompt.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import type { ChatMessage, LLM, MessageType } from "./llm/types.js";
|
||||
import { extractText } from "./llm/utils.js";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { NodeWithScore } from "./Node.js";
|
||||
import type {
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
ChatResponseChunk,
|
||||
} from "./llm/types.js";
|
||||
} from "@llamaindex/core/llms";
|
||||
import type { NodeWithScore } from "@llamaindex/core/schema";
|
||||
import { extractText } from "./llm/utils.js";
|
||||
|
||||
export class EngineResponse implements ChatResponse, ChatResponseChunk {
|
||||
@@ -64,7 +64,7 @@ export class EngineResponse implements ChatResponse, ChatResponseChunk {
|
||||
sourceNodes?: NodeWithScore[],
|
||||
): EngineResponse {
|
||||
return new EngineResponse(
|
||||
this.toChatResponse(chunk.delta, chunk.raw),
|
||||
EngineResponse.toChatResponse(chunk.delta, chunk.raw),
|
||||
true,
|
||||
sourceNodes,
|
||||
);
|
||||
|
||||
@@ -1,448 +1,6 @@
|
||||
import { createSHA256, path, randomUUID } from "@llamaindex/env";
|
||||
import { chunkSizeCheck, lazyInitHash } from "./internal/decorator/node.js";
|
||||
console.warn(
|
||||
'Package "llamaindex/Node" is deprecated, and will be removed in the next major release.',
|
||||
);
|
||||
console.warn("Please import from the @llamaindex/core/schema package instead.");
|
||||
|
||||
export enum NodeRelationship {
|
||||
SOURCE = "SOURCE",
|
||||
PREVIOUS = "PREVIOUS",
|
||||
NEXT = "NEXT",
|
||||
PARENT = "PARENT",
|
||||
CHILD = "CHILD",
|
||||
}
|
||||
|
||||
export enum ObjectType {
|
||||
TEXT = "TEXT",
|
||||
IMAGE = "IMAGE",
|
||||
INDEX = "INDEX",
|
||||
DOCUMENT = "DOCUMENT",
|
||||
IMAGE_DOCUMENT = "IMAGE_DOCUMENT",
|
||||
}
|
||||
|
||||
export enum MetadataMode {
|
||||
ALL = "ALL",
|
||||
EMBED = "EMBED",
|
||||
LLM = "LLM",
|
||||
NONE = "NONE",
|
||||
}
|
||||
|
||||
export type Metadata = Record<string, any>;
|
||||
|
||||
export interface RelatedNodeInfo<T extends Metadata = Metadata> {
|
||||
nodeId: string;
|
||||
nodeType?: ObjectType;
|
||||
metadata: T;
|
||||
hash?: string;
|
||||
}
|
||||
|
||||
export type RelatedNodeType<T extends Metadata = Metadata> =
|
||||
| RelatedNodeInfo<T>
|
||||
| RelatedNodeInfo<T>[];
|
||||
|
||||
export type BaseNodeParams<T extends Metadata = Metadata> = {
|
||||
id_?: string;
|
||||
metadata?: T;
|
||||
excludedEmbedMetadataKeys?: string[];
|
||||
excludedLlmMetadataKeys?: string[];
|
||||
relationships?: Partial<Record<NodeRelationship, RelatedNodeType<T>>>;
|
||||
hash?: string;
|
||||
embedding?: number[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic abstract class for retrievable nodes
|
||||
*/
|
||||
export abstract class BaseNode<T extends Metadata = Metadata> {
|
||||
/**
|
||||
* The unique ID of the Node/Document. The trailing underscore is here
|
||||
* to avoid collisions with the id keyword in Python.
|
||||
*
|
||||
* Set to a UUID by default.
|
||||
*/
|
||||
id_: string;
|
||||
embedding?: number[];
|
||||
|
||||
// Metadata fields
|
||||
metadata: T;
|
||||
excludedEmbedMetadataKeys: string[];
|
||||
excludedLlmMetadataKeys: string[];
|
||||
relationships: Partial<Record<NodeRelationship, RelatedNodeType<T>>>;
|
||||
|
||||
@lazyInitHash
|
||||
accessor hash: string = "";
|
||||
|
||||
protected constructor(init?: BaseNodeParams<T>) {
|
||||
const {
|
||||
id_,
|
||||
metadata,
|
||||
excludedEmbedMetadataKeys,
|
||||
excludedLlmMetadataKeys,
|
||||
relationships,
|
||||
hash,
|
||||
embedding,
|
||||
} = init || {};
|
||||
this.id_ = id_ ?? randomUUID();
|
||||
this.metadata = metadata ?? ({} as T);
|
||||
this.excludedEmbedMetadataKeys = excludedEmbedMetadataKeys ?? [];
|
||||
this.excludedLlmMetadataKeys = excludedLlmMetadataKeys ?? [];
|
||||
this.relationships = relationships ?? {};
|
||||
this.embedding = embedding;
|
||||
}
|
||||
|
||||
abstract get type(): ObjectType;
|
||||
|
||||
abstract getContent(metadataMode: MetadataMode): string;
|
||||
abstract getMetadataStr(metadataMode: MetadataMode): string;
|
||||
// todo: set value as a generic type
|
||||
abstract setContent(value: unknown): void;
|
||||
|
||||
get sourceNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.SOURCE];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Source object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get prevNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.PREVIOUS];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error(
|
||||
"Previous object must be a single RelatedNodeInfo object",
|
||||
);
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get nextNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.NEXT];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Next object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get parentNode(): RelatedNodeInfo<T> | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.PARENT];
|
||||
|
||||
if (Array.isArray(relationship)) {
|
||||
throw new Error("Parent object must be a single RelatedNodeInfo object");
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
get childNodes(): RelatedNodeInfo<T>[] | undefined {
|
||||
const relationship = this.relationships[NodeRelationship.CHILD];
|
||||
|
||||
if (!Array.isArray(relationship)) {
|
||||
throw new Error(
|
||||
"Child object must be a an array of RelatedNodeInfo objects",
|
||||
);
|
||||
}
|
||||
|
||||
return relationship;
|
||||
}
|
||||
|
||||
abstract generateHash(): string;
|
||||
|
||||
getEmbedding(): number[] {
|
||||
if (this.embedding === undefined) {
|
||||
throw new Error("Embedding not set");
|
||||
}
|
||||
|
||||
return this.embedding;
|
||||
}
|
||||
|
||||
asRelatedNodeInfo(): RelatedNodeInfo<T> {
|
||||
return {
|
||||
nodeId: this.id_,
|
||||
metadata: this.metadata,
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by built in JSON.stringify (see https://javascript.info/json)
|
||||
* Properties are read-only as they are not deep-cloned (not necessary for stringification).
|
||||
* @see toMutableJSON - use to return a mutable JSON instead
|
||||
*/
|
||||
toJSON(): Record<string, any> {
|
||||
return {
|
||||
...this,
|
||||
type: this.type,
|
||||
// hash is an accessor property, so it's not included in the rest operator
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
|
||||
clone(): BaseNode {
|
||||
return jsonToNode(this.toMutableJSON()) as BaseNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the object to a JSON representation.
|
||||
* Properties can be safely modified as a deep clone of the properties are created.
|
||||
* @return {Record<string, any>} - The JSON representation of the object.
|
||||
*/
|
||||
toMutableJSON(): Record<string, any> {
|
||||
return structuredClone(this.toJSON());
|
||||
}
|
||||
}
|
||||
|
||||
export type TextNodeParams<T extends Metadata = Metadata> =
|
||||
BaseNodeParams<T> & {
|
||||
text?: string;
|
||||
textTemplate?: string;
|
||||
startCharIdx?: number;
|
||||
endCharIdx?: number;
|
||||
metadataSeparator?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextNode is the default node type for text. Most common node type in LlamaIndex.TS
|
||||
*/
|
||||
export class TextNode<T extends Metadata = Metadata> extends BaseNode<T> {
|
||||
text: string;
|
||||
textTemplate: string;
|
||||
|
||||
startCharIdx?: number;
|
||||
endCharIdx?: number;
|
||||
// textTemplate: NOTE write your own formatter if needed
|
||||
// metadataTemplate: NOTE write your own formatter if needed
|
||||
metadataSeparator: string;
|
||||
|
||||
constructor(init: TextNodeParams<T> = {}) {
|
||||
super(init);
|
||||
const { text, textTemplate, startCharIdx, endCharIdx, metadataSeparator } =
|
||||
init;
|
||||
this.text = text ?? "";
|
||||
this.textTemplate = textTemplate ?? "";
|
||||
if (startCharIdx) {
|
||||
this.startCharIdx = startCharIdx;
|
||||
}
|
||||
this.endCharIdx = endCharIdx;
|
||||
this.metadataSeparator = metadataSeparator ?? "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash of the text node.
|
||||
* The ID is not part of the hash as it can change independent of content.
|
||||
* @returns
|
||||
*/
|
||||
generateHash() {
|
||||
const hashFunction = createSHA256();
|
||||
hashFunction.update(`type=${this.type}`);
|
||||
hashFunction.update(
|
||||
`startCharIdx=${this.startCharIdx} endCharIdx=${this.endCharIdx}`,
|
||||
);
|
||||
hashFunction.update(this.getContent(MetadataMode.ALL));
|
||||
return hashFunction.digest();
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.TEXT;
|
||||
}
|
||||
|
||||
@chunkSizeCheck
|
||||
getContent(metadataMode: MetadataMode = MetadataMode.NONE): string {
|
||||
const metadataStr = this.getMetadataStr(metadataMode).trim();
|
||||
return `${metadataStr}\n\n${this.text}`.trim();
|
||||
}
|
||||
|
||||
getMetadataStr(metadataMode: MetadataMode): string {
|
||||
if (metadataMode === MetadataMode.NONE) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const usableMetadataKeys = new Set(Object.keys(this.metadata).sort());
|
||||
if (metadataMode === MetadataMode.LLM) {
|
||||
for (const key of this.excludedLlmMetadataKeys) {
|
||||
usableMetadataKeys.delete(key);
|
||||
}
|
||||
} else if (metadataMode === MetadataMode.EMBED) {
|
||||
for (const key of this.excludedEmbedMetadataKeys) {
|
||||
usableMetadataKeys.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
return [...usableMetadataKeys]
|
||||
.map((key) => `${key}: ${this.metadata[key]}`)
|
||||
.join(this.metadataSeparator);
|
||||
}
|
||||
|
||||
setContent(value: string) {
|
||||
this.text = value;
|
||||
this.hash = this.generateHash();
|
||||
}
|
||||
|
||||
getNodeInfo() {
|
||||
return { start: this.startCharIdx, end: this.endCharIdx };
|
||||
}
|
||||
|
||||
getText() {
|
||||
return this.getContent(MetadataMode.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
export type IndexNodeParams<T extends Metadata = Metadata> =
|
||||
TextNodeParams<T> & {
|
||||
indexId: string;
|
||||
};
|
||||
|
||||
export class IndexNode<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
indexId: string;
|
||||
|
||||
constructor(init?: IndexNodeParams<T>) {
|
||||
super(init);
|
||||
const { indexId } = init || {};
|
||||
this.indexId = indexId ?? "";
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A document is just a special text node with a docId.
|
||||
*/
|
||||
export class Document<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
constructor(init?: TextNodeParams<T>) {
|
||||
super(init);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.DOCUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
export function jsonToNode(json: any, type?: ObjectType) {
|
||||
if (!json.type && !type) {
|
||||
throw new Error("Node type not found");
|
||||
}
|
||||
const nodeType = type || json.type;
|
||||
|
||||
switch (nodeType) {
|
||||
case ObjectType.TEXT:
|
||||
return new TextNode(json);
|
||||
case ObjectType.INDEX:
|
||||
return new IndexNode(json);
|
||||
case ObjectType.DOCUMENT:
|
||||
return new Document(json);
|
||||
case ObjectType.IMAGE_DOCUMENT:
|
||||
return new ImageDocument(json);
|
||||
default:
|
||||
throw new Error(`Invalid node type: ${nodeType}`);
|
||||
}
|
||||
}
|
||||
|
||||
export type ImageType = string | Blob | URL;
|
||||
|
||||
export type ImageNodeParams<T extends Metadata = Metadata> =
|
||||
TextNodeParams<T> & {
|
||||
image: ImageType;
|
||||
};
|
||||
|
||||
export class ImageNode<T extends Metadata = Metadata> extends TextNode<T> {
|
||||
image: ImageType; // image as blob
|
||||
|
||||
constructor(init: ImageNodeParams<T>) {
|
||||
super(init);
|
||||
const { image } = init;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.IMAGE;
|
||||
}
|
||||
|
||||
getUrl(): URL {
|
||||
// id_ stores the relative path, convert it to the URL of the file
|
||||
const absPath = path.resolve(this.id_);
|
||||
return new URL(`file://${absPath}`);
|
||||
}
|
||||
|
||||
// Calculates the image part of the hash
|
||||
private generateImageHash() {
|
||||
const hashFunction = createSHA256();
|
||||
|
||||
if (this.image instanceof Blob) {
|
||||
// TODO: ideally we should use the blob's content to calculate the hash:
|
||||
// hashFunction.update(new Uint8Array(await this.image.arrayBuffer()));
|
||||
// as this is async, we're using the node's ID for the time being
|
||||
hashFunction.update(this.id_);
|
||||
} else if (this.image instanceof URL) {
|
||||
hashFunction.update(this.image.toString());
|
||||
} else if (typeof this.image === "string") {
|
||||
hashFunction.update(this.image);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unknown image type: ${typeof this.image}. Can't calculate hash`,
|
||||
);
|
||||
}
|
||||
|
||||
return hashFunction.digest();
|
||||
}
|
||||
|
||||
generateHash() {
|
||||
const hashFunction = createSHA256();
|
||||
// calculates hash based on hash of both components (image and text)
|
||||
hashFunction.update(super.generateHash());
|
||||
hashFunction.update(this.generateImageHash());
|
||||
|
||||
return hashFunction.digest();
|
||||
}
|
||||
}
|
||||
|
||||
export class ImageDocument<T extends Metadata = Metadata> extends ImageNode<T> {
|
||||
constructor(init: ImageNodeParams<T>) {
|
||||
super(init);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return ObjectType.IMAGE_DOCUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node with a similarity score
|
||||
*/
|
||||
export interface NodeWithScore<T extends Metadata = Metadata> {
|
||||
node: BaseNode<T>;
|
||||
score?: number;
|
||||
}
|
||||
|
||||
export enum ModalityType {
|
||||
TEXT = "TEXT",
|
||||
IMAGE = "IMAGE",
|
||||
}
|
||||
|
||||
type NodesByType = {
|
||||
[P in ModalityType]?: BaseNode[];
|
||||
};
|
||||
|
||||
export function splitNodesByType(nodes: BaseNode[]): NodesByType {
|
||||
const result: NodesByType = {};
|
||||
|
||||
for (const node of nodes) {
|
||||
let type: ModalityType;
|
||||
if (node instanceof ImageNode) {
|
||||
type = ModalityType.IMAGE;
|
||||
} else if (node instanceof TextNode) {
|
||||
type = ModalityType.TEXT;
|
||||
} else {
|
||||
throw new Error(`Unknown node type: ${node.type}`);
|
||||
}
|
||||
if (type in result) {
|
||||
result[type]?.push(node);
|
||||
} else {
|
||||
result[type] = [node];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export * from "@llamaindex/core/schema";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { ChatMessage, ToolMetadata } from "@llamaindex/core/llms";
|
||||
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.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { LLM, ToolMetadata } from "@llamaindex/core/llms";
|
||||
import { SubQuestionOutputParser } from "./OutputParser.js";
|
||||
import type { SubQuestionPrompt } from "./Prompt.js";
|
||||
import { buildToolsText, defaultSubQuestionPrompt } from "./Prompt.js";
|
||||
@@ -6,13 +7,8 @@ import type {
|
||||
SubQuestion,
|
||||
} from "./engines/query/types.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import type { LLM } from "./llm/types.js";
|
||||
import { PromptMixin } from "./prompts/index.js";
|
||||
import type {
|
||||
BaseOutputParser,
|
||||
StructuredOutput,
|
||||
ToolMetadata,
|
||||
} from "./types.js";
|
||||
import type { BaseOutputParser, StructuredOutput } from "./types.js";
|
||||
|
||||
/**
|
||||
* LLMQuestionGenerator uses the LLM to generate new questions for the LLM using tools and a user query.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { NodeWithScore } from "./Node.js";
|
||||
import type { NodeWithScore } from "@llamaindex/core/schema";
|
||||
import type { ServiceContext } from "./ServiceContext.js";
|
||||
import type { MessageContent } from "./index.edge.js";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { LLM } from "@llamaindex/core/llms";
|
||||
import { PromptHelper } from "./PromptHelper.js";
|
||||
import { OpenAIEmbedding } from "./embeddings/OpenAIEmbedding.js";
|
||||
import type { BaseEmbedding } from "./embeddings/types.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import type { LLM } from "./llm/types.js";
|
||||
import { SimpleNodeParser } from "./nodeParsers/SimpleNodeParser.js";
|
||||
import type { NodeParser } from "./nodeParsers/types.js";
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Settings as CoreSettings } from "@llamaindex/core/global";
|
||||
import { CallbackManager } from "./callbacks/CallbackManager.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
|
||||
import { PromptHelper } from "./PromptHelper.js";
|
||||
import { SimpleNodeParser } from "./nodeParsers/SimpleNodeParser.js";
|
||||
|
||||
import type { LLM } from "@llamaindex/core/llms";
|
||||
import { AsyncLocalStorage, getEnv } from "@llamaindex/env";
|
||||
import type { ServiceContext } from "./ServiceContext.js";
|
||||
import type { BaseEmbedding } from "./embeddings/types.js";
|
||||
@@ -17,12 +19,6 @@ import {
|
||||
setEmbeddedModel,
|
||||
withEmbeddedModel,
|
||||
} from "./internal/settings/EmbedModel.js";
|
||||
import {
|
||||
getChunkSize,
|
||||
setChunkSize,
|
||||
withChunkSize,
|
||||
} from "./internal/settings/chunk-size.js";
|
||||
import type { LLM } from "./llm/types.js";
|
||||
import type { NodeParser } from "./nodeParsers/types.js";
|
||||
|
||||
export type PromptConfig = {
|
||||
@@ -148,15 +144,15 @@ class GlobalSettings implements Config {
|
||||
}
|
||||
|
||||
set chunkSize(chunkSize: number | undefined) {
|
||||
setChunkSize(chunkSize);
|
||||
CoreSettings.chunkSize = chunkSize;
|
||||
}
|
||||
|
||||
get chunkSize(): number | undefined {
|
||||
return getChunkSize();
|
||||
return CoreSettings.chunkSize;
|
||||
}
|
||||
|
||||
withChunkSize<Result>(chunkSize: number, fn: () => Result): Result {
|
||||
return withChunkSize(chunkSize, fn);
|
||||
return CoreSettings.withChunkSize(chunkSize, fn);
|
||||
}
|
||||
|
||||
get chunkOverlap(): number | undefined {
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import type {
|
||||
BaseToolWithCall,
|
||||
ChatMessage,
|
||||
LLM,
|
||||
MessageContent,
|
||||
ToolOutput,
|
||||
} from "@llamaindex/core/llms";
|
||||
import { ReadableStream, TransformStream, randomUUID } from "@llamaindex/env";
|
||||
import { ChatHistory } from "../ChatHistory.js";
|
||||
import { EngineResponse } from "../EngineResponse.js";
|
||||
@@ -11,8 +18,7 @@ import { wrapEventCaller } from "../internal/context/EventCaller.js";
|
||||
import { consoleLogger, emptyLogger } from "../internal/logger.js";
|
||||
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
|
||||
import { isAsyncIterable } from "../internal/utils.js";
|
||||
import type { ChatMessage, LLM, MessageContent } from "../llm/index.js";
|
||||
import type { BaseToolWithCall, ToolOutput } from "../types.js";
|
||||
import { ObjectRetriever } from "../objects/index.js";
|
||||
import type {
|
||||
AgentTaskContext,
|
||||
TaskHandler,
|
||||
@@ -126,12 +132,21 @@ export type AgentParamsBase<
|
||||
>
|
||||
? AdditionalMessageOptions
|
||||
: never,
|
||||
> = {
|
||||
llm?: AI;
|
||||
chatHistory?: ChatMessage<AdditionalMessageOptions>[];
|
||||
systemPrompt?: MessageContent;
|
||||
verbose?: boolean;
|
||||
};
|
||||
> =
|
||||
| {
|
||||
llm?: AI;
|
||||
chatHistory?: ChatMessage<AdditionalMessageOptions>[];
|
||||
systemPrompt?: MessageContent;
|
||||
verbose?: boolean;
|
||||
tools: BaseToolWithCall[];
|
||||
}
|
||||
| {
|
||||
llm?: AI;
|
||||
chatHistory?: ChatMessage<AdditionalMessageOptions>[];
|
||||
systemPrompt?: MessageContent;
|
||||
verbose?: boolean;
|
||||
toolRetriever: ObjectRetriever<BaseToolWithCall>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Worker will schedule tasks and handle the task execution
|
||||
@@ -219,13 +234,12 @@ export abstract class AgentRunner<
|
||||
const { llm, getTools, stream } = step.context;
|
||||
const lastMessage = step.context.store.messages.at(-1)!.content;
|
||||
const tools = await getTools(lastMessage);
|
||||
const response = await llm.chat({
|
||||
// @ts-expect-error
|
||||
stream,
|
||||
tools,
|
||||
messages: [...step.context.store.messages],
|
||||
});
|
||||
if (!stream) {
|
||||
const response = await llm.chat({
|
||||
stream,
|
||||
tools,
|
||||
messages: [...step.context.store.messages],
|
||||
});
|
||||
await stepTools<LLM>({
|
||||
response,
|
||||
tools,
|
||||
@@ -233,6 +247,11 @@ export abstract class AgentRunner<
|
||||
enqueueOutput,
|
||||
});
|
||||
} else {
|
||||
const response = await llm.chat({
|
||||
stream,
|
||||
tools,
|
||||
messages: [...step.context.store.messages],
|
||||
});
|
||||
await stepToolsStreaming<LLM>({
|
||||
response,
|
||||
tools,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { LLM } from "../llm/index.js";
|
||||
import type { BaseToolWithCall, LLM } from "@llamaindex/core/llms";
|
||||
import { ObjectRetriever } from "../objects/index.js";
|
||||
import { Settings } from "../Settings.js";
|
||||
import type { BaseToolWithCall } from "../types.js";
|
||||
import { AgentRunner, AgentWorker, type AgentParamsBase } from "./base.js";
|
||||
import { validateAgentParams } from "./utils.js";
|
||||
|
||||
type LLMParamsBase = AgentParamsBase<LLM>;
|
||||
|
||||
@@ -22,6 +22,7 @@ export class LLMAgentWorker extends AgentWorker<LLM> {
|
||||
|
||||
export class LLMAgent extends AgentRunner<LLM> {
|
||||
constructor(params: LLMAgentParams) {
|
||||
validateAgentParams(params);
|
||||
const llm = params.llm ?? (Settings.llm ? (Settings.llm as LLM) : null);
|
||||
if (!llm)
|
||||
throw new Error(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user