mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-01 22:14:03 -04:00
Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e0a627c9a | |||
| 4ba2cfe7ab | |||
| c1578a19d9 | |||
| ae49ff4e15 | |||
| a75af835a5 | |||
| 7c7cd34908 | |||
| f651891196 | |||
| 04714c886f | |||
| cf28574f51 | |||
| 24d065f054 | |||
| b8719586e3 | |||
| 07a40aca49 | |||
| 33b562938d | |||
| 723b41c23c | |||
| 4c38c1be0b | |||
| 0dde0ca27f | |||
| f3e0d07f48 | |||
| 1364e8eeed | |||
| 96fc69cc61 | |||
| 3b7736f763 | |||
| a7a7afe66e | |||
| c646ee2eca | |||
| 5729bd92fd | |||
| e0e52cf879 | |||
| 6f75306c17 | |||
| 94cb4ad810 | |||
| 1ea4014746 | |||
| 6a9a7b1458 | |||
| 1c168cd531 | |||
| 62cba5236d | |||
| d265e96420 | |||
| d30bbf799f | |||
| 53fd00a7c3 | |||
| 83f2848d47 | |||
| 313071e9cd | |||
| 5f6782038a | |||
| fe08d0451b | |||
| 59c5e5c3d4 | |||
| ee697fb1b3 | |||
| cf3320a4ea | |||
| f2ed69f2f8 | |||
| 3489e7de84 | |||
| 468bda594e | |||
| 6f3a31caf6 | |||
| 63e9846e97 | |||
| b7382b0d24 | |||
| 2a8241328d | |||
| 0b20ff9f17 | |||
| 1fc26046e3 | |||
| b17d439d6d | |||
| 040160c360 | |||
| 981811efd1 | |||
| d563b45a27 | |||
| 2774e80234 | |||
| 449274ca5a | |||
| 78037a664c | |||
| 1d9e3b1000 | |||
| df83e32107 | |||
| f7b4e94231 | |||
| 4c07a2655d | |||
| 5c0c8b2ec4 | |||
| e5e18688a6 | |||
| b6fb10eba8 | |||
| df441e28f4 | |||
| a4e05ec7ab | |||
| 96f72ad86e | |||
| f3556c011c | |||
| ebc510582b | |||
| f3bfdc29e3 | |||
| 6cce3b12ea | |||
| 0273e9739a | |||
| 7c8b883448 | |||
| c2bb418542 | |||
| ed6acbead0 | |||
| 976cce40d7 | |||
| e4fd4158bb | |||
| 31d5dffcef | |||
| d12edee802 | |||
| ac41ed3aae | |||
| d8c1159032 | |||
| c856c5becb | |||
| 50e6b57be0 | |||
| 8b7fdba544 | |||
| 22ae8d0166 | |||
| 23bcc379a8 | |||
| bdc4bfe7b0 | |||
| 025ffe6b50 | |||
| a6595747fa | |||
| d902cc3e7e | |||
| 726eb41359 | |||
| e9714dbfcd | |||
| a3618e761e | |||
| 24eabe7f35 | |||
| ecfa939ea6 | |||
| b48bcc3add | |||
| fa01fa2051 | |||
| fb36eff5e1 | |||
| d24d3d1e8c | |||
| 5c4badbcca | |||
| 2cd1383dc8 | |||
| 72440c101f | |||
| 423d66b07a | |||
| b42adebd51 | |||
| 749b43a3b1 | |||
| 8daaef44ee | |||
| ac07e3cbe6 | |||
| 1a6137b323 | |||
| 85c2e198a4 | |||
| 01263c4cfd | |||
| fbd5e0174d | |||
| 70ccb4ae65 | |||
| 7eb331774d | |||
| 24a3f058a3 | |||
| 84c28f95f9 | |||
| 7af57982fe | |||
| 6b70c5408f | |||
| 74fc725f37 | |||
| a0a74aed60 | |||
| 11feef8c82 | |||
| 9c5ff164ac | |||
| 7edeb1c2d7 | |||
| 8b95abdc85 | |||
| ffe0cd1ef1 | |||
| 5d2111a19f | |||
| 68ac7fd57f | |||
| 7320d96a36 | |||
| ee17fb475b | |||
| 28b877e31f | |||
| 4389b80a52 | |||
| d3bc663951 | |||
| 4810364788 | |||
| 2dcad52dd9 | |||
| 0bf8d80b12 | |||
| e4bba02aec | |||
| 1caa0da657 | |||
| 711c814bb2 | |||
| 5b832eb927 | |||
| 49988431f6 | |||
| 72d65dd51a | |||
| 553bc55b19 | |||
| fc6f69833c | |||
| c7fd06841f | |||
| 4648da6849 | |||
| 0188cf3bb6 | |||
| e0b4f9c047 | |||
| 4895bba96e | |||
| 76d1df817b | |||
| 83d7f415e2 | |||
| ae1149ffaf | |||
| 0148354dbe | |||
| 11b3856334 | |||
| e8f229cd01 | |||
| 75b70e5824 | |||
| 1711f6d8fc | |||
| 20d16abdf4 | |||
| 2411c9fbd0 | |||
| be3e280f2a | |||
| 2afcbe6587 | |||
| 22ff486fbe | |||
| eed0b0415d | |||
| d9d6c56ed5 | |||
| f99a237093 | |||
| fcbf18344c | |||
| bf8cbeb6c5 | |||
| e27e7dd054 | |||
| 8b66cf4341 | |||
| 6f4549bdea | |||
| c654398f75 | |||
| 0664a99945 | |||
| 58abc5731b | |||
| 7498b1e0f1 | |||
| 07a275fea5 | |||
| 1b6263e08d | |||
| 089f1d49c0 | |||
| 01c184c608 |
@@ -25,4 +25,4 @@ jobs:
|
||||
run: pnpm run build
|
||||
|
||||
- name: Pre Release
|
||||
run: pnpx pkg-pr-new publish ./packages/*
|
||||
run: pnpx pkg-pr-new publish ./packages/* ./packages/providers/*
|
||||
|
||||
+46
-23
@@ -12,6 +12,12 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
TURBO_REMOTE_ONLY: true
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
strategy:
|
||||
@@ -22,9 +28,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: ankane/setup-postgres@v1
|
||||
with:
|
||||
database: llamaindex_node_test
|
||||
dev-files: true
|
||||
- run: |
|
||||
cd /tmp
|
||||
git clone --branch v0.7.0 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
sudo make install
|
||||
- uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -42,7 +56,6 @@ jobs:
|
||||
node-version: [18.x, 20.x, 22.x]
|
||||
name: Test on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
@@ -76,13 +89,7 @@ jobs:
|
||||
- name: Run Type Check
|
||||
run: pnpm run type-check
|
||||
- name: Run Circular Dependency Check
|
||||
run: pnpm dlx turbo run circular-check
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: typecheck-build-dist
|
||||
path: ./packages/llamaindex/dist
|
||||
if-no-files-found: error
|
||||
run: pnpm run circular-check
|
||||
e2e-llamaindex-examples:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -92,7 +99,8 @@ jobs:
|
||||
- nextjs-agent
|
||||
- nextjs-edge-runtime
|
||||
- nextjs-node-runtime
|
||||
# - waku-query-engine
|
||||
- waku-query-engine
|
||||
- llama-parse-browser
|
||||
runs-on: ubuntu-latest
|
||||
name: Build LlamaIndex Example (${{ matrix.packages }})
|
||||
steps:
|
||||
@@ -128,21 +136,36 @@ 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
|
||||
- name: Pack llamaindex
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/llamaindex
|
||||
- name: Pack packages
|
||||
run: |
|
||||
for dir in packages/*; do
|
||||
if [ -d "$dir" ] && [ -f "$dir/package.json" ] && [[ ! "$dir" =~ autotool ]]; then
|
||||
echo "Packing $dir"
|
||||
pnpm pack --pack-destination ${{ runner.temp }} -C $dir
|
||||
else
|
||||
echo "Skipping $dir, no package.json found"
|
||||
fi
|
||||
done
|
||||
- name: Pack provider packages
|
||||
run: |
|
||||
for dir in packages/providers/*; do
|
||||
if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
|
||||
echo "Packing $dir"
|
||||
pnpm pack --pack-destination ${{ runner.temp }} -C $dir
|
||||
else
|
||||
echo "Skipping $dir, no package.json found"
|
||||
fi
|
||||
done
|
||||
- name: Install
|
||||
run: npm add ${{ runner.temp }}/*.tgz
|
||||
working-directory: ${{ runner.temp }}/examples
|
||||
- name: Run Type Check
|
||||
run: npx tsc --project ./tsconfig.json
|
||||
working-directory: ${{ runner.temp }}/examples
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: build-dist
|
||||
path: |
|
||||
${{ runner.temp }}/*.tgz
|
||||
if-no-files-found: error
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
LlamaIndex is a data framework for your LLM application.
|
||||
|
||||
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in Typescript and Javascript.
|
||||
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in JS runtime environments with TypeScript support.
|
||||
|
||||
Documentation: https://ts.llamaindex.ai/
|
||||
|
||||
@@ -19,30 +19,84 @@ Try examples online:
|
||||
|
||||
LlamaIndex.TS aims to be a lightweight, easy to use set of libraries to help you integrate large language models into your applications with your own data.
|
||||
|
||||
## Multiple JS Environment Support
|
||||
## Compatibility
|
||||
|
||||
### Multiple JS Environment Support
|
||||
|
||||
LlamaIndex.TS supports multiple JS environments, including:
|
||||
|
||||
- Node.js (18, 20, 22) ✅
|
||||
- Deno ✅
|
||||
- Bun ✅
|
||||
- React Server Components (Next.js) ✅
|
||||
- Nitro ✅
|
||||
- Vercel Edge Runtime ✅ (with some limitations)
|
||||
- Cloudflare Workers ✅ (with some limitations)
|
||||
|
||||
For now, browser support is limited due to the lack of support for [AsyncLocalStorage-like APIs](https://github.com/tc39/proposal-async-context)
|
||||
|
||||
### Supported LLMs:
|
||||
|
||||
- OpenAI LLms
|
||||
- Anthropic LLms
|
||||
- Groq LLMs
|
||||
- Llama2, Llama3, Llama3.1 LLMs
|
||||
- MistralAI LLMs
|
||||
- Fireworks LLMs
|
||||
- DeepSeek LLMs
|
||||
- ReplicateAI LLMs
|
||||
- TogetherAI LLMs
|
||||
- HuggingFace LLms
|
||||
- DeepInfra LLMs
|
||||
- Gemini LLMs
|
||||
|
||||
## Getting started
|
||||
|
||||
```shell
|
||||
npm install llamaindex
|
||||
pnpm install llamaindex
|
||||
yarn add llamaindex
|
||||
jsr install @llamaindex/core
|
||||
```
|
||||
|
||||
### Setup TypeScript
|
||||
|
||||
```json5
|
||||
{
|
||||
compilerOptions: {
|
||||
// ⬇️ add this line to your tsconfig.json
|
||||
moduleResolution: "bundler", // or "node16"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Why?</summary>
|
||||
We are shipping both ESM and CJS module, and compatible with Vercel Edge, Cloudflare Workers, and other serverless platforms.
|
||||
|
||||
So we are using [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to support all environments.
|
||||
|
||||
This is a kind of modern way of shipping packages, but might cause TypeScript type check to fail because of legacy module resolution.
|
||||
|
||||
Imaging you put output file into `/dist/openai.js` but you are importing `llamaindex/openai` in your code, and set `package.json` like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
"./openai": "./dist/openai.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In old module resolution, TypeScript will not be able to find the module because it is not follow the file structure, even you run `node index.js` successfully. (on Node.js >=16)
|
||||
|
||||
See more about [moduleResolution](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution) or
|
||||
[TypeScript 5.0 blog](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#--moduleresolution-bundler7).
|
||||
|
||||
</details>
|
||||
|
||||
### Node.js
|
||||
|
||||
```ts
|
||||
import fs from "fs/promises";
|
||||
import fs from "node:fs/promises";
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
@@ -76,9 +130,9 @@ main();
|
||||
node --import tsx ./main.ts
|
||||
```
|
||||
|
||||
### React Server Component (Next.js, Waku, Redwood.JS...)
|
||||
### Next.js
|
||||
|
||||
First, you will need to add a llamaindex plugin to your Next.js project.
|
||||
You will need to add a llamaindex plugin to your Next.js project.
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
@@ -89,20 +143,18 @@ module.exports = withLlamaIndex({
|
||||
});
|
||||
```
|
||||
|
||||
You can combine `ai` with `llamaindex` in Next.js with RSC (React Server Components).
|
||||
### React Server Actions
|
||||
|
||||
You can combine `ai` with `llamaindex` in Next.js, Waku or Redwood.js with RSC (React Server Components).
|
||||
|
||||
```tsx
|
||||
// src/apps/page.tsx
|
||||
"use client";
|
||||
import { chatWithAgent } from "@/actions";
|
||||
import type { JSX } from "react";
|
||||
import { useFormState } from "react-dom";
|
||||
|
||||
// You can use the Edge runtime in Next.js by adding this line:
|
||||
// export const runtime = "edge";
|
||||
import { useActionState } from "react";
|
||||
|
||||
export default function Home() {
|
||||
const [ui, action] = useFormState<JSX.Element | null>(async () => {
|
||||
const [ui, action] = useActionState<JSX.Element | null>(async () => {
|
||||
return chatWithAgent("hello!", []);
|
||||
}, null);
|
||||
return (
|
||||
@@ -132,11 +184,13 @@ export async function chatWithAgent(
|
||||
// ... adding your tools here
|
||||
],
|
||||
});
|
||||
const responseStream = await agent.chat({
|
||||
stream: true,
|
||||
message: question,
|
||||
chatHistory: prevMessages,
|
||||
});
|
||||
const responseStream = await agent.chat(
|
||||
{
|
||||
message: question,
|
||||
chatHistory: prevMessages,
|
||||
},
|
||||
true,
|
||||
);
|
||||
const uiStream = createStreamableUI(<div>loading...</div>);
|
||||
responseStream
|
||||
.pipeTo(
|
||||
@@ -154,29 +208,66 @@ export async function chatWithAgent(
|
||||
}
|
||||
```
|
||||
|
||||
## Playground
|
||||
### Cloudflare Workers
|
||||
|
||||
Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
|
||||
> [!TIP]
|
||||
> Some modules are not supported in Cloudflare Workers which require Node.js APIs.
|
||||
|
||||
## Core concepts for getting started:
|
||||
```ts
|
||||
// add `OPENAI_API_KEY` to the `.dev.vars` file
|
||||
interface Env {
|
||||
OPENAI_API_KEY: string;
|
||||
}
|
||||
|
||||
- [Document](/packages/llamaindex/src/Node.ts): A document represents a text file, PDF file or other contiguous piece of data.
|
||||
export default {
|
||||
async fetch(
|
||||
request: Request,
|
||||
env: Env,
|
||||
ctx: ExecutionContext,
|
||||
): Promise<Response> {
|
||||
const { OpenAIAgent, OpenAI } = await import("@llamaindex/openai");
|
||||
const text = await request.text();
|
||||
const agent = new OpenAIAgent({
|
||||
llm: new OpenAI({
|
||||
apiKey: env.OPENAI_API_KEY,
|
||||
}),
|
||||
tools: [],
|
||||
});
|
||||
const responseStream = await agent.chat({
|
||||
stream: true,
|
||||
message: text,
|
||||
});
|
||||
const textEncoder = new TextEncoder();
|
||||
const response = responseStream.pipeThrough<Uint8Array>(
|
||||
new TransformStream({
|
||||
transform: (chunk, controller) => {
|
||||
controller.enqueue(textEncoder.encode(chunk.delta));
|
||||
},
|
||||
}),
|
||||
);
|
||||
return new Response(response);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- [Node](/packages/llamaindex/src/Node.ts): The basic data building block. Most commonly, these are parts of the document split into manageable pieces that are small enough to be fed into an embedding model and LLM.
|
||||
### Vite
|
||||
|
||||
- [Embedding](/packages/llamaindex/src/embeddings/OpenAIEmbedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that question. Because the default service context is OpenAI, the default embedding is `OpenAIEmbedding`. If using different models, say through Ollama, use this [Embedding](/packages/llamaindex/src/embeddings/OllamaEmbedding.ts) (see all [here](/packages/llamaindex/src/embeddings)).
|
||||
We have some wasm dependencies for better performance. You can use `vite-plugin-wasm` to load them.
|
||||
|
||||
- [Indices](/packages/llamaindex/src/indices/): Indices store the Nodes and the embeddings of those nodes. QueryEngines retrieve Nodes from these Indices using embedding similarity.
|
||||
```ts
|
||||
import wasm from "vite-plugin-wasm";
|
||||
|
||||
- [QueryEngine](/packages/llamaindex/src/engines/query/RetrieverQueryEngine.ts): Query engines are what generate the query you put in and give you back the result. Query engines generally combine a pre-built prompt with selected Nodes from your Index to give the LLM the context it needs to answer your query. To build a query engine from your Index (recommended), use the [`asQueryEngine`](/packages/llamaindex/src/indices/BaseIndex.ts) method on your Index. See all query engines [here](/packages/llamaindex/src/engines/query).
|
||||
export default {
|
||||
plugins: [wasm()],
|
||||
ssr: {
|
||||
external: ["tiktoken"],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- [ChatEngine](/packages/llamaindex/src/engines/chat/SimpleChatEngine.ts): A ChatEngine helps you build a chatbot that will interact with your Indices. See all chat engines [here](/packages/llamaindex/src/engines/chat).
|
||||
### Tips when using in non-Node.js environments
|
||||
|
||||
- [SimplePrompt](/packages/llamaindex/src/Prompt.ts): A simple standardized function call definition that takes in inputs and formats them in a template literal. SimplePrompts can be specialized using currying and combined using other SimplePrompt functions.
|
||||
|
||||
## Tips when using in non-Node.js environments
|
||||
|
||||
When you are importing `llamaindex` in a non-Node.js environment(such as React Server Components, Cloudflare Workers, etc.)
|
||||
When you are importing `llamaindex` in a non-Node.js environment(such as Vercel Edge, Cloudflare Workers, etc.)
|
||||
Some classes are not exported from top-level entry file.
|
||||
|
||||
The reason is that some classes are only compatible with Node.js runtime,(e.g. `PDFReader`) which uses Node.js specific APIs(like `fs`, `child_process`, `crypto`).
|
||||
@@ -212,19 +303,31 @@ export async function getDocuments() {
|
||||
|
||||
You'll find a complete example with LlamaIndexTS here: https://github.com/run-llama/create_llama_projects/tree/main/nextjs-edge-llamaparse
|
||||
|
||||
## Supported LLMs:
|
||||
## Playground
|
||||
|
||||
- OpenAI GPT-3.5-turbo and GPT-4
|
||||
- Anthropic Claude 3 (Opus, Sonnet, and Haiku) and the legacy models (Claude 2 and Instant)
|
||||
- Groq LLMs
|
||||
- Llama2/3 Chat LLMs (70B, 13B, and 7B parameters)
|
||||
- MistralAI Chat LLMs
|
||||
- Fireworks Chat LLMs
|
||||
Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
|
||||
|
||||
## Core concepts for getting started:
|
||||
|
||||
- [Document](/packages/llamaindex/src/Node.ts): A document represents a text file, PDF file or other contiguous piece of data.
|
||||
|
||||
- [Node](/packages/llamaindex/src/Node.ts): The basic data building block. Most commonly, these are parts of the document split into manageable pieces that are small enough to be fed into an embedding model and LLM.
|
||||
|
||||
- [Embedding](/packages/llamaindex/src/embeddings/OpenAIEmbedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that question. Because the default service context is OpenAI, the default embedding is `OpenAIEmbedding`. If using different models, say through Ollama, use this [Embedding](/packages/llamaindex/src/embeddings/OllamaEmbedding.ts) (see all [here](/packages/llamaindex/src/embeddings)).
|
||||
|
||||
- [Indices](/packages/llamaindex/src/indices/): Indices store the Nodes and the embeddings of those nodes. QueryEngines retrieve Nodes from these Indices using embedding similarity.
|
||||
|
||||
- [QueryEngine](/packages/llamaindex/src/engines/query/RetrieverQueryEngine.ts): Query engines are what generate the query you put in and give you back the result. Query engines generally combine a pre-built prompt with selected Nodes from your Index to give the LLM the context it needs to answer your query. To build a query engine from your Index (recommended), use the [`asQueryEngine`](/packages/llamaindex/src/indices/BaseIndex.ts) method on your Index. See all query engines [here](/packages/llamaindex/src/engines/query).
|
||||
|
||||
- [ChatEngine](/packages/llamaindex/src/engines/chat/SimpleChatEngine.ts): A ChatEngine helps you build a chatbot that will interact with your Indices. See all chat engines [here](/packages/llamaindex/src/engines/chat).
|
||||
|
||||
- [SimplePrompt](/packages/llamaindex/src/Prompt.ts): A simple standardized function call definition that takes in inputs and formats them in a template literal. SimplePrompts can be specialized using currying and combined using other SimplePrompt functions.
|
||||
|
||||
## Contributing:
|
||||
|
||||
We are in the very early days of LlamaIndex.TS. If you’re interested in hacking on it with us check out our [contributing guide](/CONTRIBUTING.md)
|
||||
Please see our [contributing guide](CONTRIBUTING.md) for more information.
|
||||
You are highly encouraged to contribute to LlamaIndex.TS!
|
||||
|
||||
## Bugs? Questions?
|
||||
## Community
|
||||
|
||||
Please join our Discord! https://discord.com/invite/eN6D2HQ4aX
|
||||
|
||||
@@ -1,5 +1,305 @@
|
||||
# docs
|
||||
|
||||
## 0.0.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.7.2
|
||||
|
||||
## 0.0.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ae49ff4]
|
||||
- Updated dependencies [4c38c1b]
|
||||
- Updated dependencies [a75af83]
|
||||
- Updated dependencies [a75af83]
|
||||
- llamaindex@0.7.1
|
||||
|
||||
## 0.0.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1364e8e]
|
||||
- Updated dependencies [3b7736f]
|
||||
- Updated dependencies [96fc69c]
|
||||
- llamaindex@0.7.0
|
||||
- @llamaindex/examples@0.0.9
|
||||
|
||||
## 0.0.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5729bd9]
|
||||
- llamaindex@0.6.22
|
||||
|
||||
## 0.0.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f75306]
|
||||
- Updated dependencies [94cb4ad]
|
||||
- llamaindex@0.6.21
|
||||
|
||||
## 0.0.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a9a7b1]
|
||||
- llamaindex@0.6.20
|
||||
|
||||
## 0.0.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [62cba52]
|
||||
- Updated dependencies [d265e96]
|
||||
- Updated dependencies [d30bbf7]
|
||||
- Updated dependencies [53fd00a]
|
||||
- llamaindex@0.6.19
|
||||
|
||||
## 0.0.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5f67820]
|
||||
- Updated dependencies [fe08d04]
|
||||
- llamaindex@0.6.18
|
||||
|
||||
## 0.0.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ee697fb]
|
||||
- llamaindex@0.6.17
|
||||
|
||||
## 0.0.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63e9846]
|
||||
- Updated dependencies [6f3a31c]
|
||||
- llamaindex@0.6.16
|
||||
|
||||
## 0.0.84
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2a82413]
|
||||
- llamaindex@0.6.15
|
||||
|
||||
## 0.0.83
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.6.14
|
||||
|
||||
## 0.0.82
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.6.13
|
||||
|
||||
## 0.0.81
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f7b4e94]
|
||||
- Updated dependencies [78037a6]
|
||||
- Updated dependencies [1d9e3b1]
|
||||
- llamaindex@0.6.12
|
||||
|
||||
## 0.0.80
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [df441e2]
|
||||
- llamaindex@0.6.11
|
||||
|
||||
## 0.0.79
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ebc5105]
|
||||
- Updated dependencies [6cce3b1]
|
||||
- llamaindex@0.6.10
|
||||
|
||||
## 0.0.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.6.9
|
||||
|
||||
## 0.0.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8b7fdba]
|
||||
- llamaindex@0.6.8
|
||||
|
||||
## 0.0.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [23bcc37]
|
||||
- llamaindex@0.6.7
|
||||
|
||||
## 0.0.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d902cc3]
|
||||
- Updated dependencies [025ffe6]
|
||||
- Updated dependencies [a659574]
|
||||
- llamaindex@0.6.6
|
||||
|
||||
## 0.0.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e9714db]
|
||||
- llamaindex@0.6.5
|
||||
|
||||
## 0.0.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- llamaindex@0.6.4
|
||||
|
||||
## 0.0.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- Updated dependencies [5c4badb]
|
||||
- llamaindex@0.6.3
|
||||
|
||||
## 0.0.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- llamaindex@0.6.2
|
||||
|
||||
## 0.0.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [fbd5e01]
|
||||
- Updated dependencies [6b70c54]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [85c2e19]
|
||||
- llamaindex@0.6.1
|
||||
|
||||
## 0.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- llamaindex@0.6.0
|
||||
- @llamaindex/examples@0.0.8
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4810364]
|
||||
- Updated dependencies [d3bc663]
|
||||
- llamaindex@0.5.25
|
||||
|
||||
## 0.0.65
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.5.24
|
||||
|
||||
## 0.0.64
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.5.23
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4648da6]
|
||||
- llamaindex@0.5.22
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ae1149f]
|
||||
- Updated dependencies [2411c9f]
|
||||
- Updated dependencies [e8f229c]
|
||||
- Updated dependencies [11b3856]
|
||||
- Updated dependencies [83d7f41]
|
||||
- Updated dependencies [0148354]
|
||||
- Updated dependencies [1711f6d]
|
||||
- llamaindex@0.5.21
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d9d6c56]
|
||||
- Updated dependencies [22ff486]
|
||||
- Updated dependencies [eed0b04]
|
||||
- llamaindex@0.5.20
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [fcbf183]
|
||||
- llamaindex@0.5.19
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8b66cf4]
|
||||
- llamaindex@0.5.18
|
||||
|
||||
## 0.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c654398]
|
||||
- llamaindex@0.5.17
|
||||
|
||||
## 0.0.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [58abc57]
|
||||
- llamaindex@0.5.16
|
||||
|
||||
## 0.0.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [01c184c]
|
||||
- Updated dependencies [07a275f]
|
||||
- llamaindex@0.5.15
|
||||
|
||||
## 0.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -6,10 +6,17 @@ sidebar_position: 2
|
||||
|
||||
We support Node.JS versions 18, 20 and 22, with experimental support for Deno, Bun and Vercel Edge functions.
|
||||
|
||||
## NextJS App Router
|
||||
## NextJS
|
||||
|
||||
If you're using NextJS App Router route handlers/serverless functions, you'll need to use the NodeJS mode:
|
||||
If you're using NextJS you'll need to add `withLlamaIndex` to your `next.config.js` file. This will add the necessary configuration for included 3rd-party libraries to your build:
|
||||
|
||||
```js
|
||||
export const runtime = "nodejs"; // default
|
||||
// next.config.js
|
||||
const withLlamaIndex = require("llamaindex/next");
|
||||
|
||||
module.exports = withLlamaIndex({
|
||||
// your next.js config
|
||||
});
|
||||
```
|
||||
|
||||
For details, check the latest [withLlamaIndex](https://github.com/run-llama/LlamaIndexTS/blob/main/packages/llamaindex/src/next.ts) implementation.
|
||||
|
||||
@@ -50,10 +50,10 @@ We want to see what our agent is up to, so we're going to hook into some events
|
||||
|
||||
```javascript
|
||||
Settings.callbackManager.on("llm-tool-call", (event) => {
|
||||
console.log(event.detail.payload);
|
||||
console.log(event.detail);
|
||||
});
|
||||
Settings.callbackManager.on("llm-tool-result", (event) => {
|
||||
console.log(event.detail.payload);
|
||||
console.log(event.detail);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ LlamaIndex.TS handles several major use cases:
|
||||
|
||||
- **Structured Data Extraction**: turning complex, unstructured and semi-structured data into uniform, programmatically accessible formats.
|
||||
- **Retrieval-Augmented Generation (RAG)**: answering queries across your internal data by providing LLMs with up-to-date, semantically relevant context including Question and Answer systems and chat bots.
|
||||
- **Autonomous Agents**: building software that is capable of intelligently selecting and using tools to accomplish tasks in an interative, unsupervised manner.
|
||||
- **Autonomous Agents**: building software that is capable of intelligently selecting and using tools to accomplish tasks in an interactive, unsupervised manner.
|
||||
|
||||
## 👨👩👧👦 Who is LlamaIndex for?
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Agents"
|
||||
position: 3
|
||||
position: 10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_position: 13
|
||||
---
|
||||
|
||||
# ChatEngine
|
||||
@@ -27,3 +27,4 @@ for await (const chunk of stream) {
|
||||
|
||||
- [ContextChatEngine](../api/classes/ContextChatEngine.md)
|
||||
- [CondenseQuestionChatEngine](../api/classes/ContextChatEngine.md)
|
||||
- [SimpleChatEngine](../api/classes/SimpleChatEngine.md)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
# Index
|
||||
@@ -8,6 +8,7 @@ An index is the basic container and organization for your data. LlamaIndex.TS su
|
||||
|
||||
- `VectorStoreIndex` - will send the top-k `Node`s to the LLM when generating a response. The default top-k is 2.
|
||||
- `SummaryIndex` - will send every `Node` in the index to the LLM in order to generate a response
|
||||
- `KeywordTableIndex` extracts and provides keywords from `Node`s to the LLM
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
@@ -21,3 +22,4 @@ const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
- [SummaryIndex](../api/classes/SummaryIndex.md)
|
||||
- [VectorStoreIndex](../api/classes/VectorStoreIndex.md)
|
||||
- [KeywordTableIndex](../api/classes/KeywordTableIndex.md)
|
||||
|
||||
@@ -6,6 +6,19 @@ import CodeSource2 from "!raw-loader!../../../../../examples/readers/src/custom-
|
||||
|
||||
Before you can start indexing your documents, you need to load them into memory.
|
||||
|
||||
All "basic" data loaders can be seen below, mapped to their respective filetypes in `SimpleDirectoryReader`. More loaders are shown in the sidebar on the left.
|
||||
Additionally the following loaders exist without separate documentation:
|
||||
|
||||
- `AssemblyAIReader` transcribes audio using [AssemblyAI](https://www.assemblyai.com/).
|
||||
- [AudioTranscriptReader](../../api/classes/AudioTranscriptReader.md): loads entire transcript as a single document.
|
||||
- [AudioTranscriptParagraphsReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document per paragraph.
|
||||
- [AudioTranscriptSentencesReader](../../api/classes/AudioTranscriptSentencesReader.md): creates a document per sentence.
|
||||
- [AudioSubtitlesReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document containing the subtitles of a transcript.
|
||||
- [NotionReader](../../api/classes/NotionReader.md) loads [Notion](https://www.notion.so/) pages.
|
||||
- [SimpleMongoReader](../../api/classes/SimpleMongoReader) loads data from a [MongoDB](https://www.mongodb.com/).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## SimpleDirectoryReader
|
||||
|
||||
[](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples/readers?file=src/simple-directory-reader.ts&title=Simple%20Directory%20Reader)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
A simple JSON data loader with various options.
|
||||
Either parses the entire string, cleaning it and treat each line as an embedding or performs a recursive depth-first traversal yielding JSON paths.
|
||||
Supports streaming of large JSON data using [@discoveryjs/json-ext](https://github.com/discoveryjs/json-ext)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -20,12 +21,16 @@ const docsFromContent = reader.loadDataAsContent(content);
|
||||
|
||||
Basic:
|
||||
|
||||
- `streamingThreshold?`: The threshold for using streaming mode in MB of the JSON Data. CEstimates characters by calculating bytes: `(streamingThreshold * 1024 * 1024) / 2` and comparing against `.length` of the JSON string. Set `undefined` to disable streaming or `0` to always use streaming. Default is `50` MB.
|
||||
|
||||
- `ensureAscii?`: Wether to ensure only ASCII characters be present in the output by converting non-ASCII characters to their unicode escape sequence. Default is `false`.
|
||||
|
||||
- `isJsonLines?`: Wether the JSON is in JSON Lines format. If true, will split into lines, remove empty one and parse each line as JSON. Default is `false`
|
||||
- `isJsonLines?`: Wether the JSON is in JSON Lines format. If true, will split into lines, remove empty one and parse each line as JSON. Note: Uses a custom streaming parser, most likely less robust than json-ext. Default is `false`
|
||||
|
||||
- `cleanJson?`: Whether to clean the JSON by filtering out structural characters (`{}, [], and ,`). If set to false, it will just parse the JSON, not removing structural characters. Default is `true`.
|
||||
|
||||
- `logger?`: A placeholder for a custom logger function.
|
||||
|
||||
Depth-First-Traversal:
|
||||
|
||||
- `levelsBack?`: Specifies how many levels up the JSON structure to include in the output. `cleanJson` will be ignored. If set to 0, all levels are included. If undefined, parses the entire JSON, treat each line as an embedding and create a document per top-level array. Default is `undefined`
|
||||
|
||||
@@ -13,7 +13,7 @@ Official documentation for LlamaParse can be found [here](https://docs.cloud.lla
|
||||
## Usage
|
||||
|
||||
You can then use the `LlamaParseReader` class to load local files and convert them into a parsed document that can be used by LlamaIndex.
|
||||
See [LlamaParseReader.ts](https://github.com/run-llama/LlamaIndexTS/blob/main/packages/llamaindex/src/readers/LlamaParseReader.ts) for a list of supported file types:
|
||||
See [reader.ts](https://github.com/run-llama/LlamaIndexTS/blob/main/packages/cloud/src/reader.ts) for a list of supported file types:
|
||||
|
||||
<CodeBlock language="ts">{CodeSource}</CodeBlock>
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
label: "Data Stores"
|
||||
position: 2
|
||||
@@ -0,0 +1 @@
|
||||
label: "Chat Stores"
|
||||
@@ -0,0 +1,13 @@
|
||||
# Chat Stores
|
||||
|
||||
Chat stores manage chat history by storing sequences of messages in a structured way, ensuring the order of messages is maintained for accurate conversation flow.
|
||||
|
||||
## Available Chat Stores
|
||||
|
||||
- [SimpleChatStore](../../../api/classes/SimpleChatStore.md): A simple in-memory chat store with support for [persisting](../index.md#local-storage) data to disk.
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseChatStore](../../../api/interfaces/BaseChatStore.md)
|
||||
@@ -0,0 +1,2 @@
|
||||
label: "Document Stores"
|
||||
position: 2
|
||||
@@ -0,0 +1,14 @@
|
||||
# Document Stores
|
||||
|
||||
Document stores contain ingested document chunks, i.e. [Node](../../documents_and_nodes/index.md)s.
|
||||
|
||||
## Available Document Stores
|
||||
|
||||
- [SimpleDocumentStore](../../../api/classes/SimpleDocumentStore.md): A simple in-memory document store with support for [persisting](../index.md#local-storage) data to disk.
|
||||
- [PostgresDocumentStore](../../../api/classes/PostgresDocumentStore.md): A PostgreSQL document store, see [PostgreSQL Storage](../index.md#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseDocumentStore](../../../api/classes/BaseDocumentStore.md)
|
||||
@@ -0,0 +1,56 @@
|
||||
# Storage
|
||||
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a
|
||||
`StorageContext` object.
|
||||
|
||||
## Local Storage
|
||||
|
||||
You can configure the `persistDir` and attach it to an index.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
persistDir: "./storage",
|
||||
});
|
||||
|
||||
const document = new Document({ text: "Test Text" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## PostgreSQL Storage
|
||||
|
||||
You can configure the `schemaName`, `tableName`, `namespace`, and
|
||||
`connectionString`. If a `connectionString` is not
|
||||
provided, it will use the environment variables `PGHOST`, `PGUSER`,
|
||||
`PGPASSWORD`, `PGDATABASE` and `PGPORT`.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
PostgresDocumentStore,
|
||||
PostgresIndexStore,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
docStore: new PostgresDocumentStore(),
|
||||
indexStore: new PostgresIndexStore(),
|
||||
});
|
||||
|
||||
const document = new Document({ text: "Test Text" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [StorageContext](../../api/interfaces/StorageContext.md)
|
||||
@@ -0,0 +1,2 @@
|
||||
label: "Index Stores"
|
||||
position: 3
|
||||
@@ -0,0 +1,14 @@
|
||||
# Index Stores
|
||||
|
||||
Index stores are underlying storage components that contain metadata(i.e. information created when indexing) about the [index](../../data_index.md) itself.
|
||||
|
||||
## Available Index Stores
|
||||
|
||||
- [SimpleIndexStore](../../../api/classes/SimpleIndexStore.md): A simple in-memory index store with support for [persisting](../index.md#local-storage) data to disk.
|
||||
- [PostgresIndexStore](../../../api/classes/PostgresIndexStore.md): A PostgreSQL index store, , see [PostgreSQL Storage](../index.md#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseIndexStore](../../../api/classes/BaseIndexStore.md)
|
||||
@@ -0,0 +1,2 @@
|
||||
label: "Key-Value Stores"
|
||||
position: 4
|
||||
@@ -0,0 +1,14 @@
|
||||
# Key-Value Stores
|
||||
|
||||
Key-Value Stores represent underlying storage components used in [Document Stores](../doc_stores/index.md) and [Index Stores](../index_stores/index.md)
|
||||
|
||||
## Available Key-Value Stores
|
||||
|
||||
- [SimpleKVStore](../../../api/classes/SimpleKVStore.md): A simple Key-Value store with support of [persisting](../index.md#local-storage) data to disk.
|
||||
- [PostgresKVStore](../../../api/classes/PostgresKVStore.md): A PostgreSQL Key-Value store, see [PostgreSQL Storage](../index.md#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseKVStore](../../../api/classes/BaseKVStore.md)
|
||||
@@ -0,0 +1,22 @@
|
||||
# Vector Stores
|
||||
|
||||
Vector stores save embedding vectors of your ingested document chunks.
|
||||
|
||||
## Available Vector Stores
|
||||
|
||||
Available Vector Stores are shown on the sidebar to the left. Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [SimpleVectorStore](../../../api/classes/SimpleVectorStore.md): A simple in-memory vector store with optional [persistance](../index.md#local-storage) to disk.
|
||||
- [AstraDBVectorStore](../../../api/classes/AstraDBVectorStore.md): A cloud-native, scalable Database-as-a-Service built on Apache Cassandra, see [datastax.com](https://www.datastax.com/products/datastax-astra)
|
||||
- [ChromaVectorStore](../../../api/classes/ChromaVectorStore.md): An open-source vector database, focused on ease of use and performance, see [trychroma.com](https://www.trychroma.com/)
|
||||
- [MilvusVectorStore](../../../api/classes/MilvusVectorStore.md): An open-source, high-performance, highly scalable vector database, see [milvus.io](https://milvus.io/)
|
||||
- [MongoDBAtlasVectorSearch](../../../api/classes/MongoDBAtlasVectorSearch.md): A cloud-based vector search solution for MongoDB, see [mongodb.com](https://www.mongodb.com/products/platform/atlas-vector-search)
|
||||
- [PGVectorStore](../../../api/classes/PGVectorStore.md): An open-source vector store built on PostgreSQL, see [pgvector Github](https://github.com/pgvector/pgvector)
|
||||
- [PineconeVectorStore](../../../api/classes/PineconeVectorStore.md): A managed, cloud-native vector database, see [pinecone.io](https://www.pinecone.io/)
|
||||
- [WeaviateVectorStore](../../../api/classes/WeaviateVectorStore.md): An open-source, ai-native vector database, see [weaviate.io](https://weaviate.io/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [VectorStoreBase](../../../api/classes/VectorStoreBase.md)
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
# Qdrant Vector Store
|
||||
|
||||
[qdrant.tech](https://qdrant.tech/)
|
||||
|
||||
To run this example, you need to have a Qdrant instance running. You can run it with Docker:
|
||||
|
||||
```bash
|
||||
@@ -87,4 +89,4 @@ main().catch(console.error);
|
||||
|
||||
## API Reference
|
||||
|
||||
- [QdrantVectorStore](../../api/classes/QdrantVectorStore.md)
|
||||
- [QdrantVectorStore](../../../api/classes/QdrantVectorStore.md)
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Documents and Nodes
|
||||
|
||||
`Document`s and `Node`s are the basic building blocks of any index. While the API for these objects is similar, `Document` objects represent entire files, while `Node`s are smaller pieces of that original document, that are suitable for an LLM and Q&A.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Embeddings"
|
||||
position: 3
|
||||
position: 6
|
||||
|
||||
@@ -7,7 +7,7 @@ To find out more about the latest features, updates, and available models, visit
|
||||
## Table of Contents
|
||||
|
||||
1. [Setup](#setup)
|
||||
2. [Usage with LlamaIndex](#integration-with-llamaindex)
|
||||
2. [Usage with LlamaIndex](#usage-with-llamaindex)
|
||||
3. [Embeddings with Custom Parameters](#embeddings-with-custom-parameters)
|
||||
|
||||
## Setup
|
||||
@@ -98,3 +98,7 @@ Use the `embedDocuments` method to generate embeddings for the texts.
|
||||
const result = await embeddings.embedDocuments(texts);
|
||||
console.log(result); // Perfectly customized embeddings, ready to serve.
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [MixedbreadAIEmbeddings](../../../api/classes/MixedbreadAIEmbeddings.md)
|
||||
|
||||
@@ -16,6 +16,16 @@ Settings.embedModel = new OpenAIEmbedding({
|
||||
|
||||
For local embeddings, you can use the [HuggingFace](./available_embeddings/huggingface.md) embedding model.
|
||||
|
||||
## Available Embeddings
|
||||
|
||||
Most available embeddings are listed in the sidebar on the left.
|
||||
Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [ClipEmbedding](../../api/classes/ClipEmbedding.md) using `@xenova/transformers`
|
||||
- [FireworksEmbedding](../../api/classes/FireworksEmbedding.md) see [fireworks.ai](https://fireworks.ai/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAIEmbedding](../../api/classes/OpenAIEmbedding.md)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Evaluating"
|
||||
position: 3
|
||||
position: 9
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Concept
|
||||
|
||||
Evaluation and benchmarking are crucial concepts in LLM development. To improve the perfomance of an LLM app (RAG, agents) you must have a way to measure it.
|
||||
Evaluation and benchmarking are crucial concepts in LLM development. To improve the performance of an LLM app (RAG, agents) you must have a way to measure it.
|
||||
|
||||
LlamaIndex offers key modules to measure the quality of generated results. We also offer key modules to measure retrieval quality.
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Ingestion Pipeline"
|
||||
position: 2
|
||||
position: 4
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
MetadataMode,
|
||||
OpenAIEmbedding,
|
||||
TitleExtractor,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
@@ -29,7 +29,7 @@ async function main() {
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new TitleExtractor(),
|
||||
new OpenAIEmbedding(),
|
||||
],
|
||||
@@ -62,7 +62,7 @@ import {
|
||||
MetadataMode,
|
||||
OpenAIEmbedding,
|
||||
TitleExtractor,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
QdrantVectorStore,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -81,7 +81,7 @@ async function main() {
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new TitleExtractor(),
|
||||
new OpenAIEmbedding(),
|
||||
],
|
||||
|
||||
@@ -4,7 +4,7 @@ A transformation is something that takes a list of nodes as an input, and return
|
||||
|
||||
Currently, the following components are Transformation objects:
|
||||
|
||||
- [SimpleNodeParser](../../api/classes/SimpleNodeParser.md)
|
||||
- [SentenceSplitter](../../api/classes/SentenceSplitter.md)
|
||||
- [MetadataExtractor](../documents_and_nodes/metadata_extraction.md)
|
||||
- [Embeddings](../embeddings/index.md)
|
||||
|
||||
@@ -13,10 +13,10 @@ Currently, the following components are Transformation objects:
|
||||
While transformations are best used with with an IngestionPipeline, they can also be used directly.
|
||||
|
||||
```ts
|
||||
import { SimpleNodeParser, TitleExtractor, Document } from "llamaindex";
|
||||
import { SentenceSplitter, TitleExtractor, Document } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
let nodes = new SimpleNodeParser().getNodesFromDocuments([
|
||||
let nodes = new SentenceSplitter().getNodesFromDocuments([
|
||||
new Document({ text: "I am 10 years old. John is 20 years old." }),
|
||||
]);
|
||||
|
||||
@@ -34,15 +34,15 @@ main().catch(console.error);
|
||||
|
||||
## Custom Transformations
|
||||
|
||||
You can implement any transformation yourself by implementing the `TransformerComponent`.
|
||||
You can implement any transformation yourself by implementing the `TransformComponent`.
|
||||
|
||||
The following custom transformation will remove any special characters or punctutaion in text.
|
||||
The following custom transformation will remove any special characters or punctuation in text.
|
||||
|
||||
```ts
|
||||
import { TransformerComponent, Node } from "llamaindex";
|
||||
import { TransformComponent, TextNode } from "llamaindex";
|
||||
|
||||
class RemoveSpecialCharacters extends TransformerComponent {
|
||||
async transform(nodes: Node[]): Promise<Node[]> {
|
||||
export class RemoveSpecialCharacters extends TransformComponent {
|
||||
async transform(nodes: TextNode[]): Promise<TextNode[]> {
|
||||
for (const node of nodes) {
|
||||
node.text = node.text.replace(/[^\w\s]/gi, "");
|
||||
}
|
||||
@@ -75,3 +75,7 @@ async function main() {
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [TransformComponent](../../api/classes/TransformComponent.md)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "LLMs"
|
||||
position: 3
|
||||
position: 5
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# DeepSeek LLM
|
||||
|
||||
[DeepSeek Platform](https://platform.deepseek.com/)
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
@@ -45,6 +47,6 @@ Currently does not support function calling.
|
||||
|
||||
[Currently does not support json-output param while still is very good at json generating.](https://platform.deepseek.com/api-docs/faq#does-your-api-support-json-output)
|
||||
|
||||
## API platform
|
||||
## API Reference
|
||||
|
||||
- [DeepSeek platform](https://platform.deepseek.com/)
|
||||
- [DeepSeekLLM](../../../api/classes/DeepSeekLLM.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fireworks LLM
|
||||
|
||||
Fireworks.ai focus on production use cases for open source LLMs, offering speed and quality.
|
||||
[Fireworks.ai](https://fireworks.ai/) focus on production use cases for open source LLMs, offering speed and quality.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Large Language Models (LLMs)
|
||||
|
||||
The LLM is responsible for reading text and generating natural language responses to queries. By default, LlamaIndex.TS uses `gpt-3.5-turbo`.
|
||||
@@ -30,6 +26,15 @@ export AZURE_OPENAI_DEPLOYMENT="gpt-4" # or some other deployment name
|
||||
|
||||
For local LLMs, currently we recommend the use of [Ollama](./available_llms/ollama.md) LLM.
|
||||
|
||||
## Available LLMs
|
||||
|
||||
Most available LLMs are listed in the sidebar on the left. Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [HuggingFaceLLM](../../api/classes/HuggingFaceLLM.md) and [HuggingFaceInferenceAPI](../../api/classes/HuggingFaceInferenceAPI.md).
|
||||
- [ReplicateLLM](../../api/classes/ReplicateLLM.md) see [replicate.com](https://replicate.com/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAI](../../api/classes/OpenAI.md)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
# NodeParser
|
||||
@@ -7,9 +7,9 @@ sidebar_position: 4
|
||||
The `NodeParser` in LlamaIndex is responsible for splitting `Document` objects into more manageable `Node` objects. When you call `.fromDocuments()`, the `NodeParser` from the `Settings` is used to do this automatically for you. Alternatively, you can use it to split documents ahead of time.
|
||||
|
||||
```typescript
|
||||
import { Document, SimpleNodeParser } from "llamaindex";
|
||||
import { Document, SentenceSplitter } from "llamaindex";
|
||||
|
||||
const nodeParser = new SimpleNodeParser();
|
||||
const nodeParser = new SentenceSplitter();
|
||||
|
||||
Settings.nodeParser = nodeParser;
|
||||
```
|
||||
@@ -93,6 +93,5 @@ The output metadata will be something like:
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SimpleNodeParser](../api/classes/SimpleNodeParser.md)
|
||||
- [SentenceSplitter](../api/classes/SentenceSplitter.md)
|
||||
- [MarkdownNodeParser](../api/classes/MarkdownNodeParser.md)
|
||||
|
||||
@@ -107,3 +107,4 @@ const filteredNodes = processor.postprocessNodes(nodes);
|
||||
## API Reference
|
||||
|
||||
- [SimilarityPostprocessor](../../api/classes/SimilarityPostprocessor.md)
|
||||
- [MetadataReplacementPostProcessor](../../api/classes/MetadataReplacementPostProcessor.md)
|
||||
|
||||
@@ -7,7 +7,7 @@ To find out more about the latest features and updates, visit the [mixedbread.ai
|
||||
## Table of Contents
|
||||
|
||||
1. [Setup](#setup)
|
||||
2. [Usage with LlamaIndex](#integration-with-llamaindex)
|
||||
2. [Usage with LlamaIndex](#usage-with-llamaindex)
|
||||
3. [Simple Reranking Guide](#simple-reranking-guide)
|
||||
4. [Reranking with Objects](#reranking-with-objects)
|
||||
|
||||
@@ -163,3 +163,7 @@ Use the `rerank` method to reorder the documents based on the query.
|
||||
const result = await reranker.rerank(documents, query);
|
||||
console.log(result); // Perfectly customized results, ready to serve.
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [MixedbreadAIReranker](../../api/classes/MixedbreadAIReranker.md)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Prompts"
|
||||
position: 0
|
||||
position: 7
|
||||
|
||||
@@ -73,6 +73,5 @@ const response = await queryEngine.query({
|
||||
|
||||
## API Reference
|
||||
|
||||
- [TextQaPrompt](../../api/type-aliases/TextQaPrompt.md)
|
||||
- [ResponseSynthesizer](../../api/classes/ResponseSynthesizer.md)
|
||||
- [CompactAndRefine](../../api/classes/CompactAndRefine.md)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Query Engines"
|
||||
position: 2
|
||||
position: 8
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# QueryEngine
|
||||
|
||||
A query engine wraps a `Retriever` and a `ResponseSynthesizer` into a pipeline, that will use the query string to fetech nodes and then send them to the LLM to generate a response.
|
||||
A query engine wraps a `Retriever` and a `ResponseSynthesizer` into a pipeline, that will use the query string to fetch nodes and then send them to the LLM to generate a response.
|
||||
|
||||
```typescript
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
OpenAI,
|
||||
RouterQueryEngine,
|
||||
SimpleDirectoryReader,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
SummaryIndex,
|
||||
VectorStoreIndex,
|
||||
Settings,
|
||||
@@ -34,11 +34,11 @@ const documents = await new SimpleDirectoryReader().loadData({
|
||||
|
||||
## Service Context
|
||||
|
||||
Next, we need to define some basic rules and parse the documents into nodes. We will use the `SimpleNodeParser` to parse the documents into nodes and `Settings` to define the rules (eg. LLM API key, chunk size, etc.):
|
||||
Next, we need to define some basic rules and parse the documents into nodes. We will use the `SentenceSplitter` to parse the documents into nodes and `Settings` to define the rules (eg. LLM API key, chunk size, etc.):
|
||||
|
||||
```ts
|
||||
Settings.llm = new OpenAI();
|
||||
Settings.nodeParser = new SimpleNodeParser({
|
||||
Settings.nodeParser = new SentenceSplitter({
|
||||
chunkSize: 1024,
|
||||
});
|
||||
```
|
||||
@@ -104,14 +104,14 @@ import {
|
||||
OpenAI,
|
||||
RouterQueryEngine,
|
||||
SimpleDirectoryReader,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
SummaryIndex,
|
||||
VectorStoreIndex,
|
||||
Settings,
|
||||
} from "llamaindex";
|
||||
|
||||
Settings.llm = new OpenAI();
|
||||
Settings.nodeParser = new SimpleNodeParser({
|
||||
Settings.nodeParser = new SentenceSplitter({
|
||||
chunkSize: 1024,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
sidebar_position: 15
|
||||
---
|
||||
|
||||
# ResponseSynthesizer
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
sidebar_position: 14
|
||||
---
|
||||
|
||||
# Retriever
|
||||
|
||||
A retriever in LlamaIndex is what is used to fetch `Node`s from an index using a query string. Aa `VectorIndexRetriever` will fetch the top-k most similar nodes. Meanwhile, a `SummaryIndexRetriever` will fetch all nodes no matter the query.
|
||||
A retriever in LlamaIndex is what is used to fetch `Node`s from an index using a query string.
|
||||
|
||||
- [VectorIndexRetriever](../api/classes/VectorIndexRetriever.md) will fetch the top-k most similar nodes. Ideal for dense retrieval to find most relevant nodes.
|
||||
- [SummaryIndexRetriever](../api/classes/SummaryIndexRetriever.md) will fetch all nodes no matter the query. Ideal when complete context is necessary, e.g. analyzing large datasets.
|
||||
- [SummaryIndexLLMRetriever](../api/classes/SummaryIndexLLMRetriever.md) utilizes an LLM to score and filter nodes based on relevancy to the query.
|
||||
- [KeywordTableLLMRetriever](../api/classes/KeywordTableLLMRetriever.md) uses an LLM to extract keywords from the query and retrieve relevant nodes based on keyword matches.
|
||||
- [KeywordTableSimpleRetriever](../api/classes/KeywordTableSimpleRetriever.md) uses a basic frequency-based approach to extract keywords and retrieve nodes.
|
||||
- [KeywordTableRAKERetriever](../api/classes/KeywordTableRAKERetriever.md) uses the RAKE (Rapid Automatic Keyword Extraction) algorithm to extract keywords from the query, focusing on co-occurrence and context for keyword-based retrieval.
|
||||
|
||||
```typescript
|
||||
const retriever = vectorIndex.asRetriever({
|
||||
@@ -14,9 +21,3 @@ const retriever = vectorIndex.asRetriever({
|
||||
// Fetch nodes!
|
||||
const nodesWithScore = await retriever.retrieve({ query: "query string" });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SummaryIndexRetriever](../api/classes/SummaryIndexRetriever.md)
|
||||
- [SummaryIndexLLMRetriever](../api/classes/SummaryIndexLLMRetriever.md)
|
||||
- [VectorIndexRetriever](../api/classes/VectorIndexRetriever.md)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Storage
|
||||
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a `StorageContext` object. Just configure the `persistDir` and attach it to an index.
|
||||
|
||||
Right now, only saving and loading from disk is supported, with future integrations planned!
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex, storageContextFromDefaults } from "./src";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
persistDir: "./storage",
|
||||
});
|
||||
|
||||
const document = new Document({ text: "Test Text" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [StorageContext](../api/interfaces/StorageContext.md)
|
||||
@@ -0,0 +1,168 @@
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import CodeSource from "!raw-loader!../../../../examples/workflow/joke.ts";
|
||||
|
||||
# Workflows
|
||||
|
||||
A `Workflow` in LlamaIndexTS is an event-driven abstraction used to chain together several events. Workflows are made up of `steps`, with each step responsible for handling certain event types and emitting new events.
|
||||
|
||||
Workflows in LlamaIndexTS work by defining step functions that handle specific event types and emit new events.
|
||||
|
||||
When a step function is added to a workflow, you need to specify the input and optionally the output event types (used for validation). The specification of the input events ensures each step only runs when an accepted event is ready.
|
||||
|
||||
You can create a `Workflow` to do anything! Build an agent, a RAG flow, an extraction flow, or anything else you want.
|
||||
|
||||
## Getting Started
|
||||
|
||||
As an illustrative example, let's consider a naive workflow where a joke is generated and then critiqued.
|
||||
|
||||
<CodeBlock language="ts">{CodeSource}</CodeBlock>
|
||||
|
||||
There's a few moving pieces here, so let's go through this piece by piece.
|
||||
|
||||
### Defining Workflow Events
|
||||
|
||||
```typescript
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
```
|
||||
|
||||
Events are user-defined classes that extend `WorkflowEvent` and contain arbitrary data provided as template argument. In this case, our workflow relies on a single user-defined event, the `JokeEvent` with a `joke` attribute of type `string`.
|
||||
|
||||
### Setting up the Workflow Class
|
||||
|
||||
```typescript
|
||||
const llm = new OpenAI();
|
||||
...
|
||||
const jokeFlow = new Workflow({ verbose: true });
|
||||
```
|
||||
|
||||
Our workflow is implemented by initiating the `Workflow` class. For simplicity, we created a `OpenAI` llm instance.
|
||||
|
||||
### Workflow Entry Points
|
||||
|
||||
```typescript
|
||||
const generateJoke = async (_context: Context, ev: StartEvent) => {
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Here, we come to the entry-point of our workflow. While events are user-defined, there are two special-case events, the `StartEvent` and the `StopEvent`. Here, the `StartEvent` signifies where to send the initial workflow input.
|
||||
|
||||
The `StartEvent` is a bit of a special object since it can hold arbitrary attributes. Here, we accessed the topic with `ev.data.input`.
|
||||
|
||||
At this point, you may have noticed that we haven't explicitly told the workflow what events are handled by which steps.
|
||||
|
||||
To do so, we use the `addStep` method which adds a step to the workflow. The first argument is the event type that the step will handle, and the second argument is the previously defined step function:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(StartEvent, generateJoke);
|
||||
```
|
||||
|
||||
### Workflow Exit Points
|
||||
|
||||
```typescript
|
||||
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Here, we have our second, and last step, in the workflow. We know its the last step because the special `StopEvent` is returned. When the workflow encounters a returned `StopEvent`, it immediately stops the workflow and returns whatever the result was.
|
||||
|
||||
In this case, the result is a string, but it could be a map, array, or any other object.
|
||||
|
||||
Don't forget to add the step to the workflow:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke);
|
||||
```
|
||||
|
||||
### Running the Workflow
|
||||
|
||||
```typescript
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data.result);
|
||||
```
|
||||
|
||||
Lastly, we run the workflow. The `.run()` method is async, so we use await here to wait for the result.
|
||||
|
||||
### Validating Workflows
|
||||
|
||||
To tell the workflow what events are produced by each step, you can optionally provide a third argument to `addStep` to specify the output event type:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(StartEvent, generateJoke, { outputs: JokeEvent });
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke, { outputs: StopEvent });
|
||||
```
|
||||
|
||||
To validate a workflow, you need to call the `validate` method:
|
||||
|
||||
```typescript
|
||||
jokeFlow.validate();
|
||||
```
|
||||
|
||||
To automatically validate a workflow when you run it, you can set the `validate` flag to `true` at initialization:
|
||||
|
||||
```typescript
|
||||
const jokeFlow = new Workflow({ verbose: true, validate: true });
|
||||
```
|
||||
|
||||
## Working with Global Context/State
|
||||
|
||||
Optionally, you can choose to use global context between steps. For example, maybe multiple steps access the original `query` input from the user. You can store this in global context so that every step has access.
|
||||
|
||||
```typescript
|
||||
import { Context } from "@llamaindex/core/workflow";
|
||||
|
||||
const query = async (context: Context, ev: MyEvent) => {
|
||||
// get the query from the context
|
||||
const query = context.get("query");
|
||||
// do something with context and event
|
||||
const val = ...
|
||||
const result = ...
|
||||
// store in context
|
||||
context.set("key", val);
|
||||
|
||||
return new StopEvent({ result });
|
||||
};
|
||||
```
|
||||
|
||||
## Waiting for Multiple Events
|
||||
|
||||
The context does more than just hold data, it also provides utilities to buffer and wait for multiple events.
|
||||
|
||||
For example, you might have a step that waits for a query and retrieved nodes before synthesizing a response:
|
||||
|
||||
```typescript
|
||||
const synthesize = async (context: Context, ev: QueryEvent | RetrieveEvent) => {
|
||||
const events = context.collectEvents(ev, [QueryEvent | RetrieveEvent]);
|
||||
if (!events) {
|
||||
return;
|
||||
}
|
||||
const prompt = events
|
||||
.map((event) => {
|
||||
if (event instanceof QueryEvent) {
|
||||
return `Answer this query using the context provided: ${event.data.query}`;
|
||||
} else if (event instanceof RetrieveEvent) {
|
||||
return `Context: ${event.data.context}`;
|
||||
}
|
||||
return "";
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Using `ctx.collectEvents()` we can buffer and wait for ALL expected events to arrive. This function will only return events (in the requested order) once all events have arrived.
|
||||
|
||||
## Manually Triggering Events
|
||||
|
||||
Normally, events are triggered by returning another event during a step. However, events can also be manually dispatched using the `ctx.sendEvent(event)` method within a workflow.
|
||||
|
||||
## Examples
|
||||
|
||||
You can find many useful examples of using workflows in the [examples folder](https://github.com/run-llama/LlamaIndexTS/blob/main/examples/workflow).
|
||||
+14
-14
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.55",
|
||||
"version": "0.0.94",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
@@ -15,29 +15,29 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.4.0",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "3.4.0",
|
||||
"@docusaurus/core": "3.5.2",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "3.5.2",
|
||||
"@llamaindex/examples": "workspace:*",
|
||||
"@mdx-js/react": "3.0.1",
|
||||
"clsx": "2.1.1",
|
||||
"llamaindex": "workspace:*",
|
||||
"postcss": "8.4.39",
|
||||
"prism-react-renderer": "2.3.1",
|
||||
"postcss": "8.4.41",
|
||||
"prism-react-renderer": "2.4.0",
|
||||
"raw-loader": "4.0.2",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.4.0",
|
||||
"@docusaurus/preset-classic": "3.4.0",
|
||||
"@docusaurus/theme-classic": "3.4.0",
|
||||
"@docusaurus/types": "3.4.0",
|
||||
"@docusaurus/module-type-aliases": "3.5.2",
|
||||
"@docusaurus/preset-classic": "3.5.2",
|
||||
"@docusaurus/theme-classic": "3.5.2",
|
||||
"@docusaurus/types": "3.5.2",
|
||||
"@tsconfig/docusaurus": "2.0.3",
|
||||
"@types/node": "^20.12.11",
|
||||
"docusaurus-plugin-typedoc": "1.0.3",
|
||||
"typedoc": "0.26.4",
|
||||
"typedoc-plugin-markdown": "4.1.2",
|
||||
"typescript": "^5.5.3"
|
||||
"@types/node": "^22.5.1",
|
||||
"docusaurus-plugin-typedoc": "1.0.5",
|
||||
"typedoc": "0.26.6",
|
||||
"typedoc-plugin-markdown": "4.2.6",
|
||||
"typescript": "^5.6.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": ["//"],
|
||||
"tasks": {
|
||||
"build": {
|
||||
"outputs": ["build/**", ".docusaurus/**"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
# examples
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1364e8e]
|
||||
- Updated dependencies [96fc69c]
|
||||
- Updated dependencies [3b7736f]
|
||||
- Updated dependencies [96fc69c]
|
||||
- llamaindex@0.7.0
|
||||
- @llamaindex/core@0.3.0
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 11feef8: Add workflows
|
||||
- Updated dependencies [11feef8]
|
||||
- @llamaindex/core@0.2.0
|
||||
- llamaindex@0.6.0
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,7 +13,7 @@ import { FunctionTool, OpenAI, ToolCallOptions } from "llamaindex";
|
||||
}
|
||||
})();
|
||||
|
||||
async function callLLM(init: Partial<OpenAI>) {
|
||||
async function callLLM(init: { model: string }) {
|
||||
const csvData =
|
||||
"Country,Average Height (cm)\nNetherlands,156\nDenmark,158\nNorway,160";
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
OpenAI,
|
||||
OpenAIAgent,
|
||||
QueryEngineTool,
|
||||
SentenceSplitter,
|
||||
Settings,
|
||||
SimpleNodeParser,
|
||||
SimpleToolNodeMapping,
|
||||
SummaryIndex,
|
||||
VectorStoreIndex,
|
||||
@@ -43,7 +43,7 @@ async function main() {
|
||||
for (const title of wikiTitles) {
|
||||
console.log(`Processing ${title}`);
|
||||
|
||||
const nodes = new SimpleNodeParser({
|
||||
const nodes = new SentenceSplitter({
|
||||
chunkSize: 200,
|
||||
chunkOverlap: 20,
|
||||
}).getNodesFromDocuments([countryDocs[title]]);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ChatResponseChunk, OpenAIAgent } from "llamaindex";
|
||||
import { ReadableStream } from "node:stream/web";
|
||||
import {
|
||||
getCurrentIDTool,
|
||||
getUserInfoTool,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ChatResponseChunk, ReActAgent } from "llamaindex";
|
||||
import { ReadableStream } from "node:stream/web";
|
||||
import {
|
||||
getCurrentIDTool,
|
||||
getUserInfoTool,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Anthropic, SimpleChatEngine, SimpleChatHistory } from "llamaindex";
|
||||
import { Anthropic, ChatMemoryBuffer, SimpleChatEngine } from "llamaindex";
|
||||
import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
@@ -8,8 +8,8 @@ import readline from "node:readline/promises";
|
||||
model: "claude-3-opus",
|
||||
});
|
||||
// chatHistory will store all the messages in the conversation
|
||||
const chatHistory = new SimpleChatHistory({
|
||||
messages: [
|
||||
const chatHistory = new ChatMemoryBuffer({
|
||||
chatHistory: [
|
||||
{
|
||||
content: "You want to talk in rhymes.",
|
||||
role: "system",
|
||||
@@ -18,7 +18,7 @@ import readline from "node:readline/promises";
|
||||
});
|
||||
const chatEngine = new SimpleChatEngine({
|
||||
llm,
|
||||
chatHistory,
|
||||
memory: chatHistory,
|
||||
});
|
||||
const rl = readline.createInterface({ input, output });
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
AstraDBVectorStore,
|
||||
Document,
|
||||
MetadataFilters,
|
||||
storageContextFromDefaults,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -42,8 +43,10 @@ async function main() {
|
||||
const index = await VectorStoreIndex.fromDocuments(docs, {
|
||||
storageContext: ctx,
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const preFilters: MetadataFilters = {
|
||||
filters: [{ key: "id", operator: "in", value: [123, 789] }],
|
||||
}; // try changing the filters to see the different results
|
||||
const queryEngine = index.asQueryEngine({ preFilters });
|
||||
const response = await queryEngine.query({
|
||||
query: "Describe AstraDB.",
|
||||
});
|
||||
|
||||
@@ -2,10 +2,10 @@ import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
import {
|
||||
ChatSummaryMemoryBuffer,
|
||||
OpenAI,
|
||||
Settings,
|
||||
SimpleChatEngine,
|
||||
SummaryChatHistory,
|
||||
} from "llamaindex";
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
@@ -18,7 +18,7 @@ async function main() {
|
||||
// Set maxTokens to 75% of the context window size of 4096
|
||||
// This will trigger the summarizer once the chat history reaches 25% of the context window size (1024 tokens)
|
||||
const llm = new OpenAI({ model: "gpt-3.5-turbo", maxTokens: 4096 * 0.75 });
|
||||
const chatHistory = new SummaryChatHistory({ llm });
|
||||
const chatHistory = new ChatSummaryMemoryBuffer({ llm });
|
||||
const chatEngine = new SimpleChatEngine({ llm });
|
||||
const rl = readline.createInterface({ input, output });
|
||||
|
||||
|
||||
@@ -1,57 +1,83 @@
|
||||
import {
|
||||
ChromaVectorStore,
|
||||
Document,
|
||||
MetadataFilters,
|
||||
VectorStoreIndex,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const collectionName = "dog_colors";
|
||||
const collectionName = "dogs_with_color";
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const docs = [
|
||||
new Document({
|
||||
text: "The dog is brown",
|
||||
metadata: {
|
||||
dogId: "1",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
text: "The dog is red",
|
||||
metadata: {
|
||||
dogId: "2",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
console.log("Creating ChromaDB vector store");
|
||||
const chromaVS = new ChromaVectorStore({ collectionName });
|
||||
const ctx = await storageContextFromDefaults({ vectorStore: chromaVS });
|
||||
const index = await VectorStoreIndex.fromVectorStore(chromaVS);
|
||||
|
||||
console.log("Embedding documents and adding to index");
|
||||
const index = await VectorStoreIndex.fromDocuments(docs, {
|
||||
storageContext: ctx,
|
||||
});
|
||||
const queryFn = async (filters?: MetadataFilters) => {
|
||||
console.log("\nQuerying dogs by filters: ", JSON.stringify(filters));
|
||||
const query = "List all colors of dogs";
|
||||
const queryEngine = index.asQueryEngine({
|
||||
preFilters: filters,
|
||||
similarityTopK: 3,
|
||||
});
|
||||
const response = await queryEngine.query({ query });
|
||||
console.log(response.toString());
|
||||
};
|
||||
|
||||
console.log("Querying index");
|
||||
const queryEngine = index.asQueryEngine({
|
||||
preFilters: {
|
||||
filters: [
|
||||
{
|
||||
key: "dogId",
|
||||
value: "2",
|
||||
operator: "==",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const response = await queryEngine.query({
|
||||
query: "What is the color of the dog?",
|
||||
});
|
||||
console.log(response.toString());
|
||||
await queryFn(); // red, brown, yellow
|
||||
await queryFn({ filters: [{ key: "dogId", value: "1", operator: "==" }] }); // brown
|
||||
await queryFn({ filters: [{ key: "dogId", value: "1", operator: "!=" }] }); // red, yellow
|
||||
await queryFn({
|
||||
filters: [
|
||||
{ key: "dogId", value: "1", operator: "==" },
|
||||
{ key: "dogId", value: "3", operator: "==" },
|
||||
],
|
||||
condition: "or",
|
||||
}); // brown, yellow
|
||||
await queryFn({
|
||||
filters: [{ key: "dogId", value: ["1", "2"], operator: "in" }],
|
||||
}); // red, brown
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
void main();
|
||||
async function generate() {
|
||||
const docs = [
|
||||
new Document({
|
||||
id_: "doc1",
|
||||
text: "The dog is brown",
|
||||
metadata: {
|
||||
dogId: "1",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
id_: "doc2",
|
||||
text: "The dog is red",
|
||||
metadata: {
|
||||
dogId: "2",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
id_: "doc3",
|
||||
text: "The dog is yellow",
|
||||
metadata: {
|
||||
dogId: "3",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
console.log("Creating ChromaDB vector store");
|
||||
const chromaVS = new ChromaVectorStore({ collectionName });
|
||||
const ctx = await storageContextFromDefaults({ vectorStore: chromaVS });
|
||||
|
||||
console.log("Embedding documents and adding to index");
|
||||
await VectorStoreIndex.fromDocuments(docs, {
|
||||
storageContext: ctx,
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await generate();
|
||||
await main();
|
||||
})();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DeepInfraEmbedding } from "llamaindex";
|
||||
async function main() {
|
||||
// API token can be provided as an environment variable too
|
||||
// using DEEPINFRA_API_TOKEN variable
|
||||
const apiToken = "YOUR_API_TOKEN" ?? process.env.DEEPINFRA_API_TOKEN;
|
||||
const apiToken = process.env.DEEPINFRA_API_TOKEN ?? "YOUR_API_TOKEN";
|
||||
const model = "BAAI/bge-large-en-v1.5";
|
||||
const embedModel = new DeepInfraEmbedding({
|
||||
model,
|
||||
|
||||
@@ -2,13 +2,13 @@ import {
|
||||
Document,
|
||||
KeywordExtractor,
|
||||
OpenAI,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
} from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
|
||||
|
||||
const nodeParser = new SimpleNodeParser();
|
||||
const nodeParser = new SentenceSplitter();
|
||||
|
||||
const nodes = nodeParser.getNodesFromDocuments([
|
||||
new Document({ text: "banana apple orange pear peach watermelon" }),
|
||||
|
||||
@@ -2,13 +2,13 @@ import {
|
||||
Document,
|
||||
OpenAI,
|
||||
QuestionsAnsweredExtractor,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
} from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
|
||||
|
||||
const nodeParser = new SimpleNodeParser();
|
||||
const nodeParser = new SentenceSplitter();
|
||||
|
||||
const nodes = nodeParser.getNodesFromDocuments([
|
||||
new Document({
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import {
|
||||
Document,
|
||||
OpenAI,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
SummaryExtractor,
|
||||
} from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
|
||||
|
||||
const nodeParser = new SimpleNodeParser();
|
||||
const nodeParser = new SentenceSplitter();
|
||||
|
||||
const nodes = nodeParser.getNodesFromDocuments([
|
||||
new Document({
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Document, OpenAI, SimpleNodeParser, TitleExtractor } from "llamaindex";
|
||||
import { Document, OpenAI, SentenceSplitter, TitleExtractor } from "llamaindex";
|
||||
|
||||
import essay from "../essay";
|
||||
|
||||
(async () => {
|
||||
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo-0125", temperature: 0 });
|
||||
|
||||
const nodeParser = new SimpleNodeParser({});
|
||||
const nodeParser = new SentenceSplitter({});
|
||||
|
||||
const nodes = nodeParser.getNodesFromDocuments([
|
||||
new Document({
|
||||
|
||||
+12
-1
@@ -1,12 +1,23 @@
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
import { Document, Groq, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import {
|
||||
Document,
|
||||
Groq,
|
||||
HuggingFaceEmbedding,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
|
||||
// Update llm to use Groq
|
||||
Settings.llm = new Groq({
|
||||
apiKey: process.env.GROQ_API_KEY,
|
||||
});
|
||||
|
||||
// Use HuggingFace for embeddings
|
||||
Settings.embedModel = new HuggingFaceEmbedding({
|
||||
modelType: "Xenova/all-mpnet-base-v2",
|
||||
});
|
||||
|
||||
async function main() {
|
||||
// Load essay from abramov.txt in Node
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import {\n",
|
||||
" Document,\n",
|
||||
" SimpleNodeParser\n",
|
||||
"} from \"npm:llamaindex\";"
|
||||
"import { Document, SentenceSplitter } from \"npm:llamaindex\";"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -45,7 +42,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"const nodeParser = new SimpleNodeParser();\n",
|
||||
"const nodeParser = new SentenceSplitter();\n",
|
||||
"const nodes = nodeParser.getNodesFromDocuments([\n",
|
||||
" new Document({ text: \"I am 10 years old. John is 20 years old.\" }),\n",
|
||||
"]);\n",
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import {
|
||||
Document,
|
||||
getResponseSynthesizer,
|
||||
NodeWithScore,
|
||||
ResponseSynthesizer,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
TextNode,
|
||||
} from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const nodeParser = new SimpleNodeParser();
|
||||
const nodeParser = new SentenceSplitter();
|
||||
const nodes = nodeParser.getNodesFromDocuments([
|
||||
new Document({ text: "I am 10 years old. John is 20 years old." }),
|
||||
]);
|
||||
|
||||
console.log(nodes);
|
||||
|
||||
const responseSynthesizer = new ResponseSynthesizer();
|
||||
const responseSynthesizer = getResponseSynthesizer("compact");
|
||||
|
||||
const nodesWithScore: NodeWithScore[] = [
|
||||
{
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
const stream = await responseSynthesizer.synthesize(
|
||||
{
|
||||
query: "What age am I?",
|
||||
nodesWithScore,
|
||||
nodes: nodesWithScore,
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import {
|
||||
Document,
|
||||
MetadataFilters,
|
||||
Settings,
|
||||
SimpleDocumentStore,
|
||||
VectorStoreIndex,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
async function getDataSource() {
|
||||
const docs = [
|
||||
new Document({ text: "The dog is brown", metadata: { dogId: "1" } }),
|
||||
new Document({ text: "The dog is yellow", metadata: { dogId: "2" } }),
|
||||
];
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
persistDir: "./cache",
|
||||
});
|
||||
const numberOfDocs = Object.keys(
|
||||
(storageContext.docStore as SimpleDocumentStore).toDict(),
|
||||
).length;
|
||||
if (numberOfDocs === 0) {
|
||||
return await VectorStoreIndex.fromDocuments(docs, { storageContext });
|
||||
}
|
||||
return await VectorStoreIndex.init({
|
||||
storageContext,
|
||||
});
|
||||
}
|
||||
|
||||
Settings.callbackManager.on("retrieve-end", (event) => {
|
||||
const { nodes, query } = event.detail;
|
||||
console.log(`${query.query} - Number of retrieved nodes:`, nodes.length);
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const index = await getDataSource();
|
||||
const filters: MetadataFilters = {
|
||||
filters: [{ key: "dogId", value: "2", operator: "==" }],
|
||||
};
|
||||
|
||||
const retriever = index.asRetriever({ similarityTopK: 3, filters });
|
||||
const queryEngine = index.asQueryEngine({
|
||||
similarityTopK: 3,
|
||||
preFilters: filters,
|
||||
});
|
||||
|
||||
console.log("Retriever and query engine should only retrieve 1 node:");
|
||||
await retriever.retrieve({ query: "Retriever: get dog" });
|
||||
await queryEngine.query({ query: "QueryEngine: get dog" });
|
||||
}
|
||||
|
||||
void main();
|
||||
@@ -28,12 +28,23 @@ async function loadAndIndex() {
|
||||
"full_text",
|
||||
]);
|
||||
|
||||
const FILTER_METADATA_FIELD = "content_type";
|
||||
|
||||
documents.forEach((document, index) => {
|
||||
const contentType = ["tweet", "post", "story"][index % 3]; // assign a random content type to each document
|
||||
document.metadata = {
|
||||
...document.metadata,
|
||||
[FILTER_METADATA_FIELD]: contentType,
|
||||
};
|
||||
});
|
||||
|
||||
// create Atlas as a vector store
|
||||
const vectorStore = new MongoDBAtlasVectorSearch({
|
||||
mongodbClient: client,
|
||||
dbName: databaseName,
|
||||
collectionName: vectorCollectionName, // this is where your embeddings will be stored
|
||||
indexName: indexName, // this is the name of the index you will need to create
|
||||
indexedMetadataFields: [FILTER_METADATA_FIELD], // this is the field that will be used for the query
|
||||
});
|
||||
|
||||
// now create an index from all the Documents and store them in Atlas
|
||||
@@ -45,39 +56,4 @@ async function loadAndIndex() {
|
||||
await client.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is document in https://www.mongodb.com/docs/atlas/atlas-search/create-index/#create-an-fts-index-programmatically
|
||||
* But, while testing a 'CommandNotFound' error occurred, so we're not using this here.
|
||||
*/
|
||||
async function createSearchIndex() {
|
||||
const client = new MongoClient(mongoUri);
|
||||
const database = client.db(databaseName);
|
||||
const collection = database.collection(vectorCollectionName);
|
||||
|
||||
// define your Atlas Search index
|
||||
const index = {
|
||||
name: indexName,
|
||||
definition: {
|
||||
/* search index definition fields */
|
||||
mappings: {
|
||||
dynamic: true,
|
||||
fields: [
|
||||
{
|
||||
type: "vector",
|
||||
path: "embedding",
|
||||
numDimensions: 1536,
|
||||
similarity: "cosine",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
// run the helper method
|
||||
const result = await collection.createSearchIndex(index);
|
||||
console.log("Successfully created search index:", result);
|
||||
await client.close();
|
||||
}
|
||||
|
||||
loadAndIndex().catch(console.error);
|
||||
|
||||
// you can't query your index yet because you need to create a vector search index in mongodb's UI now
|
||||
|
||||
@@ -14,14 +14,26 @@ async function query() {
|
||||
dbName: process.env.MONGODB_DATABASE!,
|
||||
collectionName: process.env.MONGODB_VECTORS!,
|
||||
indexName: process.env.MONGODB_VECTOR_INDEX!,
|
||||
indexedMetadataFields: ["content_type"],
|
||||
});
|
||||
|
||||
const index = await VectorStoreIndex.fromVectorStore(store);
|
||||
|
||||
const retriever = index.asRetriever({ similarityTopK: 20 });
|
||||
const queryEngine = index.asQueryEngine({ retriever });
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
preFilters: {
|
||||
filters: [
|
||||
{
|
||||
key: "content_type",
|
||||
value: "story", // try "tweet" or "post" to see the difference
|
||||
operator: "==",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const result = await queryEngine.query({
|
||||
query: "What does the author think of web frameworks?",
|
||||
query: "What does author receive when he was 11 years old?", // Isaac Asimov's "Foundation" for Christmas
|
||||
});
|
||||
console.log(result.response);
|
||||
await client.close();
|
||||
|
||||
@@ -68,45 +68,6 @@ What you're doing here is creating a Reader which loads the data out of Mongo in
|
||||
|
||||
Now you're creating a vector search client for Mongo. In addition to a MongoDB client object, you again tell it what database everything is in. This time you give it the name of the collection where you'll store the vector embeddings, and the name of the vector search index you'll create in the next step.
|
||||
|
||||
### Create a vector search index
|
||||
|
||||
Now if all has gone well you should be able to log in to the Mongo Atlas UI and see two collections in your database: the original data in `tiny_tweets_collection`, and the vector embeddings in `tiny_tweets_vectors`.
|
||||
|
||||

|
||||
|
||||
Now it's time to create the vector search index so that you can query the data.
|
||||
It's not yet possible to programmatically create a vector search index using the [`createIndex`](https://www.mongodb.com/docs/manual/reference/method/db.collection.createIndex/) function, therefore we have to create one manually in the UI.
|
||||
To do so, first, click the 'Atlas Search' tab, and then click "Create Search Index":
|
||||
|
||||

|
||||
|
||||
We have to use the JSON editor, as the Visual Editor does not yet support to create a vector search index:
|
||||
|
||||

|
||||
|
||||
Now under "database and collection" select `tiny_tweets_db` and within that select `tiny_tweets_vectors`. Then under "Index name" enter `tiny_tweets_vector_index` (or whatever value you put for MONGODB_VECTOR_INDEX in `.env`). Under that, you'll want to enter this JSON object:
|
||||
|
||||
```json
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": "vector",
|
||||
"path": "embedding",
|
||||
"numDimensions": 1536,
|
||||
"similarity": "cosine"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This tells Mongo that the `embedding` field in each document (in the `tiny_tweets_vectors` collection) is a vector of 1536 dimensions (this is the size of embeddings used by OpenAI), and that we want to use cosine similarity to compare vectors. You don't need to worry too much about these values unless you want to use a different LLM to OpenAI entirely.
|
||||
|
||||
The UI will ask you to review and confirm your choices, then you need to wait a minute or two while it generates the index. If all goes well, you should see something like this screen:
|
||||
|
||||

|
||||
|
||||
Now you're ready to query your data!
|
||||
|
||||
### Run a test query
|
||||
|
||||
You can do this by running
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// call pnpm tsx multimodal/load.ts first to init the storage
|
||||
import { OpenAI, Settings, SimpleChatEngine, imageToDataUrl } from "llamaindex";
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
import path from "path";
|
||||
// Update llm
|
||||
Settings.llm = new OpenAI({ model: "gpt-4o-mini", maxTokens: 512 });
|
||||
|
||||
async function main() {
|
||||
const chatEngine = new SimpleChatEngine();
|
||||
|
||||
// Load the image and convert it to a data URL
|
||||
const imagePath = path.join(__dirname, ".", "data", "60.jpg");
|
||||
|
||||
// 1. you can read the buffer from the file
|
||||
const imageBuffer = await fs.readFile(imagePath);
|
||||
const dataUrl = await imageToDataUrl(imageBuffer);
|
||||
// or 2. you can just pass the file path to the imageToDataUrl function
|
||||
// const dataUrl = await imageToDataUrl(imagePath);
|
||||
|
||||
// Update the image_url in the chat message
|
||||
const response = await chatEngine.chat({
|
||||
message: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What is in this image?",
|
||||
},
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: dataUrl,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
console.log(response.message.content);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,4 +1,5 @@
|
||||
// call pnpm tsx multimodal/load.ts first to init the storage
|
||||
import { extractText } from "@llamaindex/core/utils";
|
||||
import {
|
||||
ContextChatEngine,
|
||||
NodeWithScore,
|
||||
@@ -25,8 +26,9 @@ Settings.callbackManager.on("retrieve-end", (event) => {
|
||||
const textNodes = nodes.filter(
|
||||
(node: NodeWithScore) => node.node.type === ObjectType.TEXT,
|
||||
);
|
||||
const text = extractText(query);
|
||||
console.log(
|
||||
`Retrieved ${textNodes.length} text nodes and ${imageNodes.length} image nodes for query: ${query}`,
|
||||
`Retrieved ${textNodes.length} text nodes and ${imageNodes.length} image nodes for query: ${text}`,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { extractText } from "@llamaindex/core/utils";
|
||||
import {
|
||||
MultiModalResponseSynthesizer,
|
||||
getResponseSynthesizer,
|
||||
OpenAI,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
@@ -16,7 +17,8 @@ Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
|
||||
// Update callbackManager
|
||||
Settings.callbackManager.on("retrieve-end", (event) => {
|
||||
const { nodes, query } = event.detail;
|
||||
console.log(`Retrieved ${nodes.length} nodes for query: ${query}`);
|
||||
const text = extractText(query);
|
||||
console.log(`Retrieved ${nodes.length} nodes for query: ${text}`);
|
||||
});
|
||||
|
||||
async function main() {
|
||||
@@ -27,7 +29,7 @@ async function main() {
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine({
|
||||
responseSynthesizer: new MultiModalResponseSynthesizer(),
|
||||
responseSynthesizer: getResponseSynthesizer("multi_modal"),
|
||||
retriever: index.asRetriever({ topK: { TEXT: 3, IMAGE: 1 } }),
|
||||
});
|
||||
const stream = await queryEngine.query({
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const llm = new OpenAI({ model: "o1-preview", temperature: 1 });
|
||||
|
||||
const prompt = `What are three compounds we should consider investigating to advance research
|
||||
into new antibiotics? Why should we consider them?
|
||||
`;
|
||||
|
||||
// complete api
|
||||
const response = await llm.complete({ prompt });
|
||||
console.log(response.text);
|
||||
})();
|
||||
+14
-12
@@ -1,27 +1,29 @@
|
||||
{
|
||||
"name": "@llamaindex/examples",
|
||||
"private": true,
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.9",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"@azure/identity": "^4.2.1",
|
||||
"@datastax/astra-db-ts": "^1.2.1",
|
||||
"@llamaindex/core": "^0.1.0",
|
||||
"@azure/identity": "^4.4.1",
|
||||
"@datastax/astra-db-ts": "^1.4.1",
|
||||
"@llamaindex/core": "^0.3.0",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^2.2.2",
|
||||
"@zilliz/milvus2-sdk-node": "^2.4.4",
|
||||
"@pinecone-database/pinecone": "^3.0.2",
|
||||
"@vercel/postgres": "^0.10.0",
|
||||
"@zilliz/milvus2-sdk-node": "^2.4.6",
|
||||
"chromadb": "^1.8.1",
|
||||
"commander": "^12.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"js-tiktoken": "^1.0.12",
|
||||
"llamaindex": "^0.5.0",
|
||||
"js-tiktoken": "^1.0.14",
|
||||
"llamaindex": "^0.7.0",
|
||||
"mongodb": "^6.7.0",
|
||||
"pathe": "^1.1.2"
|
||||
"pathe": "^1.1.2",
|
||||
"postgres": "^3.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.1",
|
||||
"tsx": "^4.15.6",
|
||||
"typescript": "^5.5.3"
|
||||
"@types/node": "^22.5.1",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint ."
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
IngestionPipeline,
|
||||
MetadataMode,
|
||||
OpenAIEmbedding,
|
||||
SimpleNodeParser,
|
||||
SentenceSplitter,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
@@ -18,7 +18,7 @@ async function main() {
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new OpenAIEmbedding(),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import {
|
||||
Document,
|
||||
ResponseSynthesizer,
|
||||
TreeSummarize,
|
||||
getResponseSynthesizer,
|
||||
PromptTemplate,
|
||||
TreeSummarizePrompt,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
|
||||
const treeSummarizePrompt: TreeSummarizePrompt = ({ context, query }) => {
|
||||
return `Context information from multiple sources is below.
|
||||
const treeSummarizePrompt: TreeSummarizePrompt = new PromptTemplate({
|
||||
template: `Context information from multiple sources is below.
|
||||
---------------------
|
||||
${context}
|
||||
{context}
|
||||
---------------------
|
||||
Given the information from multiple sources and not prior knowledge.
|
||||
Answer the query in the style of a Shakespeare play"
|
||||
Query: ${query}
|
||||
Answer:`;
|
||||
};
|
||||
Query: {query}
|
||||
Answer:`,
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const documents = new Document({
|
||||
@@ -26,9 +26,7 @@ async function main() {
|
||||
|
||||
const query = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new TreeSummarize(),
|
||||
});
|
||||
const responseSynthesizer = getResponseSynthesizer("tree_summarize");
|
||||
|
||||
const queryEngine = index.asQueryEngine({
|
||||
responseSynthesizer,
|
||||
|
||||
@@ -39,6 +39,12 @@ async function main() {
|
||||
dogId: "2",
|
||||
},
|
||||
}),
|
||||
new Document({
|
||||
text: "The dog is black",
|
||||
metadata: {
|
||||
dogId: "3",
|
||||
},
|
||||
}),
|
||||
];
|
||||
console.log("Creating QdrantDB vector store");
|
||||
const qdrantVs = new QdrantVectorStore({ url: qdrantUrl, collectionName });
|
||||
@@ -73,6 +79,42 @@ async function main() {
|
||||
query: "What is the color of the dog?",
|
||||
});
|
||||
console.log("Filter with dogId 2 response:", response.toString());
|
||||
|
||||
console.log("Querying index with dogId !=2: Expected output: Not red");
|
||||
const queryEngineNotDogId2 = index.asQueryEngine({
|
||||
preFilters: {
|
||||
filters: [
|
||||
{
|
||||
key: "dogId",
|
||||
value: "2",
|
||||
operator: "!=",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const responseNotDogId2 = await queryEngineNotDogId2.query({
|
||||
query: "What is the color of the dog?",
|
||||
});
|
||||
console.log(responseNotDogId2.toString());
|
||||
|
||||
console.log(
|
||||
"Querying index with dogId 2 or 3: Expected output: Red, Black",
|
||||
);
|
||||
const queryEngineIn = index.asQueryEngine({
|
||||
preFilters: {
|
||||
filters: [
|
||||
{
|
||||
key: "dogId",
|
||||
value: ["2", "3"],
|
||||
operator: "in",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const responseIn = await queryEngineIn.query({
|
||||
query: "List all dogs",
|
||||
});
|
||||
console.log(responseIn.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
"start:assemblyai": "node --import tsx ./src/assemblyai.ts",
|
||||
"start:llamaparse-dir": "node --import tsx ./src/simple-directory-reader-with-llamaparse.ts",
|
||||
"start:llamaparse-json": "node --import tsx ./src/llamaparse-json.ts",
|
||||
"start:discord": "node --import tsx ./src/discord.ts"
|
||||
"start:discord": "node --import tsx ./src/discord.ts",
|
||||
"start:json": "node --import tsx ./src/json.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"llamaindex": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.11",
|
||||
"tsx": "^4.15.6",
|
||||
"typescript": "^5.5.3"
|
||||
"@types/node": "^22.5.1",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
+11
-10
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
CompactAndRefine,
|
||||
getResponseSynthesizer,
|
||||
OpenAI,
|
||||
ResponseSynthesizer,
|
||||
PromptTemplate,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -18,17 +18,18 @@ async function main() {
|
||||
// Split text and create embeddings. Store them in a VectorStoreIndex
|
||||
const index = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
const csvPrompt = ({ context = "", query = "" }) => {
|
||||
return `The following CSV file is loaded from ${path}
|
||||
const csvPrompt = new PromptTemplate({
|
||||
templateVars: ["query", "context"],
|
||||
template: `The following CSV file is loaded from ${path}
|
||||
\`\`\`csv
|
||||
${context}
|
||||
{context}
|
||||
\`\`\`
|
||||
Given the CSV file, generate me Typescript code to answer the question: ${query}. You can use built in NodeJS functions but avoid using third party libraries.
|
||||
`;
|
||||
};
|
||||
Given the CSV file, generate me Typescript code to answer the question: {query}. You can use built in NodeJS functions but avoid using third party libraries.
|
||||
`,
|
||||
});
|
||||
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new CompactAndRefine(undefined, csvPrompt),
|
||||
const responseSynthesizer = getResponseSynthesizer("compact", {
|
||||
textQATemplate: csvPrompt,
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine({ responseSynthesizer });
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { createMessageContent } from "@llamaindex/core/response-synthesizers";
|
||||
import {
|
||||
Document,
|
||||
ImageNode,
|
||||
LlamaParseReader,
|
||||
OpenAI,
|
||||
PromptTemplate,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import { createMessageContent } from "llamaindex/synthesizers/utils";
|
||||
|
||||
const reader = new LlamaParseReader();
|
||||
async function main() {
|
||||
@@ -50,7 +51,9 @@ async function getImageTextDocs(
|
||||
|
||||
for (const imageDict of imageDicts) {
|
||||
const imageDoc = new ImageNode({ image: imageDict.path });
|
||||
const prompt = () => `Describe the image as alt text`;
|
||||
const prompt = new PromptTemplate({
|
||||
template: `Describe the image as alt text`,
|
||||
});
|
||||
const message = await createMessageContent(prompt, [imageDoc]);
|
||||
|
||||
const response = await llm.complete({
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
OpenAI,
|
||||
RouterQueryEngine,
|
||||
SentenceSplitter,
|
||||
Settings,
|
||||
SimpleDirectoryReader,
|
||||
SimpleNodeParser,
|
||||
SummaryIndex,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Settings.llm = new OpenAI();
|
||||
|
||||
// Update node parser
|
||||
Settings.nodeParser = new SimpleNodeParser({
|
||||
Settings.nodeParser = new SentenceSplitter({
|
||||
chunkSize: 1024,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
Document,
|
||||
SentenceSplitter,
|
||||
Settings,
|
||||
SimpleNodeParser,
|
||||
SummaryIndex,
|
||||
SummaryRetrieverMode,
|
||||
} from "llamaindex";
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
import essay from "./essay";
|
||||
|
||||
// Update node parser
|
||||
Settings.nodeParser = new SimpleNodeParser({
|
||||
Settings.nodeParser = new SentenceSplitter({
|
||||
chunkSize: 40,
|
||||
});
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"lib": ["ES2022"],
|
||||
"types": ["node"],
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
"incremental": true,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# neon template
|
||||
PGHOST=
|
||||
PGDATABASE=
|
||||
PGUSER=
|
||||
PGPASSWORD=
|
||||
ENDPOINT_ID=
|
||||
|
||||
# vercel template
|
||||
POSTGRES_URL=
|
||||
@@ -1,11 +1,11 @@
|
||||
// load-docs.ts
|
||||
import fs from "fs/promises";
|
||||
import {
|
||||
PGVectorStore,
|
||||
SimpleDirectoryReader,
|
||||
storageContextFromDefaults,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
async function getSourceFilenames(sourceDir: string) {
|
||||
return await fs
|
||||
@@ -40,7 +40,11 @@ async function main(args: any) {
|
||||
const rdr = new SimpleDirectoryReader(callback);
|
||||
const docs = await rdr.loadData({ directoryPath: sourceDir });
|
||||
|
||||
const pgvs = new PGVectorStore();
|
||||
const pgvs = new PGVectorStore({
|
||||
clientConfig: {
|
||||
connectionString: process.env.PG_CONNECTION_STRING,
|
||||
},
|
||||
});
|
||||
pgvs.setCollection(sourceDir);
|
||||
await pgvs.clearCollection();
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* eslint-disable turbo/no-undeclared-env-vars */
|
||||
import dotenv from "dotenv";
|
||||
import { Document, PGVectorStore, VectorStoreQueryMode } from "llamaindex";
|
||||
import postgres from "postgres";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const { PGHOST, PGDATABASE, PGUSER, ENDPOINT_ID } = process.env;
|
||||
const PGPASSWORD = decodeURIComponent(process.env.PGPASSWORD!);
|
||||
|
||||
const sql = postgres({
|
||||
host: PGHOST,
|
||||
database: PGDATABASE,
|
||||
username: PGUSER,
|
||||
password: PGPASSWORD,
|
||||
port: 5432,
|
||||
ssl: "require",
|
||||
connection: {
|
||||
options: `project=${ENDPOINT_ID}`,
|
||||
},
|
||||
});
|
||||
|
||||
await sql`CREATE EXTENSION IF NOT EXISTS vector`;
|
||||
|
||||
const vectorStore = new PGVectorStore({
|
||||
dimensions: 3,
|
||||
client: sql,
|
||||
});
|
||||
|
||||
await vectorStore.add([
|
||||
new Document({
|
||||
text: "hello, world",
|
||||
embedding: [1, 2, 3],
|
||||
}),
|
||||
]);
|
||||
|
||||
const results = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
|
||||
console.log("result", results);
|
||||
|
||||
await sql.end();
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "pg-vector-store",
|
||||
"type": "module",
|
||||
"private": true
|
||||
}
|
||||
@@ -7,7 +7,11 @@ async function main() {
|
||||
});
|
||||
|
||||
try {
|
||||
const pgvs = new PGVectorStore();
|
||||
const pgvs = new PGVectorStore({
|
||||
clientConfig: {
|
||||
connectionString: process.env.PG_CONNECTION_STRING,
|
||||
},
|
||||
});
|
||||
// Optional - set your collection name, default is no filter on this field.
|
||||
// pgvs.setCollection();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"types": ["node"],
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// https://vercel.com/docs/storage/vercel-postgres/sdk
|
||||
import { sql } from "@vercel/postgres";
|
||||
import dotenv from "dotenv";
|
||||
import { Document, PGVectorStore, VectorStoreQueryMode } from "llamaindex";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
await sql`CREATE EXTENSION IF NOT EXISTS vector`;
|
||||
|
||||
const vectorStore = new PGVectorStore({
|
||||
dimensions: 3,
|
||||
client: sql,
|
||||
});
|
||||
|
||||
await vectorStore.add([
|
||||
new Document({
|
||||
text: "hello, world",
|
||||
embedding: [1, 2, 3],
|
||||
}),
|
||||
]);
|
||||
|
||||
const results = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
|
||||
console.log("result", results);
|
||||
|
||||
await sql.end();
|
||||
@@ -2,12 +2,10 @@ import fs from "node:fs/promises";
|
||||
|
||||
import {
|
||||
Anthropic,
|
||||
CompactAndRefine,
|
||||
Document,
|
||||
ResponseSynthesizer,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
anthropicTextQaPrompt,
|
||||
getResponseSynthesizer,
|
||||
} from "llamaindex";
|
||||
|
||||
// Update llm to use Anthropic
|
||||
@@ -23,9 +21,7 @@ async function main() {
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
|
||||
// Split text and create embeddings. Store them in a VectorStoreIndex
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new CompactAndRefine(undefined, anthropicTextQaPrompt),
|
||||
});
|
||||
const responseSynthesizer = getResponseSynthesizer("compact");
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
|
||||
@@ -25,12 +25,9 @@ async function main() {
|
||||
similarityCutoff: 0.7,
|
||||
});
|
||||
// TODO: cannot pass responseSynthesizer into retriever query engine
|
||||
const queryEngine = new RetrieverQueryEngine(
|
||||
retriever,
|
||||
undefined,
|
||||
undefined,
|
||||
[nodePostprocessor],
|
||||
);
|
||||
const queryEngine = new RetrieverQueryEngine(retriever, undefined, [
|
||||
nodePostprocessor,
|
||||
]);
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query: "What did the author do growing up?",
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import {
|
||||
BaseVectorStore,
|
||||
getResponseSynthesizer,
|
||||
OpenAI,
|
||||
OpenAIEmbedding,
|
||||
ResponseSynthesizer,
|
||||
RetrieverQueryEngine,
|
||||
Settings,
|
||||
TextNode,
|
||||
TreeSummarize,
|
||||
VectorIndexRetriever,
|
||||
VectorStore,
|
||||
VectorStoreIndex,
|
||||
VectorStoreQuery,
|
||||
VectorStoreQueryResult,
|
||||
@@ -25,7 +24,7 @@ Settings.llm = new OpenAI({
|
||||
* Please do not use this class in production; it's only for demonstration purposes.
|
||||
*/
|
||||
class PineconeVectorStore<T extends RecordMetadata = RecordMetadata>
|
||||
implements VectorStore
|
||||
implements BaseVectorStore
|
||||
{
|
||||
storesText = true;
|
||||
isEmbeddingQuery = false;
|
||||
@@ -165,13 +164,8 @@ async function main() {
|
||||
similarityTopK: 500,
|
||||
});
|
||||
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new TreeSummarize(),
|
||||
});
|
||||
|
||||
return new RetrieverQueryEngine(retriever, responseSynthesizer, {
|
||||
filter,
|
||||
});
|
||||
const responseSynthesizer = getResponseSynthesizer("tree_summarize");
|
||||
return new RetrieverQueryEngine(retriever, responseSynthesizer);
|
||||
};
|
||||
|
||||
// whatever is a key from your metadata
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Weaviate Vector Store
|
||||
|
||||
Here are two sample scripts which work with loading and querying data from a Weaviate Vector Store.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- An Weaviate Vector Database
|
||||
- Hosted https://weaviate.io/
|
||||
- Self Hosted https://weaviate.io/developers/weaviate/installation/docker-compose#starter-docker-compose-file
|
||||
- An OpenAI API Key
|
||||
|
||||
## Setup
|
||||
|
||||
1. Set your env variables:
|
||||
|
||||
- `WEAVIATE_CLUSTER_URL`: Address of your Weaviate Vector Store (like localhost:8080)
|
||||
- `WEAVIATE_API_KEY`: Your Weaviate API key
|
||||
- `OPENAI_API_KEY`: Your OpenAI key
|
||||
|
||||
2. `cd` Into the `examples` directory
|
||||
3. run `npm i`
|
||||
|
||||
## Load the data
|
||||
|
||||
This sample loads the same dataset of movie reviews as sample dataset
|
||||
|
||||
run `npx tsx weaviate/load`
|
||||
|
||||
## Use RAG to Query the data
|
||||
|
||||
run `npx tsx weaviate/query`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user