Compare commits

...

50 Commits

Author SHA1 Message Date
github-actions[bot] 7384e4d273 Release @llamaindex/anthropic@0.3.9 (#1972)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-23 13:04:47 +07:00
Peter Goldstein ae75966721 Update Gemini model keys to reflect Google changes (#1968) 2025-05-23 11:22:55 +07:00
Peter Goldstein 5cdab12791 Add Claude Sonnet 4 and Claude Opus 4 models (#1969) 2025-05-23 11:10:50 +07:00
github-actions[bot] eaf2cb11a5 Release 0.11.3 (#1966)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-22 16:58:59 +07:00
Marcus Schiesser 3ae01a227e chore: remove repin (#1967) 2025-05-22 16:53:44 +07:00
Marcus Schiesser 76ff23dc48 fix: pRetry not working with CommonJS 2025-05-22 15:14:00 +07:00
github-actions[bot] ed497727b1 Release 0.11.2 (#1964)
Co-authored-by: marcusschiesser <17126+marcusschiesser@users.noreply.github.com>
2025-05-22 14:34:37 +07:00
Marcus Schiesser 59601dd3ab feat: Add support for builtin image generation tool 2025-05-22 13:12:23 +07:00
github-actions[bot] 8474ca970e Release 0.11.1 (#1961)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-20 22:18:57 -07:00
Alex Yang 3703f907d9 fix(parse): upload API (#1960) 2025-05-20 17:39:39 -07:00
github-actions[bot] f63b702bec Release 0.11.0 (#1950)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: marcusschiesser <17126+marcusschiesser@users.noreply.github.com>
2025-05-19 12:23:04 +07:00
Marcus Schiesser ccde88fe0b docs: update azure docs (#1958) 2025-05-19 11:49:18 +07:00
ANKIT VARSHNEY b0cd5301bb remove openai from llamaindex package and remove default setting for llm and embedModel (#1809)
Co-authored-by: Marcus Schiesser <marcus.schiesser@googlemail.com>
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-05-19 11:12:57 +07:00
Marcus Schiesser 3e66ddc10d chore: Move Azure models to azure package (#1888) 2025-05-16 15:50:12 +07:00
Marcus Schiesser c719b968f3 Fix: broken links in docs (#1956)
Co-authored-by: Andrew Kostka <apkostka@gmail.com>
2025-05-15 16:49:05 +07:00
Anubhav Rana c73c659c6d chore: qdrant version updates (#1913)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-05-15 12:30:24 +07:00
Marcus Schiesser 361a685012 chore: remove old workflows (#1951) 2025-05-15 10:29:47 +07:00
Marcus Schiesser 680b529e94 chore: remove requireContext from tools (#1949) 2025-05-14 16:38:44 +07:00
github-actions[bot] 389acbd307 Release 0.10.6 (#1942)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: marcusschiesser <17126+marcusschiesser@users.noreply.github.com>
2025-05-13 17:16:55 +07:00
Marcus Schiesser 2e181be160 feat: add xai tools (#1948) 2025-05-13 17:10:57 +07:00
Marcus Schiesser 7a7ca604c5 feat: add xai support (#1947) 2025-05-13 16:48:53 +07:00
Marcus Schiesser c2fd4f9fc1 docs: add docs for concept (#1946) 2025-05-13 16:02:21 +07:00
GiftMungmeeprued 40f5f410c0 fix: enhance loadJson in LlamaParseReader to handle URL inputs correctly (#1936) 2025-05-13 10:10:04 +07:00
Anubhav Rana d671ed6d25 feat: qdrant search params (#1911) 2025-05-13 09:50:23 +07:00
Marcus Schiesser 76c9a80057 chore: make core peer dep (#1941) 2025-05-12 18:08:55 +07:00
operagxsasha 46a416517c docs: added a badge to the social network Twitter (#1943) 2025-05-12 18:05:08 +07:00
Tomer Igal 168d11fe51 feat: update agent input interface to support files (#1938)
Co-authored-by: Marcus Schiesser <marcus.schiesser@googlemail.com>
2025-05-12 17:21:46 +07:00
operagxsasha 3dfa5eb9ff docs: edited the link to the license badge (#1939) 2025-05-12 17:10:17 +07:00
Marcus Schiesser 9b20859dc5 docs: reorder examples (#1937) 2025-05-12 14:16:47 +07:00
Thuc Pham 93691793c5 feat: add E2E test for installing packages with npm (#1930) 2025-05-12 11:02:44 +07:00
Marcus Schiesser 3b231cf11c readd old sentence splitter for testing (#1926) 2025-05-10 09:01:22 +07:00
Marcus Schiesser 7073fca171 docs: LlamaParseReader how to use EU (#1931) 2025-05-09 16:45:20 +07:00
Marcus Schiesser 9145577bf5 docs: move live examples (#1928) 2025-05-09 15:02:33 +07:00
github-actions[bot] 4a18a2eb3d Release 0.10.5 (#1922)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: marcusschiesser <17126+marcusschiesser@users.noreply.github.com>
2025-05-09 14:30:39 +07:00
ANKIT VARSHNEY 206b491724 feat: Support for google live api (#1905) 2025-05-09 14:20:40 +07:00
Marcus Schiesser 9b2e25a184 fix: Use Uint8Array instead of Buffer for file type messages (works w… (#1921) 2025-05-08 13:19:59 +07:00
github-actions[bot] b29521bf6c Release @llamaindex/google@0.2.6 (#1918)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-07 16:31:58 +07:00
Marcus Schiesser 73e25787e7 feat: add gemini-2.5-pro-preview-05-06 (#1917) 2025-05-07 16:18:21 +07:00
Marcus Schiesser 3ce80540fe docs: add workflows documentation and update installation instruction… (#1916) 2025-05-07 15:22:08 +07:00
Marcus Schiesser dbc1ee3089 docs: update installation instructions for LlamaIndex to include Work… (#1915) 2025-05-07 12:31:48 +07:00
github-actions[bot] 3b45191228 Release 0.10.4 (#1901)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-07 11:11:11 +07:00
Marcus Schiesser aaf2f8b2db docs: fix docs for agents (#1914) 2025-05-07 11:03:08 +07:00
Marcus Schiesser 6ddf1c1b1f chore: fixes for workflows before release (#1908) 2025-05-07 09:29:09 +07:00
Marcus Schiesser a8717d5ece chore: ensure pinning workflow version (#1907) 2025-05-06 12:51:13 +07:00
Huu Le 7e8e4549f2 chore: update @llama-flow/core to version 0.4.1 and export stream api (#1906)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-05-05 16:06:44 +07:00
Alex Yang cc3fe92a22 docs: update llama-flow 2025-05-04 02:28:04 -07:00
Alex Yang 63ab0dba4e chore: drop node.js 18 support (#1904) 2025-05-02 11:51:18 -07:00
Alex Yang 2225ffd1d4 feat: bump llama cloud sdk (#1903) 2025-05-01 13:30:52 -07:00
Marcus Schiesser bc5334249b chore: migrate agentworkflows to llama-flow (#1895)
Co-authored-by: leehuwuj <leehuwuj@gmail.com>
2025-04-30 18:14:17 +07:00
Thuc Pham 41953a3ef9 fix: node10 module resolution fail in sub llamaindex packages (#1900) 2025-04-29 17:47:50 +07:00
494 changed files with 15070 additions and 9310 deletions
+26 -2
View File
@@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [18.x, 20.x, 22.x, 23.x]
node-version: [20.x, 22.x, 23.x]
name: E2E on Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
steps:
@@ -53,7 +53,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [18.x, 20.x, 22.x, 23.x]
node-version: [20.x, 22.x, 23.x]
name: Test on Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
steps:
@@ -87,6 +87,30 @@ jobs:
run: pnpm run type-check
- name: Run Circular Dependency Check
run: pnpm run circular-check
e2e-npm:
runs-on: ubuntu-latest
name: Test using packages with npm
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm run build
- name: Pack packages
run: |
pnpm pack --pack-destination ${{ runner.temp }} -C packages/llamaindex
pnpm pack --pack-destination ${{ runner.temp }} -C packages/workflow
- name: Install packed packages
run: npm add ${{ runner.temp }}/*.tgz
working-directory: e2e/npm
- name: Run tests
run: npm test
working-directory: e2e/npm
e2e-llamaindex-examples:
strategy:
fail-fast: false
+1 -1
View File
@@ -1 +1 @@
20
22
+4 -15
View File
@@ -7,9 +7,10 @@
</h3>
[![NPM Version](https://img.shields.io/npm/v/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM License](https://img.shields.io/npm/l/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM License](https://img.shields.io/npm/l/llamaindex)](https://github.com/run-llama/LlamaIndexTS/blob/main/LICENSE)
[![NPM Downloads](https://img.shields.io/npm/dm/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![Discord](https://img.shields.io/discord/1059199217496772688)](https://discord.com/invite/eN6D2HQ4aX)
[![Twitter](https://img.shields.io/twitter/follow/llama_index)](https://x.com/llama_index)
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in JS runtime environments with TypeScript support.
@@ -63,7 +64,7 @@ yarn add llamaindex
### Setup in Node.js, Deno, Bun, TypeScript...?
See our official document: <https://ts.llamaindex.ai/docs/llamaindex/getting_started/>
See our official document: https://ts.llamaindex.ai/docs/llamaindex/getting_started
### Adding provider packages
@@ -83,19 +84,7 @@ Check out our NextJS playground at https://llama-playground.vercel.app/. The sou
## 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.
See our documentation: https://ts.llamaindex.ai/docs/llamaindex/getting_started/concepts
## Contributing:
+88
View File
@@ -1,5 +1,93 @@
# @llamaindex/doc
## 0.2.22
### Patch Changes
- Updated dependencies [76ff23d]
- @llamaindex/cloud@4.0.11
- llamaindex@0.11.3
## 0.2.21
### Patch Changes
- Updated dependencies [59601dd]
- @llamaindex/openai@0.4.1
- @llamaindex/core@0.6.7
- @llamaindex/cloud@4.0.10
- llamaindex@0.11.2
- @llamaindex/node-parser@2.0.7
- @llamaindex/readers@3.1.5
- @llamaindex/workflow@1.1.4
## 0.2.20
### Patch Changes
- Updated dependencies [3703f90]
- @llamaindex/cloud@4.0.9
- llamaindex@0.11.1
## 0.2.19
### Patch Changes
- Updated dependencies [680b529]
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- Updated dependencies [3e66ddc]
- @llamaindex/workflow@1.1.3
- @llamaindex/core@0.6.6
- llamaindex@0.11.0
- @llamaindex/openai@0.4.0
- @llamaindex/cloud@4.0.8
- @llamaindex/node-parser@2.0.6
- @llamaindex/readers@3.1.4
## 0.2.18
### Patch Changes
- d671ed6: Add functionality for search params when querying Qdrant vector store.
- Updated dependencies [76c9a80]
- Updated dependencies [168d11f]
- Updated dependencies [d671ed6]
- Updated dependencies [40f5f41]
- @llamaindex/openai@0.3.7
- @llamaindex/workflow@1.1.2
- @llamaindex/core@0.6.5
- @llamaindex/cloud@4.0.7
- llamaindex@0.10.6
- @llamaindex/node-parser@2.0.5
- @llamaindex/readers@3.1.3
## 0.2.17
### Patch Changes
- Updated dependencies [9b2e25a]
- @llamaindex/openai@0.3.6
- @llamaindex/core@0.6.4
- llamaindex@0.10.5
- @llamaindex/cloud@4.0.6
- @llamaindex/node-parser@2.0.4
- @llamaindex/readers@3.1.2
- @llamaindex/workflow@1.1.1
## 0.2.16
### Patch Changes
- Updated dependencies [7e8e454]
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [bc53342]
- Updated dependencies [41953a3]
- @llamaindex/workflow@1.1.0
- @llamaindex/cloud@4.0.5
- llamaindex@0.10.4
## 0.2.15
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/doc",
"version": "0.2.15",
"version": "0.2.22",
"private": true,
"scripts": {
"postinstall": "fumadocs-mdx",
@@ -15,7 +15,7 @@
"dependencies": {
"@huggingface/transformers": "^3.5.0",
"@icons-pack/react-simple-icons": "^10.1.0",
"@llama-flow/docs": "0.0.5",
"@llama-flow/docs": "0.0.8",
"@llamaindex/chat-ui": "0.2.0",
"@llamaindex/cloud": "workspace:*",
"@llamaindex/core": "workspace:*",
+10 -7
View File
@@ -4,7 +4,6 @@ import matter from "gray-matter";
import path from "path";
const CONTENT_DIR = path.join(process.cwd(), "src/content/docs");
const BUILD_DIR = path.join(process.cwd(), ".next");
// Regular expression to find internal links
// This captures Markdown links [text](/docs/path) and href attributes href="/docs/path"
@@ -14,6 +13,8 @@ const INTERNAL_LINK_REGEX = /(?:(?:\]\(|\bhref=["'])\/docs\/([^")]+))/g;
// This captures relative links like [text](./path) or ![alt](../images/image.png)
const RELATIVE_LINK_REGEX = /(?:\]\()(?:\s*)(?:\.\.?)\//g;
const ALLOWED_LINKS = ["/docs/llamaflow"];
interface LinkValidationResult {
file: string;
invalidLinks: Array<{ link: string; line: number }>;
@@ -28,7 +29,7 @@ interface RelativeLinkResult {
* Get all valid documentation routes from the content directory
*/
async function getValidRoutes(): Promise<Set<string>> {
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
const mdxFiles = await glob("**/*.{md,mdx}", { cwd: CONTENT_DIR });
const routes = new Set<string>();
@@ -124,14 +125,11 @@ function findRelativeLinksInFile(
return relativeLinks;
}
/**
* Validate internal links in all MDX files
*/
/**
* Find relative links in all MDX files
*/
async function findRelativeLinks(): Promise<RelativeLinkResult[]> {
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
const mdxFiles = await glob("**/*.mdx", { cwd: CONTENT_DIR });
const results: RelativeLinkResult[] = [];
for (const file of mdxFiles) {
@@ -150,7 +148,7 @@ async function findRelativeLinks(): Promise<RelativeLinkResult[]> {
}
async function validateLinks(): Promise<LinkValidationResult[]> {
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
const mdxFiles = await glob("**/*.mdx", { cwd: CONTENT_DIR });
const validRoutes = await getValidRoutes();
const results: LinkValidationResult[] = [];
@@ -160,6 +158,11 @@ async function validateLinks(): Promise<LinkValidationResult[]> {
const links = extractLinksFromFile(filePath);
const invalidLinks = links.filter(({ link }) => {
// Check if the link is in the allowed list
if (ALLOWED_LINKS.includes(`/docs/${link}`)) {
return false;
}
// Check if the link exists in valid routes
// First normalize the link (remove any query string or hash)
const baseLink = link.split("?")[0].split("#")[0];
+4 -3
View File
@@ -26,7 +26,7 @@ const llm = openai();
const response = await llm.chat({
messages: [{ content: "Tell me a joke.", role: "user" }],
});`,
`import { agent } from "llamaindex";
`import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
const analyseAgent = agent({
@@ -36,7 +36,7 @@ const analyseAgent = agent({
});
const response = await analyseAgent.run(\`Analyse the given data:
\${data}\`);`,
`import { agent, multiAgent } from "llamaindex";
`import { agent, multiAgent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
const analyseAgent = agent({
@@ -113,8 +113,9 @@ export default function HomePage() {
description="Truly powerful retrieval-augmented generation applications use agentic techniques, and LlamaIndex.TS makes it easy to build them."
>
<CodeBlock
code={`import { agent, SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
code={`import { SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { agent } from "@llamaindex/workflow";
// load documents from current directoy into an index
const reader = new SimpleDirectoryReader();
@@ -0,0 +1,60 @@
---
title: High-Level Concepts
---
This is a quick guide to the high-level concepts you'll encounter frequently when building LLM applications.
## Large Language Models (LLMs)
LLMs are the fundamental innovation that launched LlamaIndex. They are an artificial intelligence (AI) computer system that can understand, generate, and manipulate natural language, including answering questions based on their training data or data provided to them at query time.
## Agentic Applications
When an LLM is used within an application, it is often used to make decisions, take actions, and/or interact with the world. This is the core definition of an **agentic application**.
While the definition of an agentic application is broad, there are several key characteristics that define an agentic application:
- **LLM Augmentation**: The LLM is augmented with tools (i.e. arbitrary callable functions in code), memory, and/or dynamic prompts.
- **Prompt Chaining**: Several LLM calls are used that build on each other, with the output of one LLM call being used as the input to the next.
- **Routing**: The LLM is used to route the application to the next appropriate step or state in the application.
- **Parallelism**: The application can perform multiple steps or actions in parallel.
- **Orchestration**: A hierarchical structure of LLMs is used to orchestrate lower-level actions and LLMs.
- **Reflection**: The LLM is used to reflect and validate outputs of previous steps or LLM calls, which can be used to guide the application to the next appropriate step or state.
In LlamaIndex, you can build agentic applications by using the workflows to orchestrate a sequence of steps and LLMs. You can [learn more about workflows](/docs/llamaindex/tutorials/workflows).
## Agents
We define an agent as a specific instance of an "agentic application". An agent is a piece of software that semi-autonomously performs tasks by combining LLMs with other tools and memory, orchestrated in a reasoning loop that decides which tool to use next (if any).
What this means in practice, is something like:
- An agent receives a user message
- The agent uses an LLM to determine the next appropriate action to take using the previous chat history, tools, and the latest user message
- The agent may invoke one or more tools to assist in the users request
- If tools are used, the agent will then interpret the tool outputs and use them to inform the next action
- Once the agent stops taking actions, it returns the final output to the user
You can [learn more about agents](/docs/llamaindex/tutorials/basic_agent).
## Retrieval Augmented Generation (RAG)
Retrieval-Augmented Generation (RAG) is a core technique for building data-backed LLM applications with LlamaIndex. It allows LLMs to answer questions about your private data by providing it to the LLM at query time, rather than training the LLM on your data. To avoid sending **all** of your data to the LLM every time, RAG indexes your data and selectively sends only the relevant parts along with your query. You can [learn more about RAG](/docs/llamaindex/tutorials/rag).
## Use cases
There are endless use cases for data-backed LLM applications but they can be roughly grouped into four categories:
[**Agents**](/docs/llamaindex/tutorials/basic_agent):
An agent is an automated decision-maker powered by an LLM that interacts with the world via a set of [tools](/docs/llamaindex/modules/agents/tool). Agents can take an arbitrary number of steps to complete a given task, dynamically deciding on the best course of action rather than following pre-determined steps. This gives it additional flexibility to tackle more complex tasks.
[**Workflows**](/docs/llamaindex/tutorials/workflows):
A Workflow in LlamaIndex is a specific event-driven abstraction that allows you to orchestrate a sequence of steps and LLMs calls. Workflows can be used to implement any agentic application, and are a core component of LlamaIndex.
[**Structured Data Extraction**](/docs/llamaindex/tutorials/structured_data_extraction):
Pydantic extractors allow you to specify a precise data structure to extract from your data and use LLMs to fill in the missing pieces in a type-safe way. This is useful for extracting structured data from unstructured sources like PDFs, websites, and more, and is key to automating workflows.
[**Query Engines**](/docs/llamaindex/modules/rag/query_engines):
A query engine is an end-to-end flow that allows you to ask questions over your data. It takes in a natural language query, and returns a response, along with reference context retrieved and passed to the LLM.
[**Chat Engines**](/docs/llamaindex/modules/rag/chat_engine):
A chat engine is an end-to-end flow for having a conversation with your data (multiple back-and-forth instead of a single question-and-answer).
@@ -9,10 +9,10 @@ To install llamaindex, run the following command:
npm i llamaindex
```
In most cases, you'll also need an LLM package to use LlamaIndex. For example, to use the OpenAI LLM, you would install the following:
In most cases, you'll also need an LLM package and the Workflow package to use LlamaIndex. For example, to use the OpenAI LLM with agents, you would install the following:
```package-install
npm i @llamaindex/openai
npm i @llamaindex/openai @llamaindex/workflow
```
Go to [LLM APIs](/docs/llamaindex/modules/models/llms) to find out how to use other LLMs.
@@ -40,19 +40,7 @@ Make sure to set [moduleResolution](https://www.typescriptlang.org/docs/handbook
}
```
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it, but with import path limitations.
So you may encounter type errors when importing sub paths from the `llamaindex` package like:
```ts
import { Settings } from "llamaindex";
```
The simplest way to fix this without changing `moduleResolution` is to import directly from `llamaindex`:
```ts
import { Settings } from "llamaindex";
```
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it.
## Enable AsyncIterable for `Web Stream` API
@@ -68,7 +56,8 @@ Some modules uses `Web Stream` API like `ReadableStream` and `WritableStream`, y
```
```typescript
import { agent, tool } from 'llamaindex'
import { tool } from 'llamaindex'
import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
Settings.llm = openai({
@@ -1,4 +1,4 @@
{
"title": "Getting Started",
"pages": ["installation", "create_llama", "examples"]
"pages": ["concepts", "installation", "create_llama", "examples"]
}
@@ -12,7 +12,8 @@ Agent Workflows are a powerful system that enables you to create and orchestrate
The simplest use case is creating a single agent with specific tools. Here's an example of creating an assistant that tells jokes:
```typescript
import { agent, tool } from "llamaindex";
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
// Define a joke-telling tool
@@ -40,17 +41,17 @@ console.log(result); // Baby Llama is called cria
Agent Workflows provide a unified interface for event streaming, making it easy to track and respond to different events during execution:
```typescript
import { AgentToolCall, AgentStream } from "llamaindex";
import { agentToolCallEvent, agentStreamEvent } from "@llamaindex/workflow";
// Get the workflow execution context
const context = workflow.run("Tell me something funny");
const events = workflow.runStream("Tell me something funny");
// Stream and handle events
for await (const event of context) {
if (event instanceof AgentToolCall) {
for await (const event of events) {
if (agentToolCallEvent.include(event)) {
console.log(`Tool being called: ${event.data.toolName}`);
}
if (event instanceof AgentStream) {
if (agentStreamEvent.include(event)) {
process.stdout.write(event.data.delta);
}
}
@@ -68,7 +69,8 @@ An Agent Workflow can orchestrate multiple agents, enabling complex interactions
Here's an example of a multi-agent system that combines joke-telling and weather information:
```typescript
import { multiAgent, agent, tool } from "llamaindex";
import { tool } from "llamaindex";
import { multiAgent, agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
@@ -17,7 +17,8 @@ The `parameters` field in the tool configuration is defined using `zod`, a TypeS
Example:
```ts
import { agent, tool } from "llamaindex";
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { z } from "zod";
// first arg is LLM input, second is bound arg
@@ -46,7 +47,7 @@ In this example, `z.object` is used to define a schema for the `parameters` wher
You can import built-in tools from the `@llamaindex/tools` package.
```ts
import { agent } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { wiki } from "@llamaindex/tools";
const researchAgent = agent({
@@ -64,7 +65,7 @@ If you have a MCP server running, you can fetch tools from the server and use th
```ts
// 1. Import MCP tools adapter
import { mcp } from "@llamaindex/tools";
import { agent } from "llamaindex";
import { agent } from "@llamaindex/workflow";
// 2. Initialize a MCP client
// by npx
@@ -114,7 +115,8 @@ Note: calling the `bind` method will return a new `FunctionTool` instance, witho
Example to pass a `userToken` as additional argument:
```ts
import { agent, tool } from "llamaindex";
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
// first arg is LLM input, second is bound arg
const queryKnowledgeBase = async ({ question }, { userToken }) => {
@@ -6,256 +6,13 @@ A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to ch
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
To use workflows install this package:
```package-install
npm i @llama-flow/core @llamaindex/openai
npm i @llamaindex/workflow
```
## Getting Started
This package is a stable, production-ready version of our [llama-flow](/docs/llamaflow) project.
Let's explore a simple workflow example where a joke is generated and then critiqued and iterated on:
While you can still reference the llama-flow documentation for detailed information about the underlying concepts, we recommend using the `@llamaindex/workflow` package for all new projects to ensure stability and long-term availability.
```typescript
import { OpenAI } from "@llamaindex/openai";
import { createWorkflow, workflowEvent } from "@llama-flow/core";
import { withStore } from "@llama-flow/core/middleware/store";
// Create LLM instance
const llm = new OpenAI({ model: "gpt-4.1-mini", apiKey: "..."});
// Define our workflow events
const startEvent = workflowEvent<string>(); // Input topic for joke
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
const critiqueEvent = workflowEvent<{ joke: string, critique: string }>(); // Intermediate critique
const resultEvent = workflowEvent<{ joke: string, critique: string }>(); // Final joke + critique
// Create our workflow
const jokeFlow = withStore(
() => ({
numIterations: 0,
maxIterations: 3,
}),
createWorkflow()
);
// Define handlers for each step
jokeFlow.handle([startEvent], async (event) => {
// Prompt the LLM to write a joke
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
return jokeEvent.with({ joke: joke });
});
jokeFlow.handle([jokeEvent], async (event) => {
// Prompt the LLM to critique the joke
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
const response = await llm.complete({ prompt });
// If the critique includes "IMPROVE", keep iterating, else, return the result
if (response.text.includes("IMPROVE")) {
return critiqueEvent.with({ joke: event.data.joke, critique: response.text });
}
return resultEvent.with({ joke: event.data.joke, critique: response.text });
});
jokeFlow.handle([critiqueEvent], async (event) => {
// Keep track of the number of iterations
const store = jokeFlow.getStore();
store.numIterations++;
// Write a new joke based on the previous joke and critique
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
// If we've done less than the max number of iterations, keep iterating
// else, return the result
if (store.numIterations < store.maxIterations) {
return jokeEvent.with({ joke: joke });
}
return resultEvent.with({ joke: joke, critique: event.data.critique });
});
// Usage
async function main() {
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
let result: { joke: string, critique: string } | undefined;
for await (const event of stream) {
// console.log(event.data); optionally log the event data
if (resultEvent.include(event)) {
result = event.data;
break; // Stop when we get the final result
}
}
console.log(result);
}
main().catch(console.error);
```
There are a few moving pieces here, so let's go through this step by step.
### Defining Workflow Events
```typescript
const startEvent = workflowEvent<string>(); // Input topic for joke
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
const critiqueEvent = workflowEvent<{ joke: string, critique: string }>(); // Intermediate critique
const resultEvent = workflowEvent<{ joke: string, critique: string }>(); // Final joke + critique
```
Events are defined using the `workflowEvent` function and contain arbitrary data provided as a generic type. In this example, we have four events:
- `startEvent`: Takes a string input (the joke topic)
- `jokeEvent`: Contains an object with a joke property
- `critiqueEvent`: Contains both the joke and its critique, used for the feedback loop
- `resultEvent`: Contains the final joke and critique after any iterations
### Setting up the Workflow with Store Middleware
```typescript
const jokeFlow = withStore(
() => ({
numIterations: 0,
maxIterations: 3,
}),
createWorkflow()
);
```
Our workflow is implemented using the `createWorkflow()` function, enhanced with the `withStore` middleware. The store provides shared state across all handlers, which in this case tracks:
- `numIterations`: Counts how many iterations of joke improvement we've done
- `maxIterations`: Sets a limit to prevent infinite loops
This store will be accesible within workflows by using the `jokeFlow.getStore()` function.
### Adding Handlers with Loops
We have three key handlers in our workflow:
1. The first handler processes the `startEvent`, generates an initial joke, and emits a `jokeEvent`:
```typescript
jokeFlow.handle([startEvent], async (event) => {
// Prompt the LLM to write a joke
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
return jokeEvent.with({ joke: joke });
});
```
2. The second handler handles the `jokeEvent`, critiques the joke, and either:
- Emits a `critiqueEvent` if the joke needs improvement
- Emits a `resultEvent` if the joke is good enough
```typescript
jokeFlow.handle([jokeEvent], async (event) => {
// Prompt the LLM to critique the joke
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
const response = await llm.complete({ prompt });
// If the critique includes "IMPROVE", keep iterating, else, return the result
if (response.text.includes("IMPROVE")) {
return critiqueEvent.with({ joke: event.data.joke, critique: response.text });
}
return resultEvent.with({ joke: event.data.joke, critique: response.text });
});
```
3. The third handler processes the `critiqueEvent`, generates an improved joke based on the critique, and either:
- Loops back to the joke evaluation (if under the iteration limit)
- Emits the final `resultEvent` (if iteration limit reached)
```typescript
jokeFlow.handle([critiqueEvent], async (event) => {
// Keep track of the number of iterations
const store = jokeFlow.getStore();
store.numIterations++;
// Write a new joke based on the previous joke and critique
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
// If we've done less than the max number of iterations, keep iterating
// else, return the result
if (store.numIterations < store.maxIterations) {
return jokeEvent.with({ joke: joke });
}
return resultEvent.with({ joke: joke, critique: event.data.critique });
});
```
### Running the Workflow
```typescript
async function main() {
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
let result: { joke: string, critique: string } | undefined;
for await (const event of stream) {
// console.log(event.data); optionally log the event data
if (resultEvent.include(event)) {
result = event.data;
break; // Stop when we get the final result
}
}
console.log(result);
}
```
To run the workflow, we:
1. Create a workflow context with `createContext()`
2. Trigger the initial event with `sendEvent()`
3. Listen to the event stream and process events as they arrive
4. Use `include()` to check if an event is of a specific type
5. Break the loop when we receive our final result
### Using Stream Utilities
Workflows provide utility functions to make working with event streams easier:
```typescript
import { collect } from "@llama-flow/core/stream/consumer";
import { until } from "@llama-flow/core/stream/until";
// Create a workflow context and send the initial event
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
// Collect all events until we get a resultEvent
const allEvents = await collect(until(stream, resultEvent));
// The last event will be the resultEvent
const finalEvent = allEvents[allEvents.length - 1];
console.log(finalEvent.data); // Output the joke and critique
```
The stream utilities make it easier to work with the asynchronous event flow. In this example, we use:
- `collect`: Aggregates all events into an array
- `until`: Creates a stream that emits events until a condition is met (in this case, until a resultEvent is received)
You can combine these utilities with other stream operators like `filter` and `map` to create powerful processing pipelines.
## Next Steps
To learn more about workflows, check out [the documentation in the tutorial section](../../../llamaflow).
@@ -18,7 +18,7 @@ In your Discord Application, go to the `OAuth2` tab and generate an invite URL b
This will invite the bot with the necessary permissions to read messages.
Copy the URL in your browser and select the server you want your bot to join.
<include cwd>../../examples/discord/reader.ts</include>
<include cwd>../../examples/readers/discord/reader.ts</include>
### Params
@@ -88,7 +88,7 @@ async function main() {
const response = await queryEngine.query({
query: "What did the author do in college?",
});
}); // Additional filters and params can be passed as options
// Output response
console.log(response.toString());
@@ -2,89 +2,43 @@
title: Azure OpenAI
---
To use Azure OpenAI, you only need to set a few environment variables together with the `OpenAI` class.
For example:
## Environment Variables
```
export AZURE_OPENAI_KEY="<YOUR KEY HERE>"
export AZURE_OPENAI_ENDPOINT="<YOUR ENDPOINT, see https://learn.microsoft.com/en-us/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython&pivots=rest-api>"
export AZURE_OPENAI_DEPLOYMENT="gpt-4" # or some other deployment name
```
To use Azure OpenAI, you only need to install the `@llamaindex/azure` package:
## Installation
```package-install
npm i llamaindex @llamaindex/openai
npm i llamaindex @llamaindex/azure
```
## Usage
The class `AzureOpenAI` is used for setting the LLM and `AzureOpenAIEmbedding` is used for setting the embedding model, e.g.:
```ts
import { Settings } from "llamaindex";
import { OpenAI } from "@llamaindex/openai";
import { AzureOpenAI, AzureOpenAIEmbedding } from "@llamaindex/azure";
Settings.llm = new OpenAI({ model: "gpt-4", temperature: 0 });
```
## Load and index documents
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index.
```ts
const document = new Document({ text: essay, id_: "essay" });
const index = await VectorStoreIndex.fromDocuments([document]);
```
## Query
```ts
const queryEngine = index.asQueryEngine();
const query = "What is the meaning of life?";
const results = await queryEngine.query({
query,
Settings.llm = new AzureOpenAI({
apiKey: '[key]',
deployment: '[model]',
apiVersion: '[version]',
endpoint: `https://[deployment].openai.azure.com/`,
});
Settings.embedModel = new AzureOpenAIEmbedding({
apiKey: '[key]',
deployment: '[embedding-model]',
apiVersion: '[version]',
endpoint: `https://[deployment].openai.azure.com/`,
});
```
## Full Example
Instead of explicitly setting the API key, deployment, version, and endpoint in the constructor, you can use the following environment variables: `AZURE_OPENAI_DEPLOYMENT` for the model deployment name, `AZURE_OPENAI_KEY` for your API key, `AZURE_OPENAI_ENDPOINT` for your Azure endpoint URL, and `AZURE_OPENAI_API_VERSION` for the API version.
```ts
import { Document, VectorStoreIndex, Settings } from "llamaindex";
import { OpenAI } from "@llamaindex/openai";
## Examples
Settings.llm = new OpenAI({ model: "gpt-4", temperature: 0 });
async function main() {
const document = new Document({ text: essay, id_: "essay" });
// Load and index documents
const index = await VectorStoreIndex.fromDocuments([document]);
// get retriever
const retriever = index.asRetriever();
// Create a query engine
const queryEngine = index.asQueryEngine({
retriever,
});
const query = "What is the meaning of life?";
// Query
const response = await queryEngine.query({
query,
});
// Log the response
console.log(response.response);
}
```
See the [Azure examples](https://github.com/run-llama/LlamaIndexTS/tree/main/examples/storage/azure) for more examples of how to use Azure OpenAI.
## API Reference
- [OpenAI](/docs/api/classes/OpenAI)
- [AzureOpenAI](/docs/api/classes/AzureOpenAI)
- [AzureOpenAIEmbedding](/docs/api/classes/AzureOpenAIEmbedding)
@@ -120,11 +120,11 @@ async function main() {
```ts
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
import { FunctionTool, LLMAgent } from "llamaindex";
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { z } from "zod";
const sumNumbers = FunctionTool.from(
({ a, b }: { a: number; b: number }) => `${a + b}`,
const sumNumbers = tool(
{
name: "sumNumbers",
description: "Use this function to sum two numbers",
@@ -136,11 +136,11 @@ const sumNumbers = FunctionTool.from(
description: "The second number",
}),
}),
execute: ({ a, b }: { a: number; b: number }) => `${a + b}`,
},
);
const divideNumbers = FunctionTool.from(
({ a, b }: { a: number; b: number }) => `${a / b}`,
const divideNumbers = tool(
{
name: "divideNumbers",
description: "Use this function to divide two numbers",
@@ -152,6 +152,7 @@ const divideNumbers = FunctionTool.from(
description: "The divisor b to divide by",
}),
}),
execute: ({ a, b }: { a: number; b: number }) => `${a / b}`,
},
);
@@ -161,15 +162,15 @@ const bedrock = new Bedrock({
});
async function main() {
const agent = new LLMAgent({
const myAgent = agent({
llm: bedrock,
tools: [sumNumbers, divideNumbers],
});
const response = await agent.chat({
message: "How much is 5 + 5? then divide by 2",
});
const response = await myAgent.run(
"How much is 5 + 5? then divide by 2",
);
console.log(response.message);
console.log(response);
}
```
@@ -55,7 +55,7 @@ const results = await queryEngine.query({
## Full Example
<include cwd>../../examples/groq.ts</include>
<include cwd>../../examples/models/groq.ts</include>
## API Reference
@@ -166,4 +166,4 @@ Want to start a new project with LlamaIndexServer? Check out our [create-llama](
## API Reference
- [LlamaIndexServer](/docs/api/classes/LlamaIndexServer)
- [LlamaIndexServer](https://github.com/run-llama/create-llama/blob/main/packages/server)
@@ -15,7 +15,7 @@ In LlamaIndex, an agent is a semi-autonomous piece of software powered by an LLM
You'll need to have a recent version of [Node.js](https://nodejs.org/en) installed. Then you can install LlamaIndex.TS by running
```package-install
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface @llamaindex/workflow
```
## Choose your model
@@ -35,11 +35,16 @@ First we'll need to pull in our dependencies. These are:
import "dotenv/config";
import {
agent,
AgentStream,
tool,
agentStreamEvent,
openai,
} from "@llamaindex/workflow";
import {
tool,
Settings,
} from "llamaindex";
import {
openai,
} from "@llamaindex/openai";
import { z } from "zod";
```
@@ -108,11 +113,10 @@ const myAgent = agent({ tools });
### Ask the agent a question
We can use the `chat` interface to ask our agent a question, and it will use the tools we've defined to find an answer.
We can use the `run` method to ask our agent a question, and it will use the tools we've defined to find an answer.
```javascript
const context = myAgent.run("Sum 101 and 303");
const result = await context;
const result = await myAgent.run("Sum 101 and 303");
console.log(result.data);
```
You will see the following output:
@@ -123,12 +127,13 @@ You will see the following output:
{ result: 'The sum of 101 and 303 is 404.' }
```
To stream the response, you can use the `AgentStream` event which provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
To stream the response, you need to call `runStream`, which returns a stream of events.
The `agentStreamEvent` provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
```javascript
const context = myAgent.run("Add 101 and 303");
for await (const event of context) {
if (event instanceof AgentStream) {
const events = myAgent.runStream("Add 101 and 303");
for await (const event of events) {
if (agentStreamEvent.include(event)) {
process.stdout.write(event.data.delta);
}
}
@@ -140,18 +145,18 @@ for await (const event of context) {
The sum of 101 and 303 is 404.
```
Note that we're filtering for `agentStreamEvent` as an agent might return other events - more about that in the following section.
### Logging workflow events
To log the workflow events, you can check the event type and log the event data.
```javascript
const context = myAgent.run("Sum 202 and 404");
for await (const event of context) {
if (event instanceof AgentStream) {
const events = myAgent.runStream("Sum 202 and 404");
for await (const event of events) {
if (agentStreamEvent.include(event)) {
// Stream the response
for (const chunk of event.data.delta) {
process.stdout.write(chunk);
}
process.stdout.write(event.data.delta);
} else {
// Log other events
console.log("\nWorkflow event:", JSON.stringify(event, null, 2));
@@ -30,16 +30,16 @@ Settings.llm = ollama({
### Run local agent
You can also create local agent by importing `agent` from `llamaindex`.
You can also create local agent by importing `agent` from `@llamaindex/workflow`.
```javascript
import { agent } from "llamaindex";
import { agent } from "@llamaindex/workflow";
const workflow = agent({
tools: [getWeatherTool],
});
const workflowContext = workflow.run(
const resutl = workflow.run(
"What's the weather like in San Francisco?",
);
```
@@ -25,7 +25,8 @@ We'll be bringing in `SimpleDirectoryReader`, `HuggingFaceEmbedding`, `VectorSto
```javascript
import { QueryEngineTool, Settings, VectorStoreIndex } from "llamaindex";
import { OpenAI, OpenAIAgent } from "@llamaindex/openai";
import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
```
@@ -8,9 +8,10 @@ We have a comprehensive, step-by-step [guide to building agents in LlamaIndex.TS
In a new folder:
```bash npm2yarn
```package-install
npm init
npm i -D typescript @types/node
npm i @llamaindex/openai @llamaindex/workflow llamaindex zod
```
## Run agent
@@ -20,15 +21,14 @@ Create the file `example.ts`. This code will:
- Create two tools for use by the agent:
- A `sumNumbers` tool that adds two numbers
- A `divideNumbers` tool that divides numbers
-
- Give an example of the data structure we wish to generate
- Prompt the LLM with instructions and the example, plus a sample transcript
<include cwd>../../examples/agent/openai.ts</include>
<include cwd>../../examples/agents/agent/openai.ts</include>
To run the code:
```bash
```package-install
npx tsx example.ts
```
@@ -36,9 +36,18 @@ You should expect output something like:
```
{
content: 'The sum of 5 + 5 is 10. When you divide 10 by 2, you get 5.',
role: 'assistant',
options: {}
result: '5 + 5 is 10. Then, 10 divided by 2 is 5.',
state: {
memory: ChatMemoryBuffer {
chatStore: SimpleChatStore {},
chatStoreKey: 'chat_history',
tokenLimit: 750000
},
scratchpad: [],
currentAgentName: 'Agent',
agents: [ 'Agent' ],
nextAgentName: null
}
}
Done
```
@@ -4,7 +4,7 @@
"basic_agent",
"rag",
"agents",
"../../llamaflow",
"workflows",
"local_llm",
"chatbot",
"structured_data_extraction"
@@ -16,7 +16,7 @@ LlamaIndex uses a two stage method when using an LLM with your data:
1. **indexing stage**: preparing a knowledge base, and
2. **querying stage**: retrieving relevant context from the knowledge to assist the LLM in responding to a question
![](./_static/concepts/rag.jpg)
![](/_static/concepts/rag.jpg)
This process is also known as Retrieval Augmented Generation (RAG).
@@ -28,7 +28,7 @@ Let's explore each stage in detail.
LlamaIndex.TS help you prepare the knowledge base with a suite of data connectors and indexes.
![](./_static/concepts/indexing.jpg)
![](/_static/concepts/indexing.jpg)
[**Data Loaders**](/docs/llamaindex/modules/data/readers):
A data connector (i.e. `Reader`) ingest data from different data sources and data formats into a simple `Document` representation (text and simple metadata).
@@ -54,7 +54,7 @@ LlamaIndex provides composable modules that help you build and integrate RAG pip
These building blocks can be customized to reflect ranking preferences, as well as composed to reason over multiple knowledge bases in a structured way.
![](./_static/concepts/querying.jpg)
![](/_static/concepts/querying.jpg)
#### Building Blocks
@@ -8,9 +8,10 @@ One of the most common use-cases for LlamaIndex is Retrieval-Augmented Generatio
In a new folder, run:
```bash npm2yarn
```package-install
npm init
npm i -D typescript @types/node
npm i llamaindex
```
Then, check out the [installation](/docs/llamaindex/getting_started/installation) steps to install LlamaIndex.TS and prepare an OpenAI key.
@@ -26,7 +27,7 @@ Create the file `example.ts`. This code will
- index it (which creates embeddings using OpenAI)
- create a query engine to answer questions about the data
<include cwd>../../examples/vectorIndex.ts</include>
<include cwd>../../examples/index/vectorIndex.ts</include>
Create a `tsconfig.json` file in the same folder:
@@ -34,7 +35,7 @@ Create a `tsconfig.json` file in the same folder:
Now you can run the code with
```bash
```package-install
npx tsx example.ts
```
@@ -10,9 +10,10 @@ You can use [other LLMs](/docs/llamaindex/modules/models/llms) via their APIs; i
In a new folder:
```bash npm2yarn
```package-install
npm init
npm i -D typescript @types/node
npm i @llamaindex/openai zod
```
## Extract data
@@ -23,11 +24,11 @@ Create the file `example.ts`. This code will:
- Give an example of the data structure we wish to generate
- Prompt the LLM with instructions and the example, plus a sample transcript
<include cwd>../../examples/jsonExtract.ts</include>
<include cwd>../../examples/misc/jsonExtract.ts</include>
To run the code:
```bash
```package-install
npx tsx example.ts
```
@@ -0,0 +1,176 @@
---
title: Workflows
---
A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to chain together several events. Workflows are made up of `handlers`, with each one responsible for processing specific event types and emitting new events.
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
```package-install
npm i @llamaindex/workflow @llamaindex/openai
```
## Getting Started
Let's explore a simple workflow example where a joke is generated and then critiqued and iterated on:
<include cwd>../../examples/agents/workflow/joke.ts</include>
There are a few moving pieces here, so let's go through this step by step.
### Defining Workflow Events
```typescript
const startEvent = workflowEvent<string>(); // Input topic for joke
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
const critiqueEvent = workflowEvent<{ joke: string; critique: string }>(); // Intermediate critique
const resultEvent = workflowEvent<{ joke: string; critique: string }>(); // Final joke + critique
```
Events are defined using the `workflowEvent` function and contain arbitrary data provided as a generic type. In this example, we have four events:
- `startEvent`: Takes a string input (the joke topic)
- `jokeEvent`: Contains an object with a joke property
- `critiqueEvent`: Contains both the joke and its critique, used for the feedback loop
- `resultEvent`: Contains the final joke and critique after any iterations
### Setting up the Workflow with Stateful Middleware
```typescript
const { withState, getContext } = createStatefulMiddleware(() => ({
numIterations: 0,
maxIterations: 3,
}));
const jokeFlow = withState(createWorkflow());
```
Our workflow is implemented using the `createWorkflow()` function, enhanced with the `withState` middleware. This middleware provides shared state across all handlers, which in this case tracks:
- `numIterations`: Counts how many iterations of joke improvement we've done
- `maxIterations`: Sets a limit to prevent infinite loops
This state will be accessible within workflows by using the `getContext().state` function.
### Adding Handlers with Loops
We have three key handlers in our workflow:
1. The first handler processes the `startEvent`, generates an initial joke, and emits a `jokeEvent`:
```typescript
jokeFlow.handle([startEvent], async (event) => {
// Prompt the LLM to write a joke
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke =
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
response.text;
return jokeEvent.with({ joke: joke });
});
```
2. The second handler handles the `jokeEvent`, critiques the joke, and either:
- Emits a `critiqueEvent` if the joke needs improvement
- Emits a `resultEvent` if the joke is good enough
```typescript
jokeFlow.handle([jokeEvent], async (event) => {
// Prompt the LLM to critique the joke
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
const response = await llm.complete({ prompt });
// If the critique includes "IMPROVE", keep iterating, else, return the result
if (response.text.includes("IMPROVE")) {
return critiqueEvent.with({
joke: event.data.joke,
critique: response.text,
});
}
return resultEvent.with({ joke: event.data.joke, critique: response.text });
});
```
3. The third handler processes the `critiqueEvent`, generates an improved joke based on the critique, and either:
- Loops back to the joke evaluation (if under the iteration limit)
- Emits the final `resultEvent` (if iteration limit reached)
```typescript
jokeFlow.handle([critiqueEvent], async (event) => {
// Keep track of the number of iterations
const state = getContext().state;
state.numIterations++;
// Write a new joke based on the previous joke and critique
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke =
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
response.text;
// If we've done less than the max number of iterations, keep iterating
// else, return the result
if (state.numIterations < state.maxIterations) {
return jokeEvent.with({ joke: joke });
}
return resultEvent.with({ joke: joke, critique: event.data.critique });
});
```
### Running the Workflow
```typescript
async function main() {
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
let result: { joke: string, critique: string } | undefined;
for await (const event of stream) {
// console.log(event.data); optionally log the event data
if (resultEvent.include(event)) {
result = event.data;
break; // Stop when we get the final result
}
}
console.log(result);
}
```
To run the workflow, we:
1. Create a workflow context with `createContext()`
2. Trigger the initial event with `sendEvent()`
3. Listen to the event stream and process events as they arrive
4. Use `include()` to check if an event is of a specific type
5. Break the loop when we receive our final result
### Using Stream Utilities
The `stream` returned by `createContext` contains utility functions to make working with event streams easier:
```typescript
// Create a workflow context and send the initial event
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
// Collect all events until we get a resultEvent
const allEvents = await stream.until(resultEvent).toArray();
// The last event will be the resultEvent
const finalEvent = allEvents.at(-1);
console.log(finalEvent.data); // Output the joke and critique
```
The stream utilities make it easier to work with the asynchronous event flow. In this example, we use:
- `toArray`: Aggregates all events into an array
- `until`: Creates a stream that emits events until a condition is met (in this case, until a resultEvent is received)
You can combine these utilities with other stream operators like `filter` and `map` to create powerful processing pipelines.
## Next Steps
To learn more about workflows, check out [the Workflows documentation](/docs/llamaindex/modules/agents/workflows).
+1 -1
View File
@@ -1,3 +1,3 @@
{
"pages": ["llamaindex", "api"]
"pages": ["llamaindex", "api", "llamaflow"]
}
+14
View File
@@ -1,5 +1,19 @@
# @llamaindex/core-e2e
## 0.1.1
### Patch Changes
- b0cd530: # Breaking Change
## What Changed
Remove default setting of llm and embedModel in Settings
## Migration Guide
Set the llm provider and embed Model in the top of your code using Settings.llm = and Settings.embedModel
## 0.1.0
### Minor Changes
@@ -1,5 +1,52 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.164
### Patch Changes
- llamaindex@0.11.3
## 0.0.163
### Patch Changes
- llamaindex@0.11.2
## 0.0.162
### Patch Changes
- llamaindex@0.11.1
## 0.0.161
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
## 0.0.160
### Patch Changes
- llamaindex@0.10.6
## 0.0.159
### Patch Changes
- llamaindex@0.10.5
## 0.0.158
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.0.157
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.157",
"version": "0.0.164",
"type": "module",
"private": true,
"scripts": {
@@ -1,5 +1,51 @@
# @llamaindex/llama-parse-browser-test
## 0.0.66
### Patch Changes
- Updated dependencies [76ff23d]
- @llamaindex/cloud@4.0.11
## 0.0.65
### Patch Changes
- @llamaindex/cloud@4.0.10
## 0.0.64
### Patch Changes
- Updated dependencies [3703f90]
- @llamaindex/cloud@4.0.9
## 0.0.63
### Patch Changes
- @llamaindex/cloud@4.0.8
## 0.0.62
### Patch Changes
- Updated dependencies [40f5f41]
- @llamaindex/cloud@4.0.7
## 0.0.61
### Patch Changes
- @llamaindex/cloud@4.0.6
## 0.0.60
### Patch Changes
- Updated dependencies [2225ffd]
- @llamaindex/cloud@4.0.5
## 0.0.59
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/llama-parse-browser-test",
"private": true,
"version": "0.0.59",
"version": "0.0.66",
"type": "module",
"scripts": {
"dev": "vite",
+47
View File
@@ -1,5 +1,52 @@
# @llamaindex/next-agent-test
## 0.1.164
### Patch Changes
- llamaindex@0.11.3
## 0.1.163
### Patch Changes
- llamaindex@0.11.2
## 0.1.162
### Patch Changes
- llamaindex@0.11.1
## 0.1.161
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
## 0.1.160
### Patch Changes
- llamaindex@0.10.6
## 0.1.159
### Patch Changes
- llamaindex@0.10.5
## 0.1.158
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.1.157
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.157",
"version": "0.1.164",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,7 +1,7 @@
"use server";
import { OpenAIAgent } from "@llamaindex/openai";
import { createStreamableUI } from "ai/rsc";
import type { ChatMessage } from "llamaindex";
import { OpenAIAgent } from "llamaindex";
export async function chatWithAgent(
question: string,
@@ -1,5 +1,52 @@
# test-edge-runtime
## 0.1.163
### Patch Changes
- llamaindex@0.11.3
## 0.1.162
### Patch Changes
- llamaindex@0.11.2
## 0.1.161
### Patch Changes
- llamaindex@0.11.1
## 0.1.160
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
## 0.1.159
### Patch Changes
- llamaindex@0.10.6
## 0.1.158
### Patch Changes
- llamaindex@0.10.5
## 0.1.157
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.1.156
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.156",
"version": "0.1.163",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,61 @@
# @llamaindex/next-node-runtime
## 0.1.31
### Patch Changes
- llamaindex@0.11.3
## 0.1.30
### Patch Changes
- @llamaindex/huggingface@0.1.11
- llamaindex@0.11.2
- @llamaindex/readers@3.1.5
## 0.1.29
### Patch Changes
- llamaindex@0.11.1
## 0.1.28
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
- @llamaindex/huggingface@0.1.10
- @llamaindex/readers@3.1.4
## 0.1.27
### Patch Changes
- Updated dependencies [76c9a80]
- @llamaindex/huggingface@0.1.9
- llamaindex@0.10.6
- @llamaindex/readers@3.1.3
## 0.1.26
### Patch Changes
- llamaindex@0.10.5
- @llamaindex/huggingface@0.1.8
- @llamaindex/readers@3.1.2
## 0.1.25
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.1.24
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.1.24",
"version": "0.1.31",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,7 +1,8 @@
"use server";
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
import { OpenAI, OpenAIAgent } from "@llamaindex/openai";
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
import { OpenAI, OpenAIAgent, Settings, VectorStoreIndex } from "llamaindex";
import { Settings, VectorStoreIndex } from "llamaindex";
Settings.llm = new OpenAI({
apiKey: process.env.NEXT_PUBLIC_OPENAI_KEY ?? "FAKE_KEY_TO_PASS_TESTS",
@@ -1,5 +1,52 @@
# vite-import-llamaindex
## 0.0.30
### Patch Changes
- llamaindex@0.11.3
## 0.0.29
### Patch Changes
- llamaindex@0.11.2
## 0.0.28
### Patch Changes
- llamaindex@0.11.1
## 0.0.27
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
## 0.0.26
### Patch Changes
- llamaindex@0.10.6
## 0.0.25
### Patch Changes
- llamaindex@0.10.5
## 0.0.24
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.0.23
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "vite-import-llamaindex",
"private": true,
"version": "0.0.23",
"version": "0.0.30",
"type": "module",
"scripts": {
"build": "vite build",
@@ -0,0 +1 @@
{"root":["./src/main.ts","./vite.config.ts"],"version":"5.7.3"}
@@ -1,5 +1,54 @@
# @llamaindex/waku-query-engine-test
## 0.0.164
### Patch Changes
- llamaindex@0.11.3
## 0.0.163
### Patch Changes
- llamaindex@0.11.2
## 0.0.162
### Patch Changes
- llamaindex@0.11.1
## 0.0.161
### Patch Changes
- Updated dependencies [b0cd530]
- Updated dependencies [361a685]
- llamaindex@0.11.0
## 0.0.160
### Patch Changes
- llamaindex@0.10.6
## 0.0.159
### Patch Changes
- Updated dependencies [9b2e25a]
- @llamaindex/env@0.1.30
- llamaindex@0.10.5
## 0.0.158
### Patch Changes
- Updated dependencies [2225ffd]
- Updated dependencies [6ddf1c1]
- Updated dependencies [41953a3]
- llamaindex@0.10.4
## 0.0.157
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.157",
"version": "0.0.164",
"type": "module",
"private": true,
"scripts": {
+2
View File
@@ -1,6 +1,7 @@
import { ClipEmbedding } from "@llamaindex/clip";
import type { LoadTransformerEvent } from "@llamaindex/env/multi-model";
import { setTransformers } from "@llamaindex/env/multi-model";
import { OpenAIEmbedding } from "@llamaindex/openai";
import { ImageNode, Settings } from "llamaindex";
import assert from "node:assert";
import { type Mock, test } from "node:test";
@@ -19,6 +20,7 @@ test.before(() => {
test.beforeEach(() => {
callback.mock.resetCalls();
Settings.embedModel = new OpenAIEmbedding();
});
await test.skip("clip embedding", async (t) => {
+2 -6
View File
@@ -1,10 +1,6 @@
import type { TaskStep } from "@llamaindex/core/agent";
import {
LLMSingleSelector,
OpenAIAgent,
Settings,
type ChatMessage,
} from "llamaindex";
import { OpenAIAgent } from "@llamaindex/openai";
import { LLMSingleSelector, Settings, type ChatMessage } from "llamaindex";
import assert from "node:assert";
import { test } from "node:test";
import { divideNumbersTool, sumNumbersTool } from "./fixtures/tools.js";
+1 -2
View File
@@ -1,11 +1,10 @@
import { extractText } from "@llamaindex/core/utils";
import { OpenAI, OpenAIAgent } from "@llamaindex/openai";
import { consola } from "consola";
import {
Document,
FunctionTool,
ObjectIndex,
OpenAI,
OpenAIAgent,
QueryEngineTool,
SentenceSplitter,
Settings,
+2 -1
View File
@@ -1,5 +1,6 @@
import { extractText } from "@llamaindex/core/utils";
import { OpenAI, ReActAgent, Settings, type LLM } from "llamaindex";
import { OpenAI } from "@llamaindex/openai";
import { ReActAgent, Settings, type LLM } from "llamaindex";
import { ok } from "node:assert";
import { beforeEach, test } from "node:test";
import { getWeatherTool } from "./fixtures/tools.js";
+7 -2
View File
@@ -1,8 +1,9 @@
import { OpenAIEmbedding } from "@llamaindex/openai";
import { PGVectorStore } from "@llamaindex/postgres";
import { config } from "dotenv";
import { Document, VectorStoreQueryMode } from "llamaindex";
import { Document, Settings, VectorStoreQueryMode } from "llamaindex";
import assert from "node:assert";
import { test } from "node:test";
import { beforeEach, test } from "node:test";
import pg from "pg";
import { registerTypes } from "pgvector/pg";
@@ -14,6 +15,10 @@ const pgConfig = {
database: "llamaindex_node_test",
};
beforeEach(async () => {
Settings.embedModel = new OpenAIEmbedding();
});
await test("init with client", async (t) => {
const pgClient = new pg.Client(pgConfig);
await pgClient.connect();
+1
View File
@@ -0,0 +1 @@
package-lock.json
+16
View File
@@ -0,0 +1,16 @@
{
"name": "e2e-npm",
"private": true,
"scripts": {
"test": "node --import tsx --test test/*.e2e.ts"
},
"dependencies": {
"@llamaindex/workflow": "1.1.1",
"llamaindex": "0.10.5",
"zod": "^3.23.8"
},
"devDependencies": {
"tsx": "^4.19.1",
"@types/node": "^22.9.0"
}
}
+29
View File
@@ -0,0 +1,29 @@
import { OpenAI } from "@llamaindex/openai";
import { agent } from "@llamaindex/workflow";
import { Settings, tool } from "llamaindex";
import { ok } from "node:assert";
import { test } from "node:test";
import { z } from "zod";
Settings.llm = new OpenAI({ model: "gpt-4-0613" });
test("creating agent from workflow package", async () => {
const calculatorAgent = agent({
tools: [
tool({
name: "add",
description: "Adds two numbers",
parameters: z.object({ x: z.number(), y: z.number() }),
execute: ({ x, y }) => x + y,
}),
],
});
ok(calculatorAgent !== undefined, "calculatorAgent should be defined");
const agents = calculatorAgent.getAgents();
const currentLLM = agents?.[0].llm;
ok(
(currentLLM as OpenAI)?.model === (Settings.llm as OpenAI)?.model,
"Agent should use the same LLM model as setup in Settings instance",
);
});
+13
View File
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "node16",
"moduleResolution": "node16",
"target": "ESNext",
"types": ["node"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["test/**/*.ts"]
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/e2e",
"private": true,
"version": "0.1.0",
"version": "0.1.1",
"type": "module",
"scripts": {
"e2e": "node --import tsx --import ./mock-register.js --test ./node/**/*.e2e.ts",
+1 -2
View File
@@ -1,3 +1,2 @@
package-lock.json
storage
tmp_data
tmp_data
+217
View File
@@ -1,5 +1,222 @@
# examples
## 0.3.17
### Patch Changes
- Updated dependencies [59601dd]
- @llamaindex/openai@0.4.1
- @llamaindex/core@0.6.7
- @llamaindex/clip@0.0.57
- @llamaindex/deepinfra@0.0.57
- @llamaindex/deepseek@0.0.17
- @llamaindex/fireworks@0.0.17
- @llamaindex/groq@0.0.72
- @llamaindex/huggingface@0.1.11
- @llamaindex/jinaai@0.0.17
- @llamaindex/perplexity@0.0.14
- @llamaindex/azure@0.1.17
- @llamaindex/elastic-search@0.1.7
- @llamaindex/milvus@0.1.16
- @llamaindex/qdrant@0.1.16
- @llamaindex/supabase@0.1.6
- @llamaindex/together@0.0.17
- @llamaindex/vllm@0.0.43
- @llamaindex/xai@0.0.4
- @llamaindex/cloud@4.0.10
- llamaindex@0.11.2
- @llamaindex/node-parser@2.0.7
- @llamaindex/anthropic@0.3.8
- @llamaindex/assemblyai@0.1.6
- @llamaindex/cohere@0.0.21
- @llamaindex/discord@0.1.6
- @llamaindex/google@0.3.3
- @llamaindex/mistral@0.1.7
- @llamaindex/mixedbread@0.0.21
- @llamaindex/notion@0.1.6
- @llamaindex/ollama@0.1.7
- @llamaindex/portkey-ai@0.0.49
- @llamaindex/replicate@0.0.49
- @llamaindex/astra@0.0.21
- @llamaindex/chroma@0.0.21
- @llamaindex/firestore@1.0.14
- @llamaindex/mongodb@0.0.22
- @llamaindex/pinecone@0.1.7
- @llamaindex/postgres@0.0.50
- @llamaindex/upstash@0.0.21
- @llamaindex/weaviate@0.0.21
- @llamaindex/vercel@0.1.7
- @llamaindex/voyage-ai@1.0.13
- @llamaindex/readers@3.1.5
- @llamaindex/tools@0.0.12
- @llamaindex/workflow@1.1.4
## 0.3.16
### Patch Changes
- Updated dependencies [680b529]
- Updated dependencies [b0cd530]
- Updated dependencies [c73c659]
- Updated dependencies [361a685]
- Updated dependencies [3e66ddc]
- @llamaindex/workflow@1.1.3
- @llamaindex/core@0.6.6
- llamaindex@0.11.0
- @llamaindex/qdrant@0.1.15
- @llamaindex/azure@0.1.16
- @llamaindex/openai@0.4.0
- @llamaindex/cloud@4.0.8
- @llamaindex/node-parser@2.0.6
- @llamaindex/anthropic@0.3.7
- @llamaindex/assemblyai@0.1.5
- @llamaindex/clip@0.0.56
- @llamaindex/cohere@0.0.20
- @llamaindex/deepinfra@0.0.56
- @llamaindex/discord@0.1.5
- @llamaindex/google@0.3.2
- @llamaindex/huggingface@0.1.10
- @llamaindex/jinaai@0.0.16
- @llamaindex/mistral@0.1.6
- @llamaindex/mixedbread@0.0.20
- @llamaindex/notion@0.1.5
- @llamaindex/ollama@0.1.6
- @llamaindex/perplexity@0.0.13
- @llamaindex/portkey-ai@0.0.48
- @llamaindex/replicate@0.0.48
- @llamaindex/astra@0.0.20
- @llamaindex/chroma@0.0.20
- @llamaindex/elastic-search@0.1.6
- @llamaindex/firestore@1.0.13
- @llamaindex/milvus@0.1.15
- @llamaindex/mongodb@0.0.21
- @llamaindex/pinecone@0.1.6
- @llamaindex/postgres@0.0.49
- @llamaindex/supabase@0.1.5
- @llamaindex/upstash@0.0.20
- @llamaindex/weaviate@0.0.20
- @llamaindex/vercel@0.1.6
- @llamaindex/voyage-ai@1.0.12
- @llamaindex/readers@3.1.4
- @llamaindex/tools@0.0.11
- @llamaindex/deepseek@0.0.16
- @llamaindex/fireworks@0.0.16
- @llamaindex/groq@0.0.71
- @llamaindex/together@0.0.16
- @llamaindex/vllm@0.0.42
- @llamaindex/xai@0.0.3
## 0.3.15
### Patch Changes
- d671ed6: Add functionality for search params when querying Qdrant vector store.
- Updated dependencies [7a7ca60]
- Updated dependencies [7a7ca60]
- Updated dependencies [76c9a80]
- Updated dependencies [168d11f]
- Updated dependencies [d671ed6]
- Updated dependencies [40f5f41]
- @llamaindex/xai@0.0.2
- @llamaindex/fireworks@0.0.15
- @llamaindex/elastic-search@0.1.5
- @llamaindex/firestore@1.0.12
- @llamaindex/pinecone@0.1.5
- @llamaindex/postgres@0.0.48
- @llamaindex/supabase@0.1.4
- @llamaindex/weaviate@0.0.19
- @llamaindex/mongodb@0.0.20
- @llamaindex/upstash@0.0.19
- @llamaindex/chroma@0.0.19
- @llamaindex/milvus@0.1.14
- @llamaindex/qdrant@0.1.14
- @llamaindex/astra@0.0.19
- @llamaindex/azure@0.1.15
- @llamaindex/huggingface@0.1.9
- @llamaindex/assemblyai@0.1.4
- @llamaindex/mixedbread@0.0.19
- @llamaindex/perplexity@0.0.12
- @llamaindex/portkey-ai@0.0.47
- @llamaindex/anthropic@0.3.6
- @llamaindex/deepinfra@0.0.55
- @llamaindex/replicate@0.0.47
- @llamaindex/voyage-ai@1.0.11
- @llamaindex/discord@0.1.4
- @llamaindex/mistral@0.1.5
- @llamaindex/cohere@0.0.19
- @llamaindex/google@0.3.1
- @llamaindex/jinaai@0.0.15
- @llamaindex/notion@0.1.4
- @llamaindex/ollama@0.1.5
- @llamaindex/openai@0.3.7
- @llamaindex/vercel@0.1.5
- @llamaindex/clip@0.0.55
- @llamaindex/tools@0.0.10
- @llamaindex/workflow@1.1.2
- @llamaindex/core@0.6.5
- @llamaindex/cloud@4.0.7
- llamaindex@0.10.6
- @llamaindex/deepseek@0.0.15
- @llamaindex/groq@0.0.70
- @llamaindex/together@0.0.15
- @llamaindex/vllm@0.0.41
- @llamaindex/node-parser@2.0.5
- @llamaindex/readers@3.1.3
## 0.3.14
### Patch Changes
- 9b2e25a: Use Uint8Array instead of Buffer for file type messages (works with non-NodeJS)
- 206b491: Add support for google live api
- Updated dependencies [9b2e25a]
- Updated dependencies [206b491]
- @llamaindex/anthropic@0.3.5
- @llamaindex/google@0.3.0
- @llamaindex/openai@0.3.6
- @llamaindex/core@0.6.4
- @llamaindex/env@0.1.30
- llamaindex@0.10.5
- @llamaindex/clip@0.0.54
- @llamaindex/deepinfra@0.0.54
- @llamaindex/deepseek@0.0.14
- @llamaindex/fireworks@0.0.14
- @llamaindex/groq@0.0.69
- @llamaindex/huggingface@0.1.8
- @llamaindex/jinaai@0.0.14
- @llamaindex/perplexity@0.0.11
- @llamaindex/azure@0.1.14
- @llamaindex/elastic-search@0.1.4
- @llamaindex/milvus@0.1.13
- @llamaindex/qdrant@0.1.13
- @llamaindex/supabase@0.1.3
- @llamaindex/together@0.0.14
- @llamaindex/vllm@0.0.40
- @llamaindex/cloud@4.0.6
- @llamaindex/node-parser@2.0.4
- @llamaindex/assemblyai@0.1.3
- @llamaindex/cohere@0.0.18
- @llamaindex/discord@0.1.3
- @llamaindex/mistral@0.1.4
- @llamaindex/mixedbread@0.0.18
- @llamaindex/notion@0.1.3
- @llamaindex/ollama@0.1.4
- @llamaindex/portkey-ai@0.0.46
- @llamaindex/replicate@0.0.46
- @llamaindex/astra@0.0.18
- @llamaindex/chroma@0.0.18
- @llamaindex/firestore@1.0.11
- @llamaindex/mongodb@0.0.19
- @llamaindex/pinecone@0.1.4
- @llamaindex/postgres@0.0.47
- @llamaindex/upstash@0.0.18
- @llamaindex/weaviate@0.0.18
- @llamaindex/vercel@0.1.4
- @llamaindex/voyage-ai@1.0.10
- @llamaindex/readers@3.1.2
- @llamaindex/tools@0.0.9
- @llamaindex/workflow@1.1.1
## 0.3.13
### Patch Changes
+1 -1
View File
@@ -9,7 +9,7 @@ make sure you have basic knowledge of the [LlamaIndexTS](https://ts.llamaindex.a
# export your API key
export OPENAI_API_KEY="sk-..."
npx tsx ./chatEngine.ts
npx tsx ./rag/chatEngine.ts
```
## Build your own RAG app
@@ -1,12 +1,12 @@
import { tool } from "@llamaindex/core/tools";
import { openai } from "@llamaindex/openai";
import fs from "fs";
import {
agent,
AgentToolCall,
AgentToolCallResult,
agentToolCallEvent,
agentToolCallResultEvent,
multiAgent,
tool,
} from "llamaindex";
} from "@llamaindex/workflow";
import fs from "fs";
import os from "os";
import { z } from "zod";
@@ -56,19 +56,19 @@ async function main() {
rootAgent: researchAgent,
});
const context = workflow.run("Write a blog post about history of LLM");
const events = workflow.runStream("Write a blog post about history of LLM");
let finalResult;
for await (const event of context) {
if (event instanceof AgentToolCall) {
for await (const event of events) {
if (agentToolCallEvent.include(event)) {
console.log(
`[Agent ${event.displayName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
`[Agent ${event.data.agentName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
event.data.toolKwargs,
)}`,
);
} else if (event instanceof AgentToolCallResult) {
} else if (agentToolCallResultEvent.include(event)) {
console.log(
`[Agent ${event.displayName}] executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
`[Tool ${event.data.toolName}] executed with result ${event.data.toolOutput.result}`,
);
}
finalResult = event;
@@ -1,5 +1,6 @@
import { OpenAI } from "@llamaindex/openai";
import { FunctionTool, agent } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { z } from "zod";
const csvData =
@@ -11,24 +12,22 @@ const userQuestion = "which are the best comedies after 2010?";
// The agent will succeed if we increase `maxTokens` to 1024
const llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 1024 });
const interpreterTool = FunctionTool.from(
({ code }) => {
const interpreterTool = tool({
name: "interpreter",
description:
"Execute python code in a Jupyter notebook cell and return any result, stdout, stderr, display_data, and error.",
parameters: z.object({
code: z.string({
description: "The python code to execute in a single cell.",
}),
}),
execute: ({ code }) => {
console.log(
`To answer the user's question, call the following code:\n${code}`,
);
return code;
},
{
name: "interpreter",
description:
"Execute python code in a Jupyter notebook cell and return any result, stdout, stderr, display_data, and error.",
parameters: z.object({
code: z.string({
description: "The python code to execute in a single cell.",
}),
}),
},
);
});
const systemPrompt =
"You are a Python interpreter.\n - You are given tasks to complete and you run python code to solve them.\n - The python code runs in a Jupyter notebook. Every time you call $(interpreter) tool, the python code is executed in a separate cell. It's okay to make multiple calls to $(interpreter).\n - Display visualizations using matplotlib or any other visualization library directly in the notebook. Shouldn't save the visualizations to a file, just return the base64 encoded data.\n - You can install any pip package (if it exists) if you need to but the usual packages for data analysis are already preinstalled.\n - You can run any python code you want in a secure environment.";
@@ -1,6 +1,6 @@
import { openai } from "@llamaindex/openai";
import { mcp } from "@llamaindex/tools";
import { agent } from "llamaindex";
import { agent } from "@llamaindex/workflow";
async function main() {
// Create an MCP server for filesystem tools
@@ -6,15 +6,15 @@
import { openai } from "@llamaindex/openai";
import {
agent,
AgentInput,
AgentOutput,
AgentStream,
AgentToolCall,
AgentToolCallResult,
agentInputEvent,
agentOutputEvent,
agentStreamEvent,
agentToolCallEvent,
agentToolCallResultEvent,
multiAgent,
StopEvent,
tool,
} from "llamaindex";
stopAgentEvent,
} from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { z } from "zod";
const llm = openai({
@@ -79,21 +79,21 @@ async function multiWeatherAgent() {
});
// Ask the agent to get the weather in a city
const context = workflow.run(
const events = workflow.runStream(
"What is the weather in San Francisco in Celsius?",
);
// Stream the events
for await (const event of context) {
// These events might be useful for UI
for await (const event of events) {
// These events are useful for reporting the current state to the user in the UI
if (
event instanceof AgentToolCall ||
event instanceof AgentToolCallResult ||
event instanceof AgentOutput ||
event instanceof AgentInput ||
event instanceof StopEvent
agentToolCallEvent.include(event) ||
agentToolCallResultEvent.include(event) ||
agentOutputEvent.include(event) ||
agentInputEvent.include(event) ||
stopAgentEvent.include(event)
) {
console.log(event);
} else if (event instanceof AgentStream) {
console.log(event.data);
} else if (agentStreamEvent.include(event)) {
for (const chunk of event.data.delta) {
process.stdout.write(chunk);
}
@@ -1,5 +1,6 @@
import { openai } from "@llamaindex/openai";
import { agent, tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { z } from "zod";
const sumNumbers = tool({
@@ -25,7 +26,7 @@ const divideNumbers = tool({
async function main() {
const mathAgent = agent({
tools: [sumNumbers, divideNumbers],
llm: openai({ model: "gpt-4o-mini" }),
llm: openai({ model: "gpt-4.1-mini" }),
verbose: false,
});
@@ -1,11 +1,10 @@
import { openai } from "@llamaindex/openai";
import {
AgentStream,
AgentToolCallResult,
Document,
VectorStoreIndex,
agent,
openai,
} from "llamaindex";
agentStreamEvent,
agentToolCallResultEvent,
} from "@llamaindex/workflow";
import { Document, VectorStoreIndex } from "llamaindex";
async function main() {
const index = await VectorStoreIndex.fromDocuments([
@@ -30,15 +29,15 @@ async function main() {
],
});
const context = myAgent.run("The fact about cats");
const events = myAgent.runStream("The fact about cats");
for await (const event of context) {
if (event instanceof AgentToolCallResult) {
for await (const event of events) {
if (agentToolCallResultEvent.include(event)) {
console.log(
"Using these retrieved information to answer the question:\n",
event.data.toolOutput.result,
);
} else if (event instanceof AgentStream) {
} else if (agentStreamEvent.include(event)) {
for (const chunk of event.data.delta) {
process.stdout.write(chunk);
}
@@ -2,8 +2,8 @@
* This example shows how to use a single agent with a tool
*/
import { openai } from "@llamaindex/openai";
import { agent } from "llamaindex";
import { getWeatherTool } from "../agent/utils/tools";
import { agent } from "@llamaindex/workflow";
import { getWeatherTool } from "../../deprecated/agents/utils/tools";
async function main() {
const weatherAgent = agent({
@@ -14,14 +14,14 @@ async function main() {
verbose: false,
});
// Run the agent and keep the context
const context = weatherAgent.run("What's the weather like in San Francisco?");
const result = await context;
const result = await weatherAgent.run(
"What's the weather like in San Francisco?",
);
console.log(`${JSON.stringify(result, null, 2)}`);
// Reuse the context from the previous run
// Reuse the state from the previous run
const caResult = await weatherAgent.run("Compare it with California?", {
context: context.data,
state: result.data.state,
});
console.log(`${JSON.stringify(caResult, null, 2)}`);
}
@@ -1,6 +1,6 @@
import { OpenAI } from "@llamaindex/openai";
import { wiki } from "@llamaindex/tools";
import { AgentStream, agent } from "llamaindex";
import { agent, agentStreamEvent } from "@llamaindex/workflow";
async function main() {
const llm = new OpenAI({ model: "gpt-4-turbo" });
@@ -12,10 +12,10 @@ async function main() {
});
// Chat with the agent
const context = workflow.run("Who was Goethe?");
const events = workflow.runStream("Who was Goethe?");
for await (const event of context) {
if (event instanceof AgentStream) {
for await (const event of events) {
if (agentStreamEvent.include(event)) {
for (const chunk of event.data.delta) {
process.stdout.write(chunk);
}
@@ -1,11 +1,11 @@
import fs from "fs";
import {
agent,
AgentToolCall,
AgentToolCallResult,
agentToolCallEvent,
agentToolCallResultEvent,
multiAgent,
tool,
} from "llamaindex";
} from "@llamaindex/workflow";
import fs from "fs";
import { tool } from "llamaindex";
import { z } from "zod";
import { anthropic } from "@llamaindex/anthropic";
@@ -81,21 +81,21 @@ async function main() {
rootAgent: researchAgent,
});
const context = workflow.run(
const events = workflow.runStream(
"Write a report about New York weather and inflation",
);
let finalResult;
for await (const event of context) {
if (event instanceof AgentToolCall) {
for await (const event of events) {
if (agentToolCallEvent.include(event)) {
console.log(
`[Agent ${event.displayName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
`[Agent ${event.data.agentName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
event.data.toolKwargs,
)}`,
);
} else if (event instanceof AgentToolCallResult) {
} else if (agentToolCallResultEvent.include(event)) {
console.log(
`[Agent ${event.displayName}] executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
`[Agent executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
);
}
finalResult = event;
@@ -1,6 +1,6 @@
import { ollama } from "@llamaindex/ollama";
import { agent } from "llamaindex";
import { getWeatherTool } from "../agent/utils/tools";
import { agent } from "@llamaindex/workflow";
import { getWeatherTool } from "../../deprecated/agents/utils/tools";
async function main() {
const myAgent = agent({
+94
View File
@@ -0,0 +1,94 @@
import { openai } from "@llamaindex/openai";
import {
createStatefulMiddleware,
createWorkflow,
workflowEvent,
} from "@llamaindex/workflow";
// Create LLM instance
const llm = openai({ model: "gpt-4.1-mini" });
// Define our workflow events
const startEvent = workflowEvent<string>(); // Input topic for joke
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
const critiqueEvent = workflowEvent<{ joke: string; critique: string }>(); // Intermediate critique
const resultEvent = workflowEvent<{ joke: string; critique: string }>(); // Final joke + critique
// Create our workflow
const { withState, getContext } = createStatefulMiddleware(() => ({
numIterations: 0,
maxIterations: 3,
}));
const jokeFlow = withState(createWorkflow());
// Define handlers for each step
jokeFlow.handle([startEvent], async (event) => {
// Prompt the LLM to write a joke
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke =
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
response.text;
return jokeEvent.with({ joke: joke });
});
jokeFlow.handle([jokeEvent], async (event) => {
// Prompt the LLM to critique the joke
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
const response = await llm.complete({ prompt });
// If the critique includes "IMPROVE", keep iterating, else, return the result
if (response.text.includes("IMPROVE")) {
return critiqueEvent.with({
joke: event.data.joke,
critique: response.text,
});
}
return resultEvent.with({ joke: event.data.joke, critique: response.text });
});
jokeFlow.handle([critiqueEvent], async (event) => {
// Keep track of the number of iterations
const state = getContext().state;
state.numIterations++;
// Write a new joke based on the previous joke and critique
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
const response = await llm.complete({ prompt });
// Parse the joke from the response
const joke =
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
response.text;
// If we've done less than the max number of iterations, keep iterating
// else, return the result
if (state.numIterations < state.maxIterations) {
return jokeEvent.with({ joke: joke });
}
return resultEvent.with({ joke: joke, critique: event.data.critique });
});
// Usage
async function main() {
const { stream, sendEvent } = jokeFlow.createContext();
sendEvent(startEvent.with("pirates"));
let result: { joke: string; critique: string } | undefined;
for await (const event of stream) {
// console.log(event.data); optionally log the event data
if (resultEvent.include(event)) {
result = event.data;
break; // Stop when we get the final result
}
}
console.log(result);
}
main().catch(console.error);
@@ -1,12 +1,20 @@
import fs from "node:fs/promises";
import { openai, OpenAIEmbedding } from "@llamaindex/openai";
import {
Document,
MetadataMode,
NodeWithScore,
Settings,
VectorStoreIndex,
} from "llamaindex";
Settings.llm = openai({
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4o",
});
Settings.embedModel = new OpenAIEmbedding();
async function main() {
// Load essay from abramov.txt in Node
const path = "node_modules/llamaindex/examples/abramov.txt";
@@ -7,7 +7,7 @@ import {
VectorStoreIndex,
} from "llamaindex";
import essay from "./essay";
import essay from "../data/essay";
// Update llm to use OpenAI
Settings.llm = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0.1 });
-17
View File
@@ -1,17 +0,0 @@
# Run LlamaIndex Server with simple steps
1. Setup environment variables
```bash
export OPENAI_API_KEY=<your-openai-api-key>
```
2. Run the server
```bash
npx tsx llamaindex-server/simple-workflow/index.ts
```
3. Open the app at `http://localhost:4000` and start chatting with the agent
![Screenshot](./screenshot.png)

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