Compare commits

..

3 Commits

Author SHA1 Message Date
Alex Yang a93224d309 chore: bump version 2024-09-29 23:16:17 -07:00
Alex Yang d991de4f82 feat: experimental document using next.js 2024-09-29 23:09:04 -07:00
Alex Yang 9b40fc7d04 Initial commit from Create Fumadocs App 2024-09-29 22:47:51 -07:00
1470 changed files with 3027 additions and 254140 deletions
-8
View File
@@ -1,8 +0,0 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
-11
View File
@@ -1,11 +0,0 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
-16
View File
@@ -1,16 +0,0 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"target": "esnext",
"transform": {
"decoratorVersion": "2022-03"
}
},
"module": {
"type": "commonjs",
"ignoreDynamic": true
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"image": "mcr.microsoft.com/devcontainers/universal:2",
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers-contrib/features/turborepo-npm:1": {},
"ghcr.io/devcontainers-contrib/features/typescript:2": {},
"ghcr.io/devcontainers-contrib/features/pnpm:2": {}
}
}
-2
View File
@@ -1,2 +0,0 @@
examples/readers/data/** binary
examples/data/** binary
-46
View File
@@ -1,46 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels: bug
assignees: ""
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Code to reproduce the behavior:
```ts
// paste the code here
```
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. macOS, Linux]
- JS Runtime / Framework / Bundler (select all applicable)
- [ ] Node.js
- [ ] Deno
- [ ] Bun
- [ ] Next.js
- [ ] ESBuild
- [ ] Rollup
- [ ] Webpack
- [ ] Turbopack
- [ ] Vite
- [ ] Waku
- [ ] Edge Runtime
- [ ] AWS Lambda
- [ ] Cloudflare Worker
- [ ] Others (please elaborate on this)
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
-10
View File
@@ -1,10 +0,0 @@
name: Bugfix
title: ""
description: Write something like "We notice ... behavior when ... happens instead of ..." If you would like to use sweep.dev prefix with "Sweep:"
body:
- type: textarea
id: description
attributes:
label: Details
description: More details about the bug
placeholder: The bug might be in ... file
-10
View File
@@ -1,10 +0,0 @@
name: Feature Request
title: ""
description: Write something like "Write an api endpoint that does "..." in the "..." file". If you would like to use sweep.dev prefix with "Sweep:"
body:
- type: textarea
id: description
attributes:
label: Details
description: More details
placeholder: The new endpoint should use the ... class from ... file because it contains ... logic
-10
View File
@@ -1,10 +0,0 @@
name: Refactor
title: ""
description: Write something like "Modify the ... api endpoint to use ... version and ... framework" If you would like to use sweep.dev prefix with "Sweep:"
body:
- type: textarea
id: description
attributes:
label: Details
description: More details
placeholder: We are migrating this function to ... version because ...
@@ -1,13 +0,0 @@
name: Trigger Vercel Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Trigger Vercel deployment
run: |
curl -X POST "${{ secrets.DEVELOPER_HUB_DEPLOY_HOOK }}"
@@ -1,32 +0,0 @@
name: Lint on push or pull request
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_REMOTE_ONLY: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Run lint
run: pnpm run lint
- name: Run Prettier
run: pnpm run format
-33
View File
@@ -1,33 +0,0 @@
name: Publish Preview
on: [pull_request]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_REMOTE_ONLY: true
jobs:
pre_release:
name: Pre Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Pre Release
run: pnpx pkg-pr-new publish --pnpm ./packages/* ./packages/providers/* ./packages/providers/storage/*
-37
View File
@@ -1,37 +0,0 @@
name: Publish to GitHub Releases
on:
push:
tags:
- "llamaindex@*"
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build tarball
run: |
pnpm pack
working-directory: packages/llamaindex
- name: Create release
uses: ncipollo/release-action@v1
with:
artifacts: "packages/llamaindex/llamaindex-*.tgz"
name: Release ${{ github.ref }}
bodyFile: "packages/llamaindex/CHANGELOG.md"
token: ${{ secrets.GITHUB_TOKEN }}
-70
View File
@@ -1,70 +0,0 @@
name: Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Add auth token to .npmrc file
run: |
cat << EOF >> ".npmrc"
//registry.npmjs.org/:_authToken=$NPM_TOKEN
EOF
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Get changeset status
id: get-changeset-status
run: |
pnpm changeset status --output .changeset/status.json
new_version=$(jq -r '.releases[] | select(.name == "llamaindex") | .newVersion' < .changeset/status.json)
rm -v .changeset/status.json
echo "new-version=${new_version}" >> "$GITHUB_OUTPUT"
- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
commit: Release ${{ steps.get-changeset-status.outputs.new-version }}
title: Release ${{ steps.get-changeset-status.outputs.new-version }}
# update version PR with the latest changesets
version: pnpm new-version
# build package and call changeset publish
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# Refs: https://github.com/changesets/changesets/issues/421
- name: Update lock file
continue-on-error: true
run: pnpm install --lockfile-only
- name: Commit lock file
continue-on-error: true
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update lock file"
branch: changeset-release/main
file_pattern: "pnpm-lock.yaml"
-217
View File
@@ -1,217 +0,0 @@
name: Run Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
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:
fail-fast: false
matrix:
node-version: [20.x, 22.x, 23.x]
name: E2E on Node.js ${{ matrix.node-version }}
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:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Run E2E Tests
run: pnpm run e2e
test:
strategy:
fail-fast: false
matrix:
node-version: [20.x, 22.x, 23.x]
name: Test on Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Run tests
run: pnpm run test
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Run Type Check
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
pnpm pack --pack-destination ${{ runner.temp }} -C packages/core
- 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
matrix:
packages:
- cloudflare-worker-agent
- nextjs-agent
- nextjs-edge-runtime
- nextjs-node-runtime
- waku-query-engine
- vite-import-llamaindex
runs-on: ubuntu-latest
name: Build LlamaIndex Example (${{ matrix.packages }})
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build llamaindex
run: pnpm run build
- name: Build ${{ matrix.packages }}
run: pnpm run build
working-directory: e2e/examples/${{ matrix.packages }}
size-limit:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
name: Size Limit
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build llamaindex
run: pnpm run build
- uses: andresz1/size-limit-action@94bc357df29c36c8f8d50ea497c3e225c3c95d1d
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
directory: e2e/examples/vite-import-llamaindex
skip_step: "install"
build_script: ci-build
package_manager: pnpm
typecheck-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Copy examples
run: rsync -rv --exclude=node_modules ./examples ${{ runner.temp }}
- 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/* packages/providers/storage/*; 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 --legacy-peer-deps
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
+17 -42
View File
@@ -1,53 +1,28 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# deps
/node_modules
# dependencies
node_modules
.pnp
.pnpm-store
.pnp.js
# generated content
.contentlayer
.content-collections
.source
# testing
coverage
# next.js
.next/
out/
build
# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo
# misc
.DS_Store
*.pem
# debug
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# turbo
.turbo
# vercel
# others
.env*.local
.vercel
dist/
lib/
.cache
test-results/
playwright-report/
blob-report/
playwright/.cache/
.tsbuildinfo
# intellij
**/.idea
# generated API
packages/cloud/src/client
next-env.d.ts
-1
View File
@@ -1 +0,0 @@
pnpm run lint-staged
-5
View File
@@ -1,5 +0,0 @@
auto-install-peers = true
enable-pre-post-scripts = true
prefer-workspace-packages = true
save-workspace-protocol = true
link-workspace-packages = true
-1
View File
@@ -1 +0,0 @@
22
-11
View File
@@ -1,11 +0,0 @@
apps/docs/i18n
apps/docs/docs/api
pnpm-lock.yaml
lib/
dist/
docs/
.docusaurus/
.source/
# prttier doesn't support mdx3 we are using
*.mdx
packages/server/server/
-12
View File
@@ -1,12 +0,0 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"target": "esnext",
"transform": {
"decoratorVersion": "2022-03"
}
}
}
-18
View File
@@ -1,18 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Example",
"skipFiles": ["<node_internals>/**"],
"runtimeExecutable": "pnpm",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/examples",
"runtimeArgs": ["npx", "tsx", "${file}"]
}
]
}
-1
View File
@@ -1 +0,0 @@
LlamaIndexTS
-19
View File
@@ -1,19 +0,0 @@
{
"editor.tabSize": 2,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[xml]": {
"editor.defaultFormatter": "redhat.vscode-xml"
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"prettier.prettierPath": "./node_modules/prettier",
"prettier.configPath": "prettier.config.mjs"
}
-92
View File
@@ -1,92 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Development Commands
This project uses pnpm as the package manager and Turbo for build orchestration:
- `pnpm install` - Install all dependencies
- `pnpm build` - Build all packages using Turbo
- `pnpm dev` - Start development mode for all packages
- `pnpm test` - Run all unit tests
- `pnpm e2e` - Run end-to-end tests
- `pnpm lint` - Run ESLint across all packages
- `pnpm type-check` - Run TypeScript type checking across workspace
- `pnpm format` - Check code formatting with Prettier
- `pnpm format:write` - Auto-fix formatting issues
- `pnpm circular-check` - Check for circular dependencies using madge
For individual package development:
- `turbo run build --filter="@llamaindex/core"` - Build specific package
- `turbo run test --filter="@llamaindex/core"` - Test specific package
- Navigate to specific package directory and run `pnpm test` for focused testing
- `pnpm clean` - Remove all build artifacts and node_modules across workspace
## Architecture Overview
LlamaIndex.TS is a TypeScript data framework for LLM applications organized as a pnpm monorepo with multiple runtime environment support (Node.js, Deno, Bun, Vercel Edge, Cloudflare Workers).
### Package Structure
**Core Packages:**
- `packages/core/` - Abstract base classes and interfaces for all runtime environments
- `packages/llamaindex/` - Main package that aggregates core functionality
- `packages/env/` - Environment-specific compatibility layers for different JS runtimes
**Provider Packages (`packages/providers/`):**
- LLM providers: `openai/`, `anthropic/`, `ollama/`, `google/`, `groq/`, etc.
- Vector stores: `storage/pinecone/`, `storage/chroma/`, `storage/qdrant/`, etc.
- Embeddings: Various embedding providers integrated within LLM packages
- Readers: `assemblyai/`, `discord/`, `notion/` for data ingestion
**Specialized Packages:**
- `packages/cloud/` - LlamaCloud integration for managed services
- `packages/tools/` - Function calling tools and utilities
- `packages/workflow/` - Agent workflow orchestration
- `packages/readers/` - File format readers (PDF, DOCX, etc.)
### Key Architectural Patterns
**Runtime Abstraction:** Core functionality is runtime-agnostic, with environment-specific implementations in separate entry points (`index.ts`, `index.edge.ts`, `index.workerd.ts`).
**Provider Pattern:** LLMs, embeddings, and vector stores implement common interfaces from `@llamaindex/core`, allowing easy swapping between providers.
**Modular Design:** Each provider is a separate package to minimize bundle size - users install only what they need.
**Data Flow:** Document → NodeParser → Embedding → VectorStore → Retriever → QueryEngine → Response
### Core Components
- **Agents and Workflows:** Abstractions for building agentic workflows and agents in `packages/workflow`
- **Chat Engines:** Conversational interfaces in `core/chat-engine/`
- **Query Engines:** Document querying with retrieval in `core/query-engine/`
- **Indices:** VectorStoreIndex, SummaryIndex, KeywordTable in `llamaindex/indices/`
- **Node Parsers:** Text splitting and chunking in `core/node-parser/`
- **Ingestion Pipeline:** Document processing workflows in `llamaindex/ingestion/`
- **Storage:** Chat stores, document stores, index stores, and KV stores in `core/storage/`
### Deprecated Components
- **Agents:** ReAct and function calling agents in `core/agent/` and `llamaindex/agent/`
### Testing Structure
- Unit tests in each package's `tests/` directory
- E2E tests in `e2e/` directory with runtime-specific examples
- Tests depend on build artifacts, so always run `pnpm build` before testing
### Multi-Runtime Support
The codebase supports multiple JavaScript runtimes through conditional exports and separate entry points. When making changes, consider compatibility across Node.js, Deno, Bun, and edge runtimes.
### Development Notes
- The project uses Husky for git hooks with lint-staged for pre-commit formatting and linting
- All packages use bunchee for building with dual CJS/ESM support
- Core package exports are organized as sub-modules (e.g., `@llamaindex/core/llms`, `@llamaindex/core/embeddings`)
- Always run `pnpm build` before running tests, as tests depend on build artifacts
-165
View File
@@ -1,165 +0,0 @@
# Contributing
## Structure
LlamaIndex.TS uses pnpm monorepo.
We recommend you to understand the basics of Node.js, TypeScript, pnpm, and of course, LLM before contributing.
There are some important folders in the repository:
- `packages/*`: Contains the source code of the packages. Each package is a separate npm package.
- `llamaindex`: The starter package for LlamaIndex.TS, which contains the all sub-packages.
- `core`: The core package of LlamaIndex.TS, which contains the abstract classes and interfaces. It is designed for
all JS runtime environments.
- `env`: The environment package of LlamaIndex.TS, which contains the environment-specific classes and interfaces. It
includes compatibility layers for Node.js, Deno, Vercel Edge Runtime, Cloudflare Workers...
- `providers/*`: The providers package of LlamaIndex.TS, which contains the providers for LLM and other services.
- `apps/*`: The applications based on LlamaIndex.TS.
- `next`: Our documentation website based on Next.js.
- `examples`: The code examples of LlamaIndex.TS using Node.js.
## Getting Started
Make sure you have Node.js LTS (Long-term Support) installed. You can check your Node.js version by running:
```shell
node -v
# v22.x.x
```
### Use pnpm
```shell
npm install -g pnpm
```
### Install dependencies
```shell
pnpm install
pnpm install -g tsx
```
### Build the packages
To build all packages, run:
```shell
pnpm build
```
### Start Developing
You can launch the package in dev-mode by running:
```shell
pnpm dev
```
This will use turbo to run all packages in watch-mode. This means you can make changes and have them automatically built.
If you want to customize what packages are built/watched, you can run turbo directly and adjust the filter:
```shell
pnpm turbo run dev --filter="./packages/core" --concurrency=100
```
In another terminal, you can write and run any script needed to quickly test your changes. For example:
```typescript
import { createMemory, staticBlock } from "@llamaindex/core/memory";
// Create memory with predefined context
const memory = createMemory({
memoryBlocks: [
staticBlock({
content:
"The user is a software engineer who loves TypeScript and LlamaIndex.",
messageRole: "system",
}),
],
});
async function main() {
const result = await memory.getLLM();
console.log(result);
}
void main().catch(console.error);
```
And run it with:
```shell
pnpm exec tsx my_script.ts
```
This flow allows you to easily test your changes without having to build the entire project.
Once you are happy with your changes, be sure to add tests (and confirm existing tests are passing!).
### Run tests
#### Unit tests
After build, to run all unit tests, call:
```shell
pnpm test
```
Unit tests are located in the `tests` folder of each package. They are using their own package (e.g. `@llamaindex/core-tests` for `@llamaindex/core`). The tests are importing the package under test and the test package is not published.
#### E2E tests
To run all E2E tests, call:
```shell
pnpm e2e
```
All E2E tests are in the `e2e` folder.
### Docs
See the [docs](./apps/next/README.md) for more information.
## Adding a new package
Please follow these steps to add a new package:
1. Only add new packages to the `packages/providers` folder.
2. Use the `package.json` and `tsconfig.json` of an existing packages as template.
3. Reference your new package in the root `tsconfig.json` file
4. Add your package to the `examples/package.json` file if you add a new example.
## Before sending a PR
Before sending a PR, make sure of the following:
1. Tests are all running and you added meaningful tests for your change.
2. If you have a new feature, document it in the `apps/next` docs folder.
3. If you have a new feature, add a new example in the `examples` folder.
4. You have a descriptive changeset for each PR:
### Bumping the versions of packages you've modified
We use [changesets](https://github.com/changesets/changesets) for managing versions and changelogs. To create a new
changeset, run in the root folder:
```shell
pnpm changeset
```
You will be prompted to choose what packages need their versions bumped, and what kind of bump (major, minor or patch) is needed. Once you carry out this operation, the bumping will be automatic after the PR is merged.
## Publishing (maintainers only)
The [Release Github Action](.github/workflows/release.yml) is automatically generating and updating a
PR called "Release {version}".
This PR will update the `package.json` and `CHANGELOG.md` files of each package according to
the current changesets in the [.changeset](.changeset) folder.
If this PR is merged it will automatically add version tags to the repository and publish the updated packages to NPM.
-21
View File
@@ -1,21 +0,0 @@
The MIT License
Copyright (c) LlamaIndex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+18 -88
View File
@@ -1,96 +1,26 @@
<p align="center">
<img height="100" width="100" alt="LlamaIndex logo" src="https://ts.llamaindex.ai/square.svg" />
</p>
<h1 align="center">LlamaIndex.TS</h1>
<h3 align="center">
Data framework for your LLM application.
</h3>
# llamaindex-ts-doc
[![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://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)
This is a Next.js application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in JS runtime environments with TypeScript support.
Run development server:
Documentation: https://ts.llamaindex.ai/
Try examples online:
[![Open in Stackblitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples)
## What is LlamaIndex.TS?
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.
## Compatibility
### Multiple JS Environment Support
LlamaIndex.TS supports multiple JS environments, including:
- Node.js >= 20 ✅
- Deno ✅
- Bun ✅
- 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
```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```
### Setup in Node.js, Deno, Bun, TypeScript...?
Open http://localhost:3000 with your browser to see the result.
See our official document: https://ts.llamaindex.ai/docs/llamaindex/getting_started
## Learn More
### Adding provider packages
To learn more about Next.js and Fumadocs, take a look at the following
resources:
In most cases, you'll also need to install provider packages to use LlamaIndexTS. These are for adding AI models, file readers for ingestion or storing documents, e.g. in vector databases.
For example, to use the OpenAI LLM, you would install the following package:
```shell
npm install @llamaindex/openai
pnpm install @llamaindex/openai
yarn add @llamaindex/openai
```
## Playground
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:
See our documentation: https://ts.llamaindex.ai/docs/llamaindex/getting_started/concepts
## Contributing:
Please see our [contributing guide](CONTRIBUTING.md) for more information.
You are highly encouraged to contribute to LlamaIndex.TS!
## Community
Please join our Discord! https://discord.com/invite/eN6D2HQ4aX
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs
+11
View File
@@ -0,0 +1,11 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/home-layout';
import { baseOptions } from '../layout.config';
export default function Layout({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
}
+19
View File
@@ -0,0 +1,19 @@
import Link from 'next/link';
export default function HomePage() {
return (
<main className="flex h-screen flex-col justify-center text-center">
<h1 className="mb-4 text-2xl font-bold">Hello World</h1>
<p className="text-fd-muted-foreground">
You can open{' '}
<Link
href="/docs"
className="text-fd-foreground font-semibold underline"
>
/docs
</Link>{' '}
and see the documentation.
</p>
</main>
);
}
+12
View File
@@ -0,0 +1,12 @@
import { source } from '@/app/source';
import { createSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = createSearchAPI('advanced', {
indexes: source.getPages().map((page) => ({
title: page.data.title,
description: page.data.description,
structuredData: page.data.structuredData,
id: page.url,
url: page.url,
})),
});
+45
View File
@@ -0,0 +1,45 @@
import { source } from '@/app/source';
import type { Metadata } from 'next';
import {
DocsPage,
DocsBody,
DocsDescription,
DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import defaultMdxComponents from 'fumadocs-ui/mdx';
export default async function Page({
params,
}: {
params: { slug?: string[] };
}) {
const page = source.getPage(params.slug);
if (!page) notFound();
const MDX = page.data.body;
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={{ ...defaultMdxComponents }} />
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
return source.generateParams();
}
export function generateMetadata({ params }: { params: { slug?: string[] } }) {
const page = source.getPage(params.slug);
if (!page) notFound();
return {
title: page.data.title,
description: page.data.description,
} satisfies Metadata;
}
+12
View File
@@ -0,0 +1,12 @@
import { DocsLayout } from 'fumadocs-ui/layout';
import type { ReactNode } from 'react';
import { baseOptions } from '../layout.config';
import { source } from '@/app/source';
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
{children}
</DocsLayout>
);
}
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
+21
View File
@@ -0,0 +1,21 @@
import { type HomeLayoutProps } from 'fumadocs-ui/home-layout';
/**
* Shared layout configurations
*
* you can configure layouts individually from:
* Home Layout: app/(home)/layout.tsx
* Docs Layout: app/docs/layout.tsx
*/
export const baseOptions: HomeLayoutProps = {
nav: {
title: 'My App',
},
links: [
{
text: 'Documentation',
url: '/docs',
active: 'nested-url',
},
],
};
+18
View File
@@ -0,0 +1,18 @@
import './global.css';
import { RootProvider } from 'fumadocs-ui/provider';
import { Inter } from 'next/font/google';
import type { ReactNode } from 'react';
const inter = Inter({
subsets: ['latin'],
});
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" className={inter.className} suppressHydrationWarning>
<body>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}
+8
View File
@@ -0,0 +1,8 @@
import { docs, meta } from '@/.source';
import { createMDXSource } from 'fumadocs-mdx';
import { loader } from 'fumadocs-core/source';
export const source = loader({
baseUrl: '/docs',
source: createMDXSource(docs, meta),
});
+54
View File
@@ -0,0 +1,54 @@
---
title: Welcome to LlamaIndex.TS
description: A framework for building LLM-powered applications
---
# What is LlamaIndex?
LlamaIndex is a framework for building LLM-powered applications. LlamaIndex helps you ingest, structure, and access private or domain-specific data. It's available [as a Python package](https://docs.llamaindex.ai/en/stable/) and in TypeScript (this package). LlamaIndex.TS offers the core features of LlamaIndex for popular runtimes like Node.js (official support), Vercel Edge Functions (experimental), and Deno (experimental).
## 🚀 Why LlamaIndex.TS?
LLMs offer a natural language interface between humans and inferred data. Widely available models come pre-trained on huge amounts of publicly available data, from Wikipedia and mailing lists to textbooks and source code.
Applications built on top of LLMs often require augmenting these models with private or domain-specific data. That data is often distributed across siloed applications and data stores. It's behind APIs, in SQL databases, or trapped in PDFs and slide decks.
LlamaIndex.TS helps you unlock that data and then build powerful applications with it.
## 🦙 What is LlamaIndex for?
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 interactive, unsupervised manner.
## 👨‍👩‍👧‍👦 Who is LlamaIndex for?
LlamaIndex targets the "AI Engineer": developers building software in any domain that can be enhanced by LLM-powered functionality, without needing to be an expert in machine learning or natural language processing.
Our high-level API allows beginner users to use LlamaIndex.TS to ingest, index, and query their data in just a few lines of code.
For more complex applications, our lower-level APIs allow advanced users to customize and extend any module—data connectors, indices, retrievers, and query engines, to fit their needs.
## Getting Started
`npm install llamaindex`
Our documentation includes [Installation Instructions](./getting_started/installation.mdx) and a [Starter Tutorial](./getting_started/starter_tutorial/retrieval_augmented_generation.mdx) to build your first application.
Once you're up and running, [High-Level Concepts](./getting_started/concepts.md) has an overview of LlamaIndex's modular architecture. For more hands-on practical examples, look through our Examples section on the sidebar.
## 🗺️ Ecosystem
To download or contribute, find LlamaIndex on:
- Github: https://github.com/run-llama/LlamaIndexTS
- NPM: https://www.npmjs.com/package/llamaindex
## Community
Need help? Have a feature suggestion? Join the LlamaIndex community:
- Twitter: https://twitter.com/llama_index
- Discord https://discord.gg/dGcwcsnxhU
-36
View File
@@ -1,36 +0,0 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
.env.local
# macOS-specific files
.DS_Store
# built files
.build
docs-python/src/content/docs/cloud
docs-python/src/content/docs/framework
docs-python/src/content/docs/workflows
docs-python/src/content/docs/examples
docs-typescript/src/content/docs/cloud
docs-typescript/src/content/docs/framework
docs-typescript/src/content/docs/examples
docs-typescript/src/content/docs/workflows
public/python-api-reference
public/typescript-api-reference
public/cloud-api-reference
-1220
View File
File diff suppressed because it is too large Load Diff
-143
View File
@@ -1,143 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with the LlamaIndex.TS documentation site.
## Application Overview
This is a Next.js documentation site (`@llamaindex/doc`) that serves as the official documentation for LlamaIndex.TS. It's built using Fumadocs, a modern documentation framework, and includes interactive features, API documentation generation, and AI-powered chat functionality.
## Development Commands
From this directory (`apps/next/`):
- `pnpm dev` - Start development server with Turbo
- `pnpm build` - Build the documentation site (includes `prebuild` step)
- `pnpm start` - Start production server
- `pnpm build:docs` - Generate API documentation from TypeScript source
- `pnpm validate-links` - Validate all internal and external links
Key build process:
1. `prebuild` runs `build:docs` to generate API documentation using TypeDoc
2. `build` runs Next.js build process
3. `postbuild` runs post-processing scripts and link validation
## Architecture
### Framework Stack
- **Next.js 15.3** - React framework with App Router
- **Fumadocs** - Documentation framework with MDX support
- **React Server Components** - AI chat functionality with server actions
- **Tailwind CSS** - Styling with custom design system
- **TypeScript** - Full type safety
### Key Dependencies
- **Fumadocs ecosystem**: `fumadocs-ui`, `fumadocs-mdx`, `fumadocs-core`, `fumadocs-openapi`
- **AI features**: `ai` package for React Server Components chat
- **Code features**: Monaco Editor, Shiki syntax highlighting, Twoslash TypeScript integration
- **UI components**: Radix UI primitives, Framer Motion animations
- **Content processing**: MDX, remark/rehype plugins, TypeDoc for API generation
### Directory Structure
**Content Management:**
- `src/content/docs/` - MDX documentation files organized by topic
- `src/content/docs/api/` - Auto-generated API documentation from TypeScript
- `scripts/` - Build-time documentation generation and validation
**Application Code:**
- `src/app/` - Next.js App Router pages and API routes
- `src/components/` - Reusable React components including UI library
- `src/lib/` - Utilities, constants, and configuration
**Configuration:**
- `source.config.ts` - Fumadocs MDX configuration with plugins
- `next.config.mjs` - Next.js configuration with MDX integration
- `tailwind.config.mjs` - Tailwind CSS customization
### Key Features
**Documentation Features:**
- MDX-based content with TypeScript code highlighting
- Auto-generated API documentation from TypeScript source
- Interactive code examples with Monaco Editor
- Math equation support with KaTeX
- Link validation and build-time checks
**Interactive Features:**
- AI-powered chat interface using React Server Components
- Code demos with live TypeScript execution
- Interactive UI components and animations
- Search functionality across all documentation
**Build Process:**
- TypeDoc generates API documentation from workspace packages
- Custom scripts transform and validate generated content
- Link checking ensures all internal/external links work
- Static site generation with 10-minute timeout for large documentation set
### Configuration Files
**source.config.ts**: Defines MDX processing pipeline with:
- Code highlighting themes (Catppuccin)
- Twoslash TypeScript integration
- Remark/rehype plugins for enhanced Markdown
- Content directories including external docs
**next.config.mjs**: Next.js configuration with:
- Extended static generation timeout (10 minutes)
- Monaco Editor transpilation
- Server external packages for build optimization
- Webpack/Turbopack aliases for browser compatibility
### Content Organization
**Documentation Structure:**
- `/docs/llamaindex/` - Core LlamaIndex.TS documentation
- `/docs/cloud/` - LlamaCloud integration guides
- `/docs/api/` - Auto-generated TypeScript API reference
**Content Sources:**
- Local MDX files in `src/content/docs/`
- External docs from `@llamaindex/workflow-docs` package
- Generated API docs from TypeScript source
### Development Notes
- Documentation content is sourced from multiple locations including external packages
- API documentation is regenerated on each build from TypeScript source
- The site uses advanced MDX features including custom transformers and plugins
- Build process includes comprehensive link validation
- Large memory allocation needed for TypeDoc generation (`--max-old-space-size=8192`)
- Chat functionality uses React Server Components with streaming responses
### AI Chat Integration
The documentation includes an AI chat feature that:
- Uses React Server Components for server-side AI processing
- Integrates with LlamaIndex.TS packages for demonstrations
- Provides interactive examples and code generation
- Streams responses for better user experience
### Content Authoring
When adding new documentation:
- Create MDX files in appropriate `src/content/docs/` subdirectories
- Follow existing content structure and frontmatter conventions
- Use Fumadocs MDX features like code blocks, callouts, and tabs
- API documentation is auto-generated - edit TypeScript source comments instead
- Run `pnpm validate-links` to check all links before publishing
-115
View File
@@ -1,115 +0,0 @@
// @ts-check
import { defineConfig, passthroughImageService } from 'astro/config';
import starlight from '@astrojs/starlight';
import react from '@astrojs/react';
import AutoImport from 'astro-auto-import';
import starlightAutoSidebar from 'starlight-auto-sidebar'
import path from 'path';
// https://astro.build/config
export default defineConfig({
site: "https://developers.llamaindex.ai",
base: "/typescript/",
outDir: path.resolve('../dist/typescript/'),
integrations: [
starlight({
plugins: [starlightAutoSidebar()],
title: 'LlamaIndex Documentation',
head: [
{
tag: 'script',
content: `
(function (w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != "dataLayer" ? "&l=" + l : "";
j.async = true;
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, "script", "dataLayer", "GTM-WWRFB36R");
`,
},
{
tag: 'script',
content: `
document.addEventListener("DOMContentLoaded", function () {
var script = document.createElement("script");
script.type = "module";
script.id = "runllm-widget-script"
script.src = "https://widget.runllm.com";
script.setAttribute("version", "stable");
script.setAttribute("crossorigin", "true");
script.setAttribute("runllm-keyboard-shortcut", "Mod+j");
script.setAttribute("runllm-name", "LlamaIndex");
script.setAttribute("runllm-position", "BOTTOM_RIGHT");
script.setAttribute("runllm-assistant-id", "1450");
script.setAttribute("runllm-disable-ask-a-person", true);
script.setAttribute(
"runllm-slack-community-url",
"https://discord.com/invite/eN6D2HQ4aX"
);
script.async = true;
document.head.appendChild(script);
});
`
}
],
social: [
{
icon: 'twitter',
label: 'Twitter',
href: 'https://x.com/llama_index'
},
{
icon: 'linkedin',
label: 'LinkedIn',
href: 'https://www.linkedin.com/company/llamaindex'
},
{
icon: 'blueSky',
label: 'Bluesky',
href: 'https://bsky.app/profile/llamaindex.bsky.social'
},
{
icon: 'github',
label: 'GitHub',
href: 'https://github.com/run-llama/LlamaIndexTS'
}
],
logo: {
light: './src/assets/llamaindex-dark.svg',
dark: './src/assets/llamaindex-light.svg',
replacesTitle: true,
},
favicon: '/logo-dark.png',
components: {
SiteTitle: './src/components/SiteTitle.astro',
Header: './src/components/Header.astro',
},
sidebar: [
{
label: 'Framework',
autogenerate: { directory: 'framework', collapsed: true },
},
{
label: 'Framework API Reference 🔗',
link: '/framework-api-reference/'
},
],
}),
AutoImport({
imports: [
{
'@icons-pack/react-simple-icons': ['SiBun', 'SiCloudflareworkers', 'SiDeno', 'SiNodedotjs', 'SiTypescript', 'SiVite', 'SiNextdotjs', 'SiDiscord', 'SiGithub', 'SiNpm', 'SiX'],
'@astrojs/starlight/components': ['Card', 'CardGrid', 'LinkCard', 'Icon', 'Tabs', 'TabItem', 'Aside']
},
],
}),
react(),
],
image: {
service: passthroughImageService(),
}
});
-9937
View File
File diff suppressed because it is too large Load Diff
-39
View File
@@ -1,39 +0,0 @@
{
"name": "",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^4.2.6",
"@astrojs/react": "^4.2.7",
"@astrojs/starlight": "^0.34.3",
"@icons-pack/react-simple-icons": "^12.8.0",
"@types/react": "^19.1.4",
"@types/react-dom": "^19.1.5",
"astro": "^5.6.1",
"astro-auto-import": "^0.4.4",
"astro-icon": "^1.1.5",
"cross-env": "^7.0.3",
"dotenv": "^16.4.5",
"fs-extra": "^11.3.0",
"fumadocs-typescript": "^4.0.6",
"fumadocs-ui": "^15.3.3",
"glob": "^11.0.2",
"js-yaml": "^4.1.0",
"marked": "^15.0.11",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"sharp": "^0.32.5",
"starlight-auto-sidebar": "^0.1.2",
"typedoc": "^0.28.4",
"typedoc-plugin-markdown": "^4.6.3",
"typedoc-plugin-merge-modules": "^7.0.0"
},
"packageManager": "pnpm@10.8.1"
}
-22
View File
@@ -1,22 +0,0 @@
<svg width="543" height="100" viewBox="0 0 543 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 20C0 8.9543 8.96156 0 20.0162 0H80.0648C91.1194 0 100.081 8.95431 100.081 20V80C100.081 91.0457 91.1194 100 80.0648 100H20.0162C8.96155 100 0 91.0457 0 80V20Z" fill="black"/>
<path d="M62.8864 65.775C56.444 68.619 49.4648 67.4537 46.7804 66.5156C46.7804 67.1575 46.7512 69.1522 46.634 71.9961C46.5169 74.8401 45.6091 76.6373 45.1699 77.1804C45.2187 78.9579 45.2577 82.8387 45.0234 84.1422C44.7892 85.4456 43.9497 86.5615 43.5593 86.9565H39.606C39.9574 85.179 41.3142 84.0434 41.9487 83.6978C42.3001 80.0244 41.607 76.8348 41.2166 75.6992C40.8261 77.0817 39.8695 80.291 39.1667 82.0685C38.4639 83.8459 37.4097 85.4753 36.9704 86.0678H34.0421C33.8957 84.2903 34.8718 83.6978 35.5063 83.6978C35.7991 83.1547 36.5019 81.4464 36.9704 78.9579C37.439 76.4694 36.7752 71.7986 36.3848 69.7743V63.405C31.6994 60.887 29.9424 58.3689 28.771 55.5546C27.8339 53.3031 28.0877 49.8765 28.3318 48.4447C28.0389 47.9016 27.1852 46.5212 26.8676 44.5935C26.4283 41.9273 26.6724 40.0017 26.8676 38.9649C26.5747 38.6686 25.9891 37.1578 25.9891 33.4843C25.9891 29.8109 27.0628 27.9051 27.5996 27.4113V25.782C25.5498 25.6339 23.4999 24.7451 22.3286 23.5601C21.1572 22.3752 22.0358 20.5977 22.7678 20.0052C23.4999 19.4127 24.232 19.8571 25.257 19.5608C26.2819 19.2646 27.1604 18.9683 27.5996 18.0796C27.951 17.3686 27.258 14.4259 26.8676 13.0435C28.6246 13.2805 29.7471 14.8209 30.0888 15.5615V13.0435C32.285 14.0803 36.2383 16.5984 37.5561 22.0789C38.6103 26.4633 39.3619 35.6568 39.6059 39.7055C45.2186 39.7549 52.3443 38.9013 58.7867 40.298C64.6434 41.5677 67.279 44.1492 70.3538 44.1492C73.4285 44.1492 75.1856 42.3717 77.3818 43.8529C79.5781 45.3341 80.7495 49.4816 80.4566 52.5921C80.2224 55.0806 78.3092 55.9002 77.3818 55.999C76.2105 59.9094 77.3818 63.6519 78.1139 65.0344V70.6631C78.4556 71.1568 79.1389 72.6775 79.1389 74.8105C79.1389 76.9435 78.4556 78.3654 78.1139 78.8098C78.6996 82.1277 77.8699 85.5247 77.3818 86.8084H73.4285C73.8971 85.6234 74.6975 85.3272 75.0391 85.3272C75.742 81.6537 75.2344 78.2667 74.8927 77.0323C72.6672 75.7288 71.2323 73.428 70.793 72.4405C70.8418 73.2799 70.7052 75.6104 69.7681 78.2173C68.831 80.8243 67.4254 82.3647 66.8397 82.8091V85.9197H62.8864C62.8864 84.0237 63.9602 83.6485 64.497 83.6978C65.1803 82.4635 66.8397 80.5873 66.8397 76.8842C66.8397 73.7596 64.6435 72.2924 63.0329 69.4781C62.2676 68.141 62.6424 66.4663 62.8864 65.775Z" fill="url(#paint0_linear_3021_4359)"/>
<path d="M169.643 73.8052V24.6479H180.094V73.8052H169.643Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M426.79 74.3352C423.394 74.3352 420.335 73.5844 417.613 72.0827C414.888 70.5369 412.721 68.3949 411.113 65.6564C409.551 62.9182 408.77 59.6939 408.77 55.9839C408.77 52.2299 409.551 48.9837 411.113 46.2454C412.721 43.5069 414.888 41.3869 417.613 39.8854C420.335 38.3837 423.394 37.6329 426.79 37.6329C429.826 37.6329 432.485 38.2954 434.763 39.6204C435.808 40.2289 436.745 40.9817 437.574 41.8789V24.6479H448.025V73.8052H438.044V69.6895C437.144 70.7648 436.095 71.6509 434.897 72.3477C432.662 73.6727 429.96 74.3352 426.79 74.3352ZM428.6 65.8552C430.296 65.8552 431.835 65.4577 433.221 64.6627C434.606 63.8677 435.698 62.7414 436.502 61.2839C437.352 59.7824 437.776 58.0157 437.776 55.9839C437.776 53.9082 437.352 52.1414 436.502 50.6842C435.698 49.2267 434.606 48.1004 433.221 47.3054C431.835 46.5104 430.296 46.1129 428.6 46.1129C426.858 46.1129 425.293 46.5104 423.91 47.3054C422.525 48.1004 421.407 49.2267 420.56 50.6842C419.757 52.1414 419.355 53.9082 419.355 55.9839C419.355 58.0157 419.757 59.7824 420.56 61.2839C421.407 62.7414 422.525 63.8677 423.91 64.6627C425.293 65.4577 426.858 65.8552 428.6 65.8552Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M464.733 71.9501C467.86 73.5398 471.478 74.3348 475.586 74.3348C478.847 74.3348 481.726 73.8491 484.229 72.8773C486.729 71.8616 488.805 70.4263 490.458 68.5713L484.899 62.6088C483.693 63.7571 482.353 64.6183 480.879 65.1926C479.448 65.7666 477.775 66.0538 475.854 66.0538C473.71 66.0538 471.834 65.6783 470.226 64.9276C468.664 64.1326 467.435 63.0063 466.543 61.5488C466.08 60.731 465.744 59.8476 465.533 58.8988H492.804L492.823 58.7017C492.86 58.3196 492.899 57.9216 492.938 57.5076C492.981 56.9776 493.004 56.5138 493.004 56.1163C493.004 52.2738 492.177 48.9833 490.526 46.2451C488.873 43.4626 486.618 41.3426 483.759 39.8851C480.945 38.3833 477.775 37.6326 474.246 37.6326C470.583 37.6326 467.301 38.4276 464.399 40.0176C461.494 41.5633 459.194 43.7276 457.497 46.5101C455.844 49.2483 455.02 52.4063 455.02 55.9838C455.02 59.5171 455.867 62.6751 457.566 65.4576C459.262 68.1958 461.651 70.3601 464.733 71.9501ZM465.412 52.8701C465.586 51.7659 465.918 50.7722 466.409 49.8888C467.167 48.4753 468.216 47.3933 469.556 46.6426C470.942 45.8476 472.527 45.4501 474.314 45.4501C476.099 45.4501 477.664 45.8476 479.004 46.6426C480.343 47.3933 481.392 48.4533 482.151 49.8226C482.654 50.7313 482.992 51.7472 483.162 52.8701H465.412Z" fill="black"/>
<path d="M508.291 55.828L494.425 73.8058H505.814L514 62.8882L521.892 73.8058H533.751L519.808 55.5938L533.215 38.1636H522.094L514.264 48.573L506.618 38.1636H494.895L508.291 55.828Z" fill="black"/>
<path d="M394.277 39.3551C392.044 38.2066 389.499 37.6326 386.639 37.6326C383.558 37.6326 380.812 38.2728 378.4 39.5538C376.978 40.3095 375.749 41.2574 374.715 42.3975V38.1626H364.734V73.8048H375.185V56.1826C375.185 53.9741 375.541 52.1633 376.257 50.7501C377.015 49.3366 378.041 48.2988 379.338 47.6363C380.678 46.9296 382.175 46.5763 383.826 46.5763C386.149 46.5763 387.936 47.2608 389.185 48.6301C390.482 49.9991 391.129 52.1191 391.129 54.9901V73.8048H401.58V53.4001C401.58 49.7783 400.933 46.8191 399.636 44.5226C398.342 42.1816 396.554 40.4591 394.277 39.3551Z" fill="black"/>
<path d="M343.488 73.8049V27.4299H354.341V73.8049H343.488Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M323.512 69.3766V73.8048H333.293V53.4663C333.293 48.0338 331.773 44.0366 328.737 41.4751C325.701 38.9133 321.436 37.6326 315.943 37.6326C313.083 37.6326 310.27 38.0078 307.501 38.7588C304.731 39.5096 302.364 40.5696 300.4 41.9388L304.152 49.1601C305.446 48.1441 307.008 47.3491 308.841 46.7751C310.717 46.1566 312.613 45.8476 314.534 45.8476C317.348 45.8476 319.426 46.4658 320.766 47.7026C322.149 48.9391 322.842 50.6616 322.842 52.8701H314.534C310.871 52.8701 307.903 53.3338 305.626 54.2613C303.348 55.1446 301.672 56.3813 300.6 57.9713C299.574 59.5613 299.06 61.4163 299.06 63.5363C299.06 65.5678 299.596 67.4008 300.668 69.0351C301.74 70.6691 303.28 71.9721 305.289 72.9436C307.299 73.8711 309.711 74.3348 312.525 74.3348C315.695 74.3348 318.286 73.7388 320.296 72.5463C321.653 71.7413 322.725 70.6847 323.512 69.3766ZM322.842 58.8988H315.675C313.217 58.8988 311.521 59.2963 310.583 60.0913C309.688 60.8863 309.243 61.8801 309.243 63.0726C309.243 64.3976 309.757 65.4576 310.783 66.2526C311.855 67.0033 313.306 67.3788 315.139 67.3788C316.881 67.3788 318.443 66.9813 319.828 66.1863C321.211 65.3471 322.217 64.1326 322.842 62.5426V58.8988Z" fill="black"/>
<path d="M277.299 37.6326C280.155 37.6326 282.678 38.2066 284.868 39.3551C287.1 40.4591 288.842 42.1816 290.093 44.5226C291.387 46.8191 292.037 49.7783 292.037 53.4001V73.8048H281.586V54.9901C281.586 52.1191 280.982 49.9991 279.776 48.6301C278.57 47.2608 276.874 46.5763 274.685 46.5763C273.165 46.5763 271.805 46.9296 270.599 47.6363C269.393 48.2988 268.456 49.3146 267.786 50.6838C267.116 52.0528 266.779 53.7976 266.779 55.9176V73.8048H256.329V54.9901C256.329 52.1191 255.727 49.9991 254.521 48.6301C253.358 47.2608 251.684 46.5763 249.495 46.5763C247.976 46.5763 246.616 46.9296 245.409 47.6363C244.203 48.2988 243.265 49.3146 242.595 50.6838C241.925 52.0528 241.591 53.7976 241.591 55.9176V73.8048H231.14V38.1626H241.122V42.2748C242.091 41.1711 243.23 40.264 244.538 39.5538C246.861 38.2728 249.495 37.6326 252.443 37.6326C255.747 37.6326 258.629 38.4716 261.086 40.1501C262.393 41.004 263.468 42.0992 264.312 43.4357C265.349 42.132 266.619 41.0147 268.119 40.0838C270.799 38.4496 273.858 37.6326 277.299 37.6326Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M211.9 69.376V73.8048H221.681V53.4663C221.681 48.0338 220.163 44.0366 217.126 41.4751C214.089 38.9133 209.824 37.6326 204.33 37.6326C201.472 37.6326 198.658 38.0078 195.889 38.7588C193.12 39.5096 190.753 40.5696 188.788 41.9388L192.539 49.1601C193.835 48.1441 195.398 47.3491 197.229 46.7751C199.105 46.1566 201.003 45.8476 202.923 45.8476C205.737 45.8476 207.814 46.4658 209.154 47.7026C210.538 48.9391 211.23 50.6616 211.23 52.8701H202.923C199.261 52.8701 196.291 53.3338 194.013 54.2613C191.736 55.1446 190.061 56.3813 188.989 57.9713C187.962 59.5613 187.448 61.4163 187.448 63.5363C187.448 65.5678 187.984 67.4008 189.056 69.0351C190.128 70.6691 191.669 71.9721 193.678 72.9436C195.688 73.8711 198.1 74.3348 200.914 74.3348C204.085 74.3348 206.675 73.7388 208.685 72.5463C210.042 71.7412 211.114 70.6844 211.9 69.376ZM211.23 58.8988H204.062C201.606 58.8988 199.909 59.2963 198.971 60.0913C198.078 60.8863 197.631 61.8801 197.631 63.0726C197.631 64.3976 198.145 65.4576 199.172 66.2526C200.244 67.0033 201.695 67.3788 203.526 67.3788C205.268 67.3788 206.831 66.9813 208.216 66.1863C209.6 65.3471 210.605 64.1326 211.23 62.5426V58.8988Z" fill="black"/>
<path d="M129.883 27.4299V73.8049H164.25V65.0599H140.735V27.4299H129.883Z" fill="black"/>
<defs>
<linearGradient id="paint0_linear_3021_4359" x1="26.4432" y1="19.2646" x2="89.8582" y2="72.4099" gradientUnits="userSpaceOnUse">
<stop offset="0.0619804" stop-color="#F6DCD9"/>
<stop offset="0.325677" stop-color="#FFA5EA"/>
<stop offset="0.589257" stop-color="#45DFF8"/>
<stop offset="1" stop-color="#BC8DEB"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 9.6 KiB

-22
View File
@@ -1,22 +0,0 @@
<svg width="543" height="100" viewBox="0 0 543 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 20C0 8.9543 8.96156 0 20.0162 0H80.0648C91.1194 0 100.081 8.95431 100.081 20V80C100.081 91.0457 91.1194 100 80.0648 100H20.0162C8.96155 100 0 91.0457 0 80V20Z" fill="black"/>
<path d="M62.8864 65.775C56.444 68.619 49.4648 67.4537 46.7804 66.5156C46.7804 67.1575 46.7512 69.1522 46.634 71.9961C46.5169 74.8401 45.6091 76.6373 45.1699 77.1804C45.2187 78.9579 45.2577 82.8387 45.0234 84.1422C44.7892 85.4456 43.9497 86.5615 43.5593 86.9565H39.606C39.9574 85.179 41.3142 84.0434 41.9487 83.6978C42.3001 80.0244 41.607 76.8348 41.2166 75.6992C40.8261 77.0817 39.8695 80.291 39.1667 82.0685C38.4639 83.8459 37.4097 85.4753 36.9704 86.0678H34.0421C33.8957 84.2903 34.8718 83.6978 35.5063 83.6978C35.7991 83.1547 36.5019 81.4464 36.9704 78.9579C37.439 76.4694 36.7752 71.7986 36.3848 69.7743V63.405C31.6994 60.887 29.9424 58.3689 28.771 55.5546C27.8339 53.3031 28.0877 49.8765 28.3318 48.4447C28.0389 47.9016 27.1852 46.5212 26.8676 44.5935C26.4283 41.9273 26.6724 40.0017 26.8676 38.9649C26.5747 38.6686 25.9891 37.1578 25.9891 33.4843C25.9891 29.8109 27.0628 27.9051 27.5996 27.4113V25.782C25.5498 25.6339 23.4999 24.7451 22.3286 23.5601C21.1572 22.3752 22.0358 20.5977 22.7678 20.0052C23.4999 19.4127 24.232 19.8571 25.257 19.5608C26.2819 19.2646 27.1604 18.9683 27.5996 18.0796C27.951 17.3686 27.258 14.4259 26.8676 13.0435C28.6246 13.2805 29.7471 14.8209 30.0888 15.5615V13.0435C32.285 14.0803 36.2383 16.5984 37.5561 22.0789C38.6103 26.4633 39.3619 35.6568 39.6059 39.7055C45.2186 39.7549 52.3443 38.9013 58.7867 40.298C64.6434 41.5677 67.279 44.1492 70.3538 44.1492C73.4285 44.1492 75.1856 42.3717 77.3818 43.8529C79.5781 45.3341 80.7495 49.4816 80.4566 52.5921C80.2224 55.0806 78.3092 55.9002 77.3818 55.999C76.2105 59.9094 77.3818 63.6519 78.1139 65.0344V70.6631C78.4556 71.1568 79.1389 72.6775 79.1389 74.8105C79.1389 76.9435 78.4556 78.3654 78.1139 78.8098C78.6996 82.1277 77.8699 85.5247 77.3818 86.8084H73.4285C73.8971 85.6234 74.6975 85.3272 75.0391 85.3272C75.742 81.6537 75.2344 78.2667 74.8927 77.0323C72.6672 75.7288 71.2323 73.428 70.793 72.4405C70.8418 73.2799 70.7052 75.6104 69.7681 78.2173C68.831 80.8243 67.4254 82.3647 66.8397 82.8091V85.9197H62.8864C62.8864 84.0237 63.9602 83.6485 64.497 83.6978C65.1803 82.4635 66.8397 80.5873 66.8397 76.8842C66.8397 73.7596 64.6435 72.2924 63.0329 69.4781C62.2676 68.141 62.6424 66.4663 62.8864 65.775Z" fill="url(#paint0_linear_3054_4082)"/>
<path d="M169.643 73.8052V24.6479H180.094V73.8052H169.643Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M426.79 74.3352C423.394 74.3352 420.335 73.5844 417.613 72.0827C414.888 70.5369 412.721 68.3949 411.113 65.6564C409.551 62.9182 408.77 59.6939 408.77 55.9839C408.77 52.2299 409.551 48.9837 411.113 46.2454C412.721 43.5069 414.888 41.3869 417.613 39.8854C420.335 38.3837 423.394 37.6329 426.79 37.6329C429.826 37.6329 432.485 38.2954 434.763 39.6204C435.808 40.2289 436.745 40.9817 437.574 41.8789V24.6479H448.025V73.8052H438.044V69.6895C437.144 70.7648 436.095 71.6509 434.897 72.3477C432.662 73.6727 429.96 74.3352 426.79 74.3352ZM428.6 65.8552C430.296 65.8552 431.835 65.4577 433.221 64.6627C434.606 63.8677 435.698 62.7414 436.502 61.2839C437.352 59.7824 437.776 58.0157 437.776 55.9839C437.776 53.9082 437.352 52.1414 436.502 50.6842C435.698 49.2267 434.606 48.1004 433.221 47.3054C431.835 46.5104 430.296 46.1129 428.6 46.1129C426.858 46.1129 425.293 46.5104 423.91 47.3054C422.525 48.1004 421.407 49.2267 420.56 50.6842C419.757 52.1414 419.355 53.9082 419.355 55.9839C419.355 58.0157 419.757 59.7824 420.56 61.2839C421.407 62.7414 422.525 63.8677 423.91 64.6627C425.293 65.4577 426.858 65.8552 428.6 65.8552Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M464.733 71.9501C467.86 73.5398 471.478 74.3348 475.586 74.3348C478.847 74.3348 481.726 73.8491 484.229 72.8773C486.729 71.8616 488.805 70.4263 490.458 68.5713L484.899 62.6088C483.693 63.7571 482.353 64.6183 480.879 65.1926C479.448 65.7666 477.775 66.0538 475.854 66.0538C473.71 66.0538 471.834 65.6783 470.226 64.9276C468.664 64.1326 467.435 63.0063 466.543 61.5488C466.08 60.731 465.744 59.8476 465.533 58.8988H492.804L492.823 58.7017C492.86 58.3196 492.899 57.9216 492.938 57.5076C492.981 56.9776 493.004 56.5138 493.004 56.1163C493.004 52.2738 492.177 48.9833 490.526 46.2451C488.873 43.4626 486.618 41.3426 483.759 39.8851C480.945 38.3833 477.775 37.6326 474.246 37.6326C470.583 37.6326 467.301 38.4276 464.399 40.0176C461.494 41.5633 459.194 43.7276 457.497 46.5101C455.844 49.2483 455.02 52.4063 455.02 55.9838C455.02 59.5171 455.867 62.6751 457.566 65.4576C459.262 68.1958 461.651 70.3601 464.733 71.9501ZM465.412 52.8701C465.586 51.7659 465.918 50.7722 466.409 49.8888C467.167 48.4753 468.216 47.3933 469.556 46.6426C470.942 45.8476 472.527 45.4501 474.314 45.4501C476.099 45.4501 477.664 45.8476 479.004 46.6426C480.343 47.3933 481.392 48.4533 482.151 49.8226C482.654 50.7313 482.992 51.7472 483.162 52.8701H465.412Z" fill="white"/>
<path d="M508.291 55.828L494.425 73.8058H505.814L514 62.8882L521.892 73.8058H533.751L519.808 55.5938L533.215 38.1636H522.094L514.264 48.573L506.618 38.1636H494.895L508.291 55.828Z" fill="white"/>
<path d="M394.277 39.3551C392.044 38.2066 389.499 37.6326 386.639 37.6326C383.558 37.6326 380.812 38.2728 378.4 39.5538C376.978 40.3095 375.749 41.2574 374.715 42.3975V38.1626H364.734V73.8048H375.185V56.1826C375.185 53.9741 375.541 52.1633 376.257 50.7501C377.015 49.3366 378.041 48.2988 379.338 47.6363C380.678 46.9296 382.175 46.5763 383.826 46.5763C386.149 46.5763 387.936 47.2608 389.185 48.6301C390.482 49.9991 391.129 52.1191 391.129 54.9901V73.8048H401.58V53.4001C401.58 49.7783 400.933 46.8191 399.636 44.5226C398.342 42.1816 396.554 40.4591 394.277 39.3551Z" fill="white"/>
<path d="M343.488 73.8049V27.4299H354.341V73.8049H343.488Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M323.512 69.3766V73.8048H333.293V53.4663C333.293 48.0338 331.773 44.0366 328.737 41.4751C325.701 38.9133 321.436 37.6326 315.943 37.6326C313.083 37.6326 310.27 38.0078 307.501 38.7588C304.731 39.5096 302.364 40.5696 300.4 41.9388L304.152 49.1601C305.446 48.1441 307.008 47.3491 308.841 46.7751C310.717 46.1566 312.613 45.8476 314.534 45.8476C317.348 45.8476 319.426 46.4658 320.766 47.7026C322.149 48.9391 322.842 50.6616 322.842 52.8701H314.534C310.871 52.8701 307.903 53.3338 305.626 54.2613C303.348 55.1446 301.672 56.3813 300.6 57.9713C299.574 59.5613 299.06 61.4163 299.06 63.5363C299.06 65.5678 299.596 67.4008 300.668 69.0351C301.74 70.6691 303.28 71.9721 305.289 72.9436C307.299 73.8711 309.711 74.3348 312.525 74.3348C315.695 74.3348 318.286 73.7388 320.296 72.5463C321.653 71.7413 322.725 70.6847 323.512 69.3766ZM322.842 58.8988H315.675C313.217 58.8988 311.521 59.2963 310.583 60.0913C309.688 60.8863 309.243 61.8801 309.243 63.0726C309.243 64.3976 309.756 65.4576 310.783 66.2526C311.855 67.0033 313.306 67.3788 315.139 67.3788C316.881 67.3788 318.443 66.9813 319.828 66.1863C321.211 65.3471 322.217 64.1326 322.842 62.5426V58.8988Z" fill="white"/>
<path d="M277.299 37.6326C280.155 37.6326 282.678 38.2066 284.868 39.3551C287.1 40.4591 288.842 42.1816 290.093 44.5226C291.387 46.8191 292.037 49.7783 292.037 53.4001V73.8048H281.586V54.9901C281.586 52.1191 280.982 49.9991 279.776 48.6301C278.57 47.2608 276.874 46.5763 274.685 46.5763C273.165 46.5763 271.805 46.9296 270.599 47.6363C269.393 48.2988 268.456 49.3146 267.786 50.6838C267.116 52.0528 266.779 53.7976 266.779 55.9176V73.8048H256.329V54.9901C256.329 52.1191 255.727 49.9991 254.521 48.6301C253.358 47.2608 251.684 46.5763 249.495 46.5763C247.976 46.5763 246.616 46.9296 245.409 47.6363C244.203 48.2988 243.265 49.3146 242.595 50.6838C241.925 52.0528 241.591 53.7976 241.591 55.9176V73.8048H231.14V38.1626H241.122V42.2748C242.091 41.1711 243.23 40.264 244.538 39.5538C246.861 38.2728 249.495 37.6326 252.443 37.6326C255.747 37.6326 258.629 38.4716 261.086 40.1501C262.393 41.004 263.468 42.0992 264.312 43.4357C265.349 42.132 266.619 41.0147 268.119 40.0838C270.799 38.4496 273.858 37.6326 277.299 37.6326Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M211.9 69.376V73.8048H221.681V53.4663C221.681 48.0338 220.163 44.0366 217.126 41.4751C214.089 38.9133 209.824 37.6326 204.33 37.6326C201.472 37.6326 198.658 38.0078 195.889 38.7588C193.12 39.5096 190.753 40.5696 188.788 41.9388L192.539 49.1601C193.835 48.1441 195.398 47.3491 197.229 46.7751C199.105 46.1566 201.003 45.8476 202.923 45.8476C205.737 45.8476 207.814 46.4658 209.154 47.7026C210.538 48.9391 211.23 50.6616 211.23 52.8701H202.923C199.261 52.8701 196.291 53.3338 194.013 54.2613C191.736 55.1446 190.061 56.3813 188.989 57.9713C187.962 59.5613 187.448 61.4163 187.448 63.5363C187.448 65.5678 187.984 67.4008 189.056 69.0351C190.128 70.6691 191.669 71.9721 193.678 72.9436C195.688 73.8711 198.1 74.3348 200.914 74.3348C204.085 74.3348 206.675 73.7388 208.685 72.5463C210.042 71.7412 211.114 70.6844 211.9 69.376ZM211.23 58.8988H204.062C201.606 58.8988 199.909 59.2963 198.971 60.0913C198.078 60.8863 197.631 61.8801 197.631 63.0726C197.631 64.3976 198.145 65.4576 199.172 66.2526C200.244 67.0033 201.695 67.3788 203.526 67.3788C205.268 67.3788 206.831 66.9813 208.216 66.1863C209.6 65.3471 210.605 64.1326 211.23 62.5426V58.8988Z" fill="white"/>
<path d="M129.883 27.4299V73.8049H164.25V65.0599H140.735V27.4299H129.883Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_3054_4082" x1="26.4432" y1="19.2646" x2="89.8582" y2="72.4099" gradientUnits="userSpaceOnUse">
<stop offset="0.0619804" stop-color="#F6DCD9"/>
<stop offset="0.325677" stop-color="#FFA5EA"/>
<stop offset="0.589257" stop-color="#45DFF8"/>
<stop offset="1" stop-color="#BC8DEB"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

-97
View File
@@ -1,97 +0,0 @@
---
import config from 'virtual:starlight/user-config';
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import Search from 'virtual:starlight/components/Search';
import SiteTitle from 'virtual:starlight/components/SiteTitle';
import SocialIcons from 'virtual:starlight/components/SocialIcons';
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
/**
* Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
*/
const shouldRenderSearch =
config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
---
<div class="header">
<div class="title-wrapper sl-flex">
<SiteTitle />
</div>
<div class="sl-flex print:hidden">
{shouldRenderSearch && <Search />}
</div>
<div class="sl-hidden md:sl-flex print:hidden right-group">
<div class="sl-flex">
<a href="/python/framework/">Python</a>
</div>
<div class="sl-flex social-icons">
<SocialIcons />
</div>
<ThemeSelect />
<LanguageSelect />
</div>
</div>
<style>
@layer starlight.core {
.header {
display: flex;
gap: var(--sl-nav-gap);
justify-content: space-between;
align-items: center;
height: 100%;
}
.title-wrapper {
/* Prevent long titles overflowing and covering the search and menu buttons on narrow viewports. */
overflow: clip;
/* Avoid clipping focus ring around link inside title wrapper. */
padding: 0.25rem;
margin: -0.25rem;
min-width: 0;
}
.right-group,
.social-icons {
gap: 1rem;
align-items: center;
}
.social-icons::after {
content: '';
height: 2rem;
border-inline-end: 1px solid var(--sl-color-gray-5);
}
@media (min-width: 50rem) {
:global(:root[data-has-sidebar]) {
--__sidebar-pad: calc(2 * var(--sl-nav-pad-x));
}
:global(:root:not([data-has-toc])) {
--__toc-width: 0rem;
}
.header {
--__sidebar-width: max(0rem, var(--sl-content-inline-start, 0rem) - var(--sl-nav-pad-x));
--__main-column-fr: calc(
(
100% + var(--__sidebar-pad, 0rem) - var(--__toc-width, var(--sl-sidebar-width)) -
(2 * var(--__toc-width, var(--sl-nav-pad-x))) - var(--sl-content-inline-start, 0rem) -
var(--sl-content-width)
) / 2
);
display: grid;
grid-template-columns:
/* 1 (site title): runs up until the main content columns left edge or the width of the title, whichever is the largest */
minmax(
calc(var(--__sidebar-width) + max(0rem, var(--__main-column-fr) - var(--sl-nav-gap))),
auto
)
/* 2 (search box): all free space that is available. */
1fr
/* 3 (right items): use the space that these need. */
auto;
align-content: center;
}
}
}
</style>
@@ -1,64 +0,0 @@
import Heading from "@theme/Heading";
import clsx from "clsx";
import styles from "./styles.module.css";
const FeatureList = [
{
title: "Easy to Use",
Svg: require("@site/static/img/undraw_docusaurus_mountain.svg").default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: "Focus on What Matters",
Svg: require("@site/static/img/undraw_docusaurus_tree.svg").default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: "Powered by React",
Svg: require("@site/static/img/undraw_docusaurus_react.svg").default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({ Svg, title, description }) {
return (
<div className={clsx("col col--4")}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}
@@ -1,11 +0,0 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}
-148
View File
@@ -1,148 +0,0 @@
import { useEffect, useState } from "react";
const SELF_HOSTING_PASSWORD = "llamacloud-self-host-2025";
const STORAGE_KEY = "llamacloud-self-hosting-auth";
export default function ProtectedContent({ children }) {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Check if user is already authenticated
const savedAuth = localStorage.getItem(STORAGE_KEY);
if (savedAuth === "true") {
setIsAuthenticated(true);
}
setIsLoading(false);
}, []);
const handleSubmit = (e) => {
e.preventDefault();
if (password === SELF_HOSTING_PASSWORD) {
setIsAuthenticated(true);
localStorage.setItem(STORAGE_KEY, "true");
setError("");
} else {
setError("Incorrect password. Please try again.");
setPassword("");
}
};
const handleLogout = () => {
setIsAuthenticated(false);
localStorage.removeItem(STORAGE_KEY);
setPassword("");
};
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return (
<div
style={{
maxWidth: "400px",
margin: "2rem auto",
padding: "2rem",
border: "1px solid #e0e0e0",
borderRadius: "8px",
backgroundColor: "#f9f9f9",
}}
>
<h2 style={{ textAlign: "center", marginBottom: "1.5rem" }}>
Self-Hosting Documentation Access
</h2>
<p
style={{ textAlign: "center", marginBottom: "1.5rem", color: "#666" }}
>
This section requires a password to access. Interested in
self-hosting?{" "}
<a href="https://www.llamaindex.ai/contact">Contact sales</a> to learn
more.
</p>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: "1rem" }}>
<label
htmlFor="password"
style={{ display: "block", marginBottom: "0.5rem" }}
>
Password:
</label>
<input
type="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
style={{
width: "100%",
padding: "0.5rem",
border: "1px solid #ccc",
borderRadius: "4px",
fontSize: "1rem",
}}
required
/>
</div>
{error && (
<p
style={{ color: "red", fontSize: "0.9rem", marginBottom: "1rem" }}
>
{error}
</p>
)}
<button
type="submit"
style={{
width: "100%",
padding: "0.75rem",
backgroundColor: "#007cba",
color: "white",
border: "none",
borderRadius: "4px",
fontSize: "1rem",
cursor: "pointer",
}}
>
Access Documentation
</button>
</form>
</div>
);
}
return (
<div>
<div
style={{
textAlign: "right",
marginBottom: "1rem",
padding: "0.5rem",
backgroundColor: "#f0f0f0",
borderRadius: "4px",
}}
>
<small style={{ marginRight: "1rem", color: "#666" }}>
Self-Hosting Documentation Access Granted
</small>
<button
onClick={handleLogout}
style={{
padding: "0.25rem 0.5rem",
backgroundColor: "#dc3545",
color: "white",
border: "none",
borderRadius: "3px",
fontSize: "0.8rem",
cursor: "pointer",
}}
>
Logout
</button>
</div>
{children}
</div>
);
}
-59
View File
@@ -1,59 +0,0 @@
---
import { logos } from 'virtual:starlight/user-images';
import config from 'virtual:starlight/user-config';
const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute;
---
<a href="/" class="site-title sl-flex">
{
config.logo && logos.dark && (
<>
<img
class:list={{ 'light:sl-hidden print:hidden': !('src' in config.logo) }}
alt={config.logo.alt}
src={logos.dark.src}
width={logos.dark.width}
height={logos.dark.height}
/>
{/* Show light alternate if a user configure both light and dark logos. */}
{!('src' in config.logo) && (
<img
class="dark:sl-hidden print:block"
alt={config.logo.alt}
src={logos.light?.src}
width={logos.light?.width}
height={logos.light?.height}
/>
)}
</>
)
}
<span class:list={{ 'sr-only': config.logo?.replacesTitle }} translate="no">
{siteTitle}
</span>
</a>
<style>
@layer starlight.core {
.site-title {
align-items: center;
gap: var(--sl-nav-gap);
font-size: var(--sl-text-h4);
font-weight: 600;
color: var(--sl-color-text-accent);
text-decoration: none;
white-space: nowrap;
min-width: 0;
}
span {
overflow: hidden;
}
img {
height: calc(var(--sl-nav-height) - 2 * var(--sl-nav-pad-y));
width: auto;
max-width: 100%;
object-fit: contain;
object-position: 0 50%;
}
}
</style>
-71
View File
@@ -1,71 +0,0 @@
export const LEPython = ({ children }) => (
<>
<span>
<small>In Python:</small>
</span>
<pre>
extractor = LlamaExtract(
<br />
&nbsp;&nbsp;{children}
<br />)
</pre>
</>
);
export const LEAPI = ({
children,
endpoint = "",
isUpload = false,
outputFile = false,
}) => {
if (!endpoint) endpoint = "parsing/upload";
let outputLine = <></>;
if (outputFile)
outputLine = (
<>
&nbsp;\
<br />
&nbsp;&nbsp;--output "file.png"
</>
);
let uploadLine = <></>;
if (isUpload)
uploadLine = (
<>
&nbsp;\
<br />
&nbsp;&nbsp;-F 'file=@/path/to/your/file.pdf;type=application/pdf'
</>
);
let paramList = <></>;
if (typeof children == "string") {
let entries = children.split("|");
paramList = entries.map((line) => {
return (
<>
&nbsp;\
<br />
&nbsp;&nbsp;--form '{line}'
</>
);
});
}
return (
<>
<span>
<small>Using the API:</small>
</span>
<pre>
curl -X 'POST' \<br />
&nbsp;&nbsp;'https://api.cloud.llamaindex.ai/api/{endpoint}' &nbsp;\
<br />
&nbsp;&nbsp;-H 'accept: application/json' \<br />
&nbsp;&nbsp;-H 'Content-Type: multipart/form-data' \<br />
&nbsp;&nbsp;-H "Authorization: Bearer $LLAMA_CLOUD_API_KEY"
{paramList}
{uploadLine}
{outputLine}
</pre>
</>
);
};
-93
View File
@@ -1,93 +0,0 @@
import React from "react";
export const LPPython = ({ children }) => (
<>
<span>
<small>In Python:</small>
</span>
<pre>
parser = LlamaParse(
<br />
&nbsp;&nbsp;{children}
<br />)
</pre>
</>
);
export const LPAPI = ({
children,
endpoint = "",
isUpload = false,
outputFile = false,
}) => {
if (!endpoint) endpoint = "upload";
let outputLine = <></>;
if (outputFile)
outputLine = (
<>
&nbsp;\
<br />
&nbsp;&nbsp;--output "file.png"
</>
);
let uploadLine = <></>;
if (isUpload)
uploadLine = (
<>
&nbsp;\
<br />
&nbsp;&nbsp;-F 'file=@/path/to/your/file.pdf;type=application/pdf'
</>
);
let paramList = <></>;
if (typeof children !== "undefined") {
// Get the raw text content of children
let rawContent = "";
if (typeof children === "string") {
rawContent = children;
} else {
// For React elements, get their text content
// this is because React interprets key-value pairs with URLs as prop values
rawContent = React.Children.toArray(children)
.map((child) => {
if (typeof child === "string") return child;
if (React.isValidElement(child)) return child.props.children || "";
return "";
})
.join("");
}
// Split by | if multiple parameters
const entries = rawContent.split("|");
paramList = entries.map((line) => {
return (
<>
&nbsp;\
<br />
&nbsp;&nbsp;--form '{line.trim()}'
</>
);
});
}
return (
<>
<span>
<small>Using the API:</small>
</span>
<pre>
curl -X 'POST' \<br />
&nbsp;&nbsp;'https://api.cloud.llamaindex.ai/api/v1/parsing/{endpoint}'
&nbsp;\
<br />
&nbsp;&nbsp;-H 'accept: application/json' \<br />
&nbsp;&nbsp;-H 'Content-Type: multipart/form-data' \<br />
&nbsp;&nbsp;-H "Authorization: Bearer $LLAMA_CLOUD_API_KEY"
{paramList}
{uploadLine}
{outputLine}
</pre>
</>
);
};
-33
View File
@@ -1,33 +0,0 @@
import TabItem from "@theme/TabItem";
import Tabs from "@theme/Tabs";
import { Children, cloneElement } from "react";
export const StyledTitle = ({ title, subtitle }) => {
return (
<div style={{ marginBottom: "1rem" }}>
<h3 style={{ marginBottom: "0.25rem" }}>{title}</h3>
{subtitle && (
<span style={{ fontSize: "0.875rem", opacity: 0.6 }}>{subtitle}</span>
)}
</div>
);
};
export const StyledTab = ({ children }) => {
return (
<Tabs>
{Children.map(children, (child) => {
if (child.type !== TabItem) return child;
return cloneElement(child, {
children: (
<div style={{ fontSize: "0.875rem" }}>{child.props.children}</div>
),
});
})}
</Tabs>
);
};
export const ImageSizer = ({ children, width = "350px" }) => {
return <div style={{ width, margin: "0" }}>{children}</div>;
};
-13
View File
@@ -1,13 +0,0 @@
import { docsLoader } from "@astrojs/starlight/loaders";
import { docsSchema } from "@astrojs/starlight/schema";
import { defineCollection } from "astro:content";
import { autoSidebarLoader } from "starlight-auto-sidebar/loader";
import { autoSidebarSchema } from "starlight-auto-sidebar/schema";
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
autoSidebar: defineCollection({
loader: autoSidebarLoader(),
schema: autoSidebarSchema(),
}),
};
@@ -1,2 +0,0 @@
label: Getting Started
collapsed: true
@@ -1,60 +0,0 @@
---
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](/typescript/framework/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](/typescript/framework/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](/typescript/framework/tutorials/rag).
## Use cases
There are endless use cases for data-backed LLM applications but they can be roughly grouped into four categories:
[**Agents**](/typescript/framework/tutorials/basic_agent):
An agent is an automated decision-maker powered by an LLM that interacts with the world via a set of [tools](/typescript/framework/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**](/typescript/framework/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**](/typescript/framework/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**](/typescript/framework/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**](/typescript/framework/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).
@@ -1,26 +0,0 @@
---
title: Create-Llama
---
`create-llama` is a powerful but easy to use command-line tool that generates a working, full-stack web application that allows you to chat with your data. You can learn more about it on [the `create-llama` README page](https://www.npmjs.com/package/create-llama).
Run it once and it will ask you a series of questions about the kind of application you want to generate. Then you can customize your application to suit your use-case. To get started, run:
```bash npm2yarn
npx create-llama@latest
```
Once your app is generated, `cd` into your app directory and run
```bash npm2yarn
npm run dev
```
to start the development server. You can then visit [http://localhost:3000](http://localhost:3000) to see your app, which should look something like this:
![create-llama interface](/images/create_llama.png)
## Learn more
- [Learn more about `create-llama`](https://github.com/run-llama/create-llama)
- [Want to use the same UI components? You can use our React components](https://ui.llamaindex.ai/)
@@ -1,33 +0,0 @@
---
title: Code examples
---
Our GitHub repository has a wealth of examples to explore and try out. You can check out our [examples folder](https://github.com/run-llama/LlamaIndexTS/tree/main/examples) to see them all at once, or browse the pages in this section for some selected highlights.
## Use examples locally
It may be useful to check out all the examples at once so you can try them out locally. To do this into a folder called `my-new-project`, run these commands:
```bash npm2yarn
npx degit run-llama/LlamaIndexTS/examples my-new-project
cd my-new-project
npm i
```
Then you can run any example in the folder with `tsx`, e.g.:
```bash npm2yarn
export OPENAI_API_KEY=your-api-key
npx tsx ./agents/agent/openai.ts
```
## Try examples online
You can also try the examples online using StackBlitz:
<iframe
className="w-full h-[440px]"
aria-label="LlamaIndex.TS Examples"
aria-description="This is a list of examples for LlamaIndex.TS."
src="https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples?file=README.md"
/>
@@ -1,2 +0,0 @@
label: Installation
collapsed: true
@@ -1,177 +0,0 @@
---
title: Installation
description: How to install and set up LlamaIndex.TS for your project.
---
## Quick Start
Install the core package:
```package-install
npm i llamaindex
```
In most cases, you'll also need an LLM provider and the Workflow package:
```package-install
npm i @llamaindex/openai @llamaindex/workflow
```
## Environment Setup
### API Keys
Most LLM providers require API keys. Set your OpenAI key (or other provider):
```bash
export OPENAI_API_KEY=your-api-key
```
Or use a `.env` file:
```bash
echo "OPENAI_API_KEY=your-api-key" > .env
```
<Aside type="caution">Never commit API keys to your repository.</Aside>
### Loading Environment Variables
For Node.js applications:
```bash
node --env-file .env your-script.js
```
For other environments, see the deployment-specific guides below.
## TypeScript Configuration
LlamaIndex.TS is built with TypeScript and provides excellent type safety. Add these settings to your `tsconfig.json`:
```json5
{
"compilerOptions": {
// Essential for module resolution
"moduleResolution": "bundler", // or "nodenext" | "node16" | "node"
// Required for Web Stream API support
"lib": ["DOM.AsyncIterable"],
// Recommended for better compatibility
"target": "es2020",
"module": "esnext"
}
}
```
## Running your first agent
### Set up
If you don't already have a project, you can create a new one in a new folder:
```package-install
npm init
npm i -D typescript @types/node
npm i @llamaindex/openai @llamaindex/workflow llamaindex zod
```
### Run the agent
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/agents/agent/openai.ts</include>
To run the code:
```package-install
npx tsx example.ts
```
You should expect output something like:
```
{
result: '5 + 5 is 10. Then, 10 divided by 2 is 5.',
state: {
memory: Memory {
messages: [Array],
tokenLimit: 30000,
shortTermTokenLimitRatio: 0.7,
memoryBlocks: [],
memoryCursor: 0,
adapters: [Object]
},
scratchpad: [],
currentAgentName: 'Agent',
agents: [ 'Agent' ],
nextAgentName: null
}
}
Done
```
## Performance Optimization
### Tokenization Speed
Install `gpt-tokenizer` for 60x faster tokenization (Node.js environments only):
```package-install
npm i gpt-tokenizer
```
LlamaIndex will automatically use this when available.
## Deployment Guides
Choose your deployment target:
<CardGrid>
<Card
title="Server APIs & Backends"
description="Express, Fastify, Koa, standalone Node.js servers"
href="/typescript/framework/getting_started/installation/server-apis"
/>
<Card
title="Serverless Functions"
description="Vercel, Netlify, AWS Lambda, Cloudflare Workers"
href="/typescript/framework/getting_started/installation/serverless"
/>
<Card
title="Next.js Applications"
description="API routes, server components, edge runtime"
href="/typescript/framework/getting_started/installation/nextjs"
/>
<Card
title="Troubleshooting"
description="Common issues, bundle optimization, compatibility"
href="/typescript/framework/getting_started/installation/troubleshooting"
/>
</CardGrid>
## LLM/Embedding Providers
Go to [LLM APIs](/typescript/framework/modules/models/llms) and [Embedding APIs](/typescript/framework/modules/models/embeddings) to find out how to use different LLM and embedding providers beyond OpenAI.
## What's Next?
<CardGrid>
<Card
title="Learn LlamaIndex.TS"
description="Learn how to use LlamaIndex.TS by starting with one of our tutorials."
href="/typescript/framework/tutorials/basic_agent"
/>
<Card
title="Show me code examples"
description="Explore code examples using LlamaIndex.TS."
href="/typescript/framework/getting_started/examples"
/>
</CardGrid>
@@ -1,405 +0,0 @@
---
title: Next.js Applications
description: Deploy LlamaIndex.TS in Next.js applications with API routes, server components, and edge runtime.
---
This guide covers integrating LlamaIndex.TS agents with Next.js applications.
## Essential Configuration
### Next.js Config
Use `withLlamaIndex` to ensure compatibility:
```javascript
// next.config.mjs
import withLlamaIndex from "llamaindex/next";
/** @type {import('next').NextConfig} */
const nextConfig = {
// Your existing config
};
export default withLlamaIndex(nextConfig);
```
## API Routes
### App Router (Recommended)
```typescript
// app/api/chat/route.ts
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
import { NextRequest, NextResponse } from "next/server";
// Initialize agent once (consider using a singleton pattern)
let myAgent: any = null;
async function initializeAgent() {
if (myAgent) return myAgent;
try {
const greetTool = tool({
name: "greet",
description: "Greets a user with their name",
parameters: z.object({
name: z.string(),
}),
execute: ({ name }) => `Hello, ${name}! How can I help you today?`,
});
myAgent = agent({
tools: [greetTool],
llm: openai({ model: "gpt-4o-mini" }),
});
return myAgent;
} catch (error) {
console.error("Failed to initialize agent:", error);
throw error;
}
}
export async function POST(request: NextRequest) {
try {
const { message } = await request.json();
if (!message || typeof message !== 'string') {
return NextResponse.json(
{ error: "Message is required and must be a string" },
{ status: 400 }
);
}
const agent = await initializeAgent();
const result = await agent.run(message);
return NextResponse.json({ response: result.data });
} catch (error) {
console.error("Chat error:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
```
### Pages Router (Legacy)
```typescript
// pages/api/chat.ts
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
import type { NextApiRequest, NextApiResponse } from "next";
let myAgent: any = null;
async function initializeAgent() {
if (myAgent) return myAgent;
const timeTool = tool({
name: "getCurrentTime",
description: "Gets the current time",
parameters: z.object({}),
execute: () => new Date().toISOString(),
});
myAgent = agent({
tools: [timeTool],
llm: openai({ model: "gpt-4o-mini" }),
});
return myAgent;
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
try {
const { message } = req.body;
const agent = await initializeAgent();
const result = await agent.run(message);
res.json({ response: result.data });
} catch (error) {
console.error("Chat error:", error);
res.status(500).json({ error: "Internal server error" });
}
}
```
## Server Components
Initialize agents in server components:
```typescript
// app/chat/page.tsx
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
async function initializeAgent() {
const helpTool = tool({
name: "getHelp",
description: "Provides help information",
parameters: z.object({
topic: z.string().optional(),
}),
execute: ({ topic }) => {
if (topic) {
return `Here's help for ${topic}: This is a helpful resource about ${topic}.`;
}
return "Available topics: general, troubleshooting, api, deployment";
},
});
return agent({
tools: [helpTool],
llm: openai({ model: "gpt-4o-mini" }),
});
}
export default async function ChatPage() {
const chatAgent = await initializeAgent();
return (
<div>
<h1>Chat Interface</h1>
<p>Agent initialized and ready to help!</p>
{/* Your chat UI components */}
</div>
);
}
```
## Edge Runtime
The Edge Runtime has limited Node.js API access:
```typescript
// app/api/chat-edge/route.ts
import { NextRequest, NextResponse } from "next/server";
export const runtime = "edge";
export async function POST(request: NextRequest) {
const { setEnvs } = await import("@llamaindex/env");
setEnvs(process.env);
try {
const { message } = await request.json();
const { agent } = await import("@llamaindex/workflow");
const { tool } = await import("llamaindex");
const { openai } = await import("@llamaindex/openai");
const { z } = await import("zod");
const timeTool = tool({
name: "time",
description: "Gets current time",
parameters: z.object({}),
execute: () => new Date().toISOString(),
});
const myAgent = agent({
tools: [timeTool],
llm: openai({ model: "gpt-4o-mini" }),
});
const result = await myAgent.run(message);
return NextResponse.json({ response: result.data });
} catch (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
```
## Streaming Responses
Implement streaming for better user experience:
```typescript
// app/api/chat-stream/route.ts
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { agentStreamEvent } from "@llamaindex/workflow";
import { NextRequest } from "next/server";
import { z } from "zod";
// Initialize agent once (consider using a singleton pattern)
let myAgent: any = null;
async function initializeAgent() {
if (myAgent) return myAgent;
try {
const greetTool = tool({
name: "greet",
description: "Greets a user with their name",
parameters: z.object({
name: z.string(),
}),
execute: ({ name }) => `Hello, ${name}! How can I help you today?`,
});
myAgent = agent({
tools: [greetTool],
llm: openai({ model: "gpt-4o-mini" }),
});
return myAgent;
} catch (error) {
console.error("Failed to initialize agent:", error);
throw error;
}
}
export async function POST(request: NextRequest) {
const { message } = await request.json();
const stream = new ReadableStream({
async start(controller) {
try {
const agent = await initializeAgent();
const events = agent.runStream(message);
for await (const event of events) {
if (agentStreamEvent.include(event)) {
controller.enqueue(new TextEncoder().encode(event.data.delta));
}
}
controller.close();
} catch (error) {
controller.error(error);
}
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/plain",
"Transfer-Encoding": "chunked",
},
});
}
```
## Client-side Integration
### React Hook for API Calls
```typescript
// hooks/useAgentChat.ts
import { useState } from "react";
export function useAgentChat() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [response, setResponse] = useState<string | null>(null);
const chat = async (message: string) => {
setLoading(true);
setError(null);
try {
const res = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message }),
});
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
const data = await res.json();
setResponse(data.response);
} catch (err) {
setError(err instanceof Error ? err.message : "An error occurred");
} finally {
setLoading(false);
}
};
return { chat, loading, error, response };
}
```
### Chat Component
```typescript
// components/ChatInterface.tsx
"use client";
import { useState } from "react";
import { useAgentChat } from "@/hooks/useAgentChat";
export default function ChatInterface() {
const [message, setMessage] = useState("");
const { chat, loading, error, response } = useAgentChat();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!message.trim()) return;
await chat(message);
setMessage("");
};
return (
<div className="max-w-2xl mx-auto p-4">
<form onSubmit={handleSubmit} className="mb-4">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Send a message..."
className="w-full p-2 border rounded"
disabled={loading}
/>
<button
type="submit"
disabled={loading || !message.trim()}
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
{loading ? "Thinking..." : "Send"}
</button>
</form>
{error && (
<div className="p-3 mb-4 bg-red-100 border border-red-400 text-red-700 rounded">
Error: {error}
</div>
)}
{response && (
<div className="p-3 bg-gray-100 border rounded">
<strong>Agent:</strong>
<p>{response}</p>
</div>
)}
</div>
);
}
```
## Next Steps
- Learn about [serverless deployment](/typescript/framework/getting_started/installation/serverless)
- Explore [server APIs](/typescript/framework/getting_started/installation/server-apis)
- Check [troubleshooting guide](/typescript/framework/getting_started/installation/troubleshooting) for common issues
@@ -1,211 +0,0 @@
---
title: Server APIs & Backends
description: Deploy LlamaIndex.TS in server environments like Express, Fastify, and standalone Node.js applications.
---
This guide covers adding LlamaIndex.TS agents to traditional server environments where you have full Node.js runtime access.
## Supported Runtimes
LlamaIndex.TS works seamlessly with:
- **Node.js** (v18+)
- **Bun** (v1.0+)
- **Deno** (v1.30+)
## Common Server Frameworks
### Express.js
```typescript
import express from 'express';
import { agent } from '@llamaindex/workflow';
import { tool } from 'llamaindex';
import { openai } from '@llamaindex/openai';
import { z } from 'zod';
const app = express();
app.use(express.json());
// Initialize agent once at startup
let myAgent: any;
async function initializeAgent() {
// Create tools for the agent
const sumTool = tool({
name: "sum",
description: "Adds two numbers",
parameters: z.object({
a: z.number(),
b: z.number(),
}),
execute: ({ a, b }) => a + b,
});
const multiplyTool = tool({
name: "multiply",
description: "Multiplies two numbers",
parameters: z.object({
a: z.number(),
b: z.number(),
}),
execute: ({ a, b }) => a * b,
});
// Create the agent
myAgent = agent({
tools: [sumTool, multiplyTool],
llm: openai({ model: "gpt-4o-mini" }),
});
}
app.post('/api/chat', async (req, res) => {
try {
const { message } = req.body;
const result = await myAgent.run(message);
res.json({ response: result.data });
} catch (error) {
res.status(500).json({ error: 'Chat failed' });
}
});
// Initialize and start server
initializeAgent().then(() => {
app.listen(3000, () => {
console.log('Server running on port 3000');
});
});
```
### Fastify
```typescript
import Fastify from 'fastify';
import { agent } from '@llamaindex/workflow';
import { tool } from 'llamaindex';
import { openai } from '@llamaindex/openai';
import { z } from 'zod';
const fastify = Fastify();
let myAgent: any;
async function initializeAgent() {
const sumTool = tool({
name: "sum",
description: "Adds two numbers",
parameters: z.object({
a: z.number(),
b: z.number(),
}),
execute: ({ a, b }) => a + b,
});
myAgent = agent({
tools: [sumTool],
llm: openai({ model: "gpt-4o-mini" }),
});
}
fastify.post('/api/chat', async (request, reply) => {
try {
const { message } = request.body as { message: string };
const result = await myAgent.run(message);
return { response: result.data };
} catch (error) {
reply.status(500).send({ error: 'Chat failed' });
}
});
const start = async () => {
await initializeAgent();
await fastify.listen({ port: 3000 });
console.log('Server running on port 3000');
};
start();
```
### Hono
```typescript
import { Hono } from "hono";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
type Bindings = {
OPENAI_API_KEY: string;
};
const app = new Hono<{ Bindings: Bindings }>();
app.post("/api/chat", async (c) => {
const { setEnvs } = await import("@llamaindex/env");
setEnvs(c.env);
const { message } = await c.req.json();
const greetTool = tool({
name: "greet",
description: "Greets a user",
parameters: z.object({
name: z.string(),
}),
execute: ({ name }) => `Hello, ${name}!`,
});
const myAgent = agent({
tools: [greetTool],
llm: openai({ model: "gpt-4o-mini" }),
});
try {
const result = await myAgent.run(message);
return c.json({ response: result.data });
} catch (error) {
return c.json({ error: error.message }, 500);
}
});
export default app;
```
## Streaming Responses
For real-time agent responses:
```typescript
import { agentStreamEvent } from "@llamaindex/workflow";
app.post('/api/chat-stream', async (req, res) => {
const { message } = req.body;
res.writeHead(200, {
'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked',
});
try {
const events = myAgent.runStream(message);
for await (const event of events) {
if (agentStreamEvent.include(event)) {
res.write(event.data.delta);
}
}
res.end();
} catch (error) {
res.write('Error: ' + error.message);
res.end();
}
});
```
## Next Steps
- Learn about [serverless deployment](/typescript/framework/getting_started/installation/serverless)
- Explore [Next.js integration](/typescript/framework/getting_started/installation/nextjs)
- Check [troubleshooting guide](/typescript/framework/getting_started/installation/troubleshooting) for common issues
@@ -1,240 +0,0 @@
---
title: Serverless Functions
description: Deploy LlamaIndex.TS in serverless environments like Vercel, Netlify, AWS Lambda, and Cloudflare Workers.
---
This guide covers adding LlamaIndex.TS agents to serverless environments where you have execution time and memory constraints.
## Cloudflare Workers
```typescript
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { setEnvs } = await import("@llamaindex/env");
setEnvs(env);
const { agent } = await import("@llamaindex/workflow");
const { openai } = await import("@llamaindex/openai");
const { tool } = await import("llamaindex");
const { z } = await import("zod");
const timeTool = tool({
name: "getCurrentTime",
description: "Gets the current time",
parameters: z.object({}),
execute: () => new Date().toISOString(),
});
const myAgent = agent({
tools: [timeTool],
llm: openai({ model: "gpt-4o-mini" }),
});
try {
const { message } = await request.json();
const result = await myAgent.run(message);
return new Response(JSON.stringify({ response: result.data }), {
headers: { "Content-Type": "application/json" },
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
},
};
```
## Vercel Functions
### Node.js Runtime
```typescript
// pages/api/chat.ts or app/api/chat/route.ts
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { message } = req.body;
const weatherTool = tool({
name: "getWeather",
description: "Get weather information",
parameters: z.object({
city: z.string(),
}),
execute: ({ city }) => `Weather in ${city}: 72°F, sunny`,
});
const myAgent = agent({
tools: [weatherTool],
llm: openai({ model: "gpt-4o-mini" }),
});
try {
const result = await myAgent.run(message);
res.json({ response: result.data });
} catch (error) {
res.status(500).json({ error: error.message });
}
}
```
### Edge Runtime
```typescript
// app/api/chat/route.ts
import { NextRequest, NextResponse } from "next/server";
export const runtime = "edge";
export async function POST(request: NextRequest) {
const { setEnvs } = await import("@llamaindex/env");
setEnvs(process.env);
const { message } = await request.json();
try {
// Use simpler tools for edge runtime
const { agent } = await import("@llamaindex/workflow");
const { tool } = await import("llamaindex");
const { openai } = await import("@llamaindex/openai");
const { z } = await import("zod");
const timeTool = tool({
name: "time",
description: "Gets current time",
parameters: z.object({}),
execute: () => new Date().toISOString(),
});
const myAgent = agent({
tools: [timeTool],
llm: openai({ model: "gpt-4o-mini" }),
});
const result = await myAgent.run(message);
return NextResponse.json({ response: result.data });
} catch (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
```
## AWS Lambda
```typescript
import { APIGatewayProxyHandler } from "aws-lambda";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
export const handler: APIGatewayProxyHandler = async (event, context) => {
const { message } = JSON.parse(event.body || "{}");
const calculatorTool = tool({
name: "calculate",
description: "Performs basic math",
parameters: z.object({
expression: z.string(),
}),
execute: ({ expression }) => {
// Simple calculator implementation
try {
return `Result: ${eval(expression)}`;
} catch {
return "Invalid expression";
}
},
});
const myAgent = agent({
tools: [calculatorTool],
llm: openai({ model: "gpt-4o-mini" }),
});
try {
const result = await myAgent.run(message);
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({ response: result.data }),
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: error.message }),
};
}
};
```
## Netlify Functions
```typescript
// netlify/functions/chat.ts
import { Handler } from "@netlify/functions";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
export const handler: Handler = async (event, context) => {
if (event.httpMethod !== "POST") {
return { statusCode: 405, body: "Method Not Allowed" };
}
const { message } = JSON.parse(event.body || "{}");
const helpTool = tool({
name: "help",
description: "Provides help information",
parameters: z.object({
topic: z.string().optional(),
}),
execute: ({ topic }) => {
return topic ? `Help for ${topic}` : "Available help topics";
},
});
const myAgent = agent({
tools: [helpTool],
llm: openai({ model: "gpt-4o-mini" }),
});
try {
const result = await myAgent.run(message);
return {
statusCode: 200,
body: JSON.stringify({ response: result.data }),
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: error.message }),
};
}
};
```
## Next Steps
- Learn about [Next.js integration](/typescript/framework/getting_started/installation/nextjs)
- Explore [server deployment](/typescript/framework/getting_started/installation/server-apis)
- Check [troubleshooting guide](/typescript/framework/getting_started/installation/troubleshooting) for common issues
@@ -1,501 +0,0 @@
---
title: Troubleshooting
description: Common issues and solutions when installing and deploying LlamaIndex.TS applications.
---
This guide addresses common issues you might encounter when installing and deploying LlamaIndex.TS applications across different environments.
## Installation Issues
### Module Resolution Errors
**Problem:** Import errors or module not found errors
**Solution:** Ensure your `tsconfig.json` is properly configured:
```json5
{
"compilerOptions": {
"moduleResolution": "bundler", // or "nodenext" | "node16" | "node"
"lib": ["DOM.AsyncIterable"],
"target": "es2020",
"module": "esnext"
}
}
```
**Alternative solution:** Try different module resolution strategies:
```bash
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Or try with different package manager
pnpm install
# or
yarn install
```
### TypeScript Errors
**Problem:** TypeScript compilation errors with LlamaIndex imports
**Solution:** Ensure you have the correct TypeScript configuration:
```json5
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true, // Skip type checking of node_modules
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
}
}
```
### Package Compatibility Issues
**Problem:** Some packages don't work in certain environments
**Common incompatibilities:**
- `@llamaindex/readers` - May not work in serverless environments
- `@llamaindex/huggingface` - Limited browser/edge compatibility
- File system readers - Don't work in browser/edge environments
**Solution:** Use environment-specific alternatives:
```typescript
// Instead of file system readers in serverless
// Use remote data sources
async function loadDocumentsFromAPI() {
const response = await fetch('https://api.example.com/documents');
const data = await response.json();
return data.map(doc => new Document(doc.content));
}
```
## Runtime Issues
### Memory Errors
**Problem:** Out of memory errors during index creation or querying
**Solution:** Optimize memory usage:
```typescript
// Batch process large document sets
async function batchProcessDocuments(documents: Document[], batchSize = 10) {
const results = [];
for (let i = 0; i < documents.length; i += batchSize) {
const batch = documents.slice(i, i + batchSize);
const batchIndex = await VectorStoreIndex.fromDocuments(batch);
results.push(batchIndex);
// Optional: Add delay between batches
await new Promise(resolve => setTimeout(resolve, 100));
}
return results;
}
```
**For serverless environments:**
```typescript
// Use external vector stores instead of in-memory
// TODO: Example with Pinecone, Weaviate, etc.
// const vectorStore = new PineconeVectorStore(/* config */);
// const index = await VectorStoreIndex.fromVectorStore(vectorStore);
```
### API Rate Limiting
**Problem:** Rate limiting errors from LLM providers
**Solution:** Implement retry logic with exponential backoff:
```typescript
async function queryWithRetry(queryEngine: any, question: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await queryEngine.query(question);
} catch (error) {
if (error.message.includes('rate limit') && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
```
### Tokenization Performance
**Problem:** Slow tokenization affecting performance
**Solution:** Install faster tokenizer (Node.js only):
```bash
npm install gpt-tokenizer
```
LlamaIndex will automatically use this for 60x faster tokenization.
## Bundling Issues
### Bundle Size Too Large
**Problem:** Large bundle sizes affecting performance
**Solution:** Use dynamic imports and code splitting:
```typescript
// Lazy load LlamaIndex components
const initializeLlamaIndex = async () => {
const { VectorStoreIndex, SimpleDirectoryReader } = await import("llamaindex");
return { VectorStoreIndex, SimpleDirectoryReader };
};
// In your API route
export async function POST(request: NextRequest) {
const { VectorStoreIndex, SimpleDirectoryReader } = await initializeLlamaIndex();
// Use the imported modules
}
```
### Webpack/Vite Bundling Issues
**Problem:** Bundler compatibility issues
**Solution for Next.js:**
```javascript
// next.config.mjs
import withLlamaIndex from "llamaindex/next";
const nextConfig = {
webpack: (config, { isServer }) => {
// Custom webpack configuration if needed
if (!isServer) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
};
}
return config;
},
};
export default withLlamaIndex(nextConfig);
```
**Solution for Vite:**
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
define: {
global: 'globalThis',
},
resolve: {
alias: {
// Add aliases for problematic modules
},
},
optimizeDeps: {
include: ['llamaindex'],
},
});
```
## Environment-Specific Issues
### Node.js Version Compatibility
**Problem:** Node.js version compatibility issues
**Solution:** Use supported Node.js versions:
```json
{
"engines": {
"node": ">=18.0.0"
}
}
```
**Check your Node.js version:**
```bash
node --version
```
### Cloudflare Workers Issues
**Problem:** Module not available in Cloudflare Workers
**Solution:** Use `@llamaindex/env` for environment compatibility:
```typescript
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { setEnvs } = await import("@llamaindex/env");
setEnvs(env);
// Your LlamaIndex code here
},
};
```
### Vercel Edge Runtime Issues
**Problem:** Limited Node.js API access in Edge Runtime
**Solution:** Use standard runtime or adapt code:
```typescript
// Force standard runtime
export const runtime = "nodejs";
// Or adapt for edge
export const runtime = "edge";
export async function POST(request: NextRequest) {
// Use edge-compatible code only
const { setEnvs } = await import("@llamaindex/env");
setEnvs(process.env);
// Avoid file system operations
// Use remote data sources
}
```
## Performance Issues
### Slow Query Responses
**Problem:** Slow query performance
**Solution:** Implement caching and optimization:
```typescript
import { LRUCache } from 'lru-cache';
const queryCache = new LRUCache<string, string>({
max: 100,
ttl: 1000 * 60 * 10, // 10 minutes
});
export async function optimizedQuery(question: string, queryEngine: any) {
// Check cache first
const cached = queryCache.get(question);
if (cached) return cached;
// Query and cache result
const result = await queryEngine.query(question);
queryCache.set(question, result);
return result;
}
```
### Cold Start Issues
**Problem:** Slow cold starts in serverless environments
**Solution:** Pre-warm your functions:
```typescript
// Pre-initialize outside handler
let cachedQueryEngine: any = null;
export async function handler(event: any) {
if (!cachedQueryEngine) {
cachedQueryEngine = await initializeQueryEngine();
}
// Use cached engine
return await cachedQueryEngine.query(question);
}
```
## Environment Variable Issues
### Missing API Keys
**Problem:** API key not found or invalid
**Solution:** Verify environment variable setup:
```typescript
// Check if API key is available
if (!process.env.OPENAI_API_KEY) {
throw new Error('OPENAI_API_KEY environment variable is required');
}
// For debugging (remove in production)
console.log('API Key present:', !!process.env.OPENAI_API_KEY);
```
### Environment Variable Loading
**Problem:** Environment variables not loading correctly
**Solution:** Use proper loading mechanisms:
```typescript
// For Node.js
import 'dotenv/config';
// For Next.js - use .env.local
// Variables are automatically loaded
// For Cloudflare Workers
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Use env parameter, not process.env
const apiKey = env.OPENAI_API_KEY;
// ...
},
};
```
## Common Error Messages
### "Cannot find module 'llamaindex'"
**Cause:** Package not installed or module resolution issue
**Solution:**
```bash
npm install llamaindex
```
### "Module not found: Can't resolve 'fs'"
**Cause:** File system modules used in browser/edge environment
**Solution:**
```typescript
// Use dynamic imports with fallbacks
const loadDocuments = async () => {
if (typeof window !== 'undefined') {
// Browser environment - use alternative
return await loadDocumentsFromAPI();
} else {
// Node.js environment - use file system
const { SimpleDirectoryReader } = await import('llamaindex');
return await new SimpleDirectoryReader('data').loadData();
}
};
```
### "ReferenceError: global is not defined"
**Cause:** Global polyfill missing in browser environments
**Solution:**
```typescript
// Add to your app entry point
if (typeof global === 'undefined') {
global = globalThis;
}
```
### "Cannot read properties of undefined (reading 'query')"
**Cause:** Query engine not properly initialized
**Solution:**
```typescript
// Always check initialization
if (!queryEngine) {
throw new Error('Query engine not initialized');
}
// Or use optional chaining
const response = await queryEngine?.query(question);
```
## Debugging Tips
### Enable Debug Logging
```typescript
// Enable debug logging
process.env.DEBUG = "llamaindex:*";
// Or specific modules
process.env.DEBUG = "llamaindex:vector-store";
```
### Check Package Versions
```bash
npm list llamaindex
npm list @llamaindex/openai
```
### Test in Isolation
```typescript
// Create minimal test case
import { VectorStoreIndex } from 'llamaindex';
async function testBasic() {
try {
console.log('Testing basic import...');
const index = new VectorStoreIndex();
console.log('Success!');
} catch (error) {
console.error('Error:', error);
}
}
testBasic();
```
## Getting Help
### Before Asking for Help
1. **Check this troubleshooting guide**
2. **Search existing GitHub issues**
3. **Try minimal reproduction**
4. **Check your environment configuration**
### When Reporting Issues
Include:
- Node.js version (`node --version`)
- Package versions (`npm list llamaindex`)
- Environment (Node.js, Cloudflare Workers, Vercel, etc.)
- Minimal code reproduction
- Full error message and stack trace
### Useful Resources
- [GitHub Issues](https://github.com/run-llama/LlamaIndexTS/issues)
- [Discord Community](https://discord.gg/dGcwcsnxhU)
- [Documentation](https://docs.llamaindex.ai/)
## Next Steps
If you're still experiencing issues:
1. **Check specific deployment guides:**
- [Server APIs](/typescript/framework/getting_started/installation/server-apis)
- [Serverless Functions](/typescript/framework/getting_started/installation/serverless)
- [Next.js Applications](/typescript/framework/getting_started/installation/nextjs)
2. **Open an issue** on GitHub with a minimal reproduction
3. **Join our Discord** for community support
-118
View File
@@ -1,118 +0,0 @@
---
title: Welcome to LlamaIndex.TS
description: LlamaIndex.TS is the leading framework for utilizing context engineering to build LLM applications in JavaScript and TypeScript.
---
LlamaIndex.TS is a **framework for utilizing context engineering to build generative AI applications** with large language models. From rapid-prototyping RAG chatbots to deploying multi-agent workflows in production, LlamaIndex gives you everything you need — all in idiomatic TypeScript.
Built for modern JavaScript runtimes like <SiNodedotjs className="inline" color="#5FA04E" /> **Node.js**, <SiDeno className="inline" color="#70FFAF" /> **Deno**, <SiBun className="inline" /> **Bun**, <SiCloudflareworkers className="inline" color="#F38020" /> **Cloudflare Workers**, and more.
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 my-6">
<a href="#introduction" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline">
<h3 className="mb-1 text-lg font-semibold underline">Introduction</h3>
<p className="text-sm text-gray-400 no-underline">Context engineering, agents &amp; workflows — what do they mean?</p>
</a>
<a href="#use-cases" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline">
<h3 className="mb-1 text-lg font-semibold underline">Use cases</h3>
<p className="text-sm text-gray-400 no-underline">See what you can build with LlamaIndex.TS.</p>
</a>
<a href="#getting-started" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline">
<h3 className="mb-1 text-lg font-semibold underline">Getting started</h3>
<p className="text-sm text-gray-400 no-underline">Your first app in 5 lines of code.</p>
</a>
<a href="https://docs.cloud.llamaindex.ai/" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline" target="_blank" rel="noopener noreferrer">
<h3 className="mb-1 text-lg font-semibold underline">LlamaCloud</h3>
<p className="text-sm text-gray-400 no-underline">Managed parsing, extraction &amp; retrieval pipelines.</p>
</a>
<a href="#community" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline">
<h3 className="mb-1 text-lg font-semibold underline">Community</h3>
<p className="text-sm text-gray-400 no-underline">Join thousands of builders on Discord, Twitter, and more.</p>
</a>
<a href="#related-projects" className="block rounded-lg border border-gray-600/40 p-4 hover:border-gray-400 hover:bg-gray-700/20 no-underline">
<h3 className="mb-1 text-lg font-semibold underline">Related projects</h3>
<p className="text-sm text-gray-400 no-underline">Connectors, demos &amp; starter kits.</p>
</a>
</div>
## Introduction
### What are agents?
[Agents](/typescript/framework/tutorials/agents/1_setup) are LLM-powered assistants that can reason, use external tools, and take actions to accomplish tasks such as research, data extraction, and automation.
LlamaIndex.TS provides foundational building blocks for creating and orchestrating these agents.
### What are workflows?
[Workflows](/typescript/framework/tutorials/workflows) are multi-step, event-driven processes that combine agents, data connectors, and other tools to solve complex problems.
With LlamaIndex.TS you can chain together retrieval, generation, and tool-calling steps and then deploy the entire pipeline as a microservice.
### What is context engineering?
LLMs come pre-trained on vast public corpora, but not on **your** private or domain-specific data.
Context engineering bridges that gap by injecting the right pieces of your data into the LLM prompt at the right time.
The most popular example is [Retrieval-Augmented Generation (RAG)](/typescript/framework/getting_started/concepts), but the same idea powers agent memory, evaluation, extraction, summarisation, and more.
LlamaIndex.TS gives you:
- **Data connectors** to ingest from APIs, files, SQL, and dozens more sources.
- **Indexes & retrievers** to store and retrieve your data for LLM consumption.
- **Agents and Engines** to query and use chat+reasoning interfaces over your data.
- **Workflows** for fine-grained orchestration of your data and LLM-powered agents.
- **Observability** integrations so you can iterate with confidence.
You can learn more about these concepts in our [concepts guide](/typescript/framework/getting_started/concepts).
## Use cases
Popular scenarios include:
- [LLM-Powered Agents](/typescript/framework/tutorials/agents/1_setup)
- [Indexing and Retrieval](/typescript/framework/tutorials/rag)
- [Extracting Structured Data](/typescript/framework/tutorials/structured_data_extraction)
- [Custom Orchestration with Workflows](/typescript/framework/tutorials/workflows)
## Getting started
The fastest way to get started is in StackBlitz below — no local setup required:
<iframe
className="w-full h-[440px]"
aria-label="LlamaIndex.TS Starter"
aria-description="Interactive starter for LlamaIndex.TS"
src="https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples?embed=1&file=starter.ts"
/>
Want to learn more? We have several tutorials to get you started:
- [Installation + Runtime Guide](/typescript/framework/getting_started/installation)
- [Create your first agent](/typescript/framework/tutorials/agents/1_setup)
- [Learn how to index data and chat with it](/typescript/framework/tutorials/rag)
- [Learn how to write your own workflows and agents](/typescript/framework/tutorials/workflows)
---
## LlamaCloud
Need an end-to-end managed pipeline? Check out **[LlamaCloud](https://cloud.llamaindex.ai/)**: best-in-class document parsing (LlamaParse), extraction (LlamaExtract), and indexing services with generous free tiers.
---
## Community
- [Twitter](https://twitter.com/llama_index)
- [Discord](https://discord.gg/dGcwcsnxhU)
- [LinkedIn](https://www.linkedin.com/company/llamaindex/)
We 💜 contributors! View our [contributing guide](https://github.com/run-llama/LlamaIndexTS/blob/main/CONTRIBUTING.md) to get started.
## Related projects
- [Python framework GitHub](https://github.com/run-llama/llama_index)
- [Python docs](https://docs.llamaindex.ai/)
- [create-llama](https://www.npmjs.com/package/create-llama) — scaffold a new project in seconds!
- [UI Components](https://ui.llamaindex.ai/) — build chat applications with our Next.js components.
@@ -1,2 +0,0 @@
label: Integration
collapsed: true
@@ -1,28 +0,0 @@
---
title: Langtrace
description: Learn how to integrate LlamaIndex.TS with Langtrace.
---
Enhance your observability with Langtrace, a robust open-source tool supports OpenTelemetry and is designed to trace, evaluate, and manage LLM applications seamlessly. Langtrace integrates directly with LlamaIndex, offering detailed, real-time insights into performance metrics such as accuracy, evaluations, and latency.
## Install
- Self-host or sign-up and generate an API key using [Langtrace](https://www.langtrace.ai) Cloud
```package-install
npm i @langtrase/typescript-sdk
```
## Initialize
```js
import * as Langtrace from "@langtrase/typescript-sdk";
Langtrace.init({ api_key: "<YOUR_API_KEY>" });
```
Features:
- OpenTelemetry compliant, ensuring broad compatibility with observability platforms.
- Provides comprehensive logs and detailed traces of all components.
- Real-time monitoring of accuracy, evaluations, usage, costs, and latency.
- For more configuration options and details, visit [Langtrace Docs](https://docs.langtrace.ai/introduction).
@@ -1,85 +0,0 @@
---
title: MCP Toolbox For Databases
description: MCP Toolbox for Databases is an open source MCP server for databases.
---
# MCP Toolbox for Databases
[MCP Toolbox for Databases](https://github.com/googleapis/genai-toolbox) is an open source MCP server for databases. It was designed with enterprise-grade and production-quality in mind. It enables you to develop tools easier, faster, and more securely by handling the complexities such as connection pooling, authentication, and more.
Toolbox Tools can be seemlessly integrated with LlamaIndex applications. For more
information on [getting
started](https://googleapis.github.io/genai-toolbox/getting-started/local_quickstart_js/) or
[configuring](https://googleapis.github.io/genai-toolbox/getting-started/configure/)
Toolbox, see the
[documentation](https://googleapis.github.io/genai-toolbox/getting-started/introduction/).
![architecture](/images/mcp_db_toolbox.png)
### Configure and deploy
Toolbox is an open source server that you deploy and manage yourself. For more
instructions on deploying and configuring, see the official Toolbox
documentation:
* [Installing the Server](https://googleapis.github.io/genai-toolbox/getting-started/introduction/#installing-the-server)
* [Configuring Toolbox](https://googleapis.github.io/genai-toolbox/getting-started/configure/)
### Install client SDK
LlamaIndex relies on the `@toolbox-sdk/core` node package to use Toolbox. Install the
package before getting started:
```shell
npm install @toolbox-sdk/core
```
### Loading Toolbox Tools
Once your Toolbox server is configured and up and running, you can load tools
from your server using the SDK:
```javascript
import { gemini, GEMINI_MODEL } from "@llamaindex/google";
import { agent } from "@llamaindex/workflow";
import { tool } from "llamaindex";
import { ToolboxClient } from "@toolbox-sdk/core";
// Initialize LLM
const llm = gemini({
model: GEMINI_MODEL.GEMINI_2_0_FLASH,
apiKey: process.env.GOOGLE_API_KEY,
});
// Replace with your Toolbox Server URL
const URL = 'https://127.0.0.1:5000';
const client = new ToolboxClient("http://127.0.0.1:5000");
const toolboxTools = await client.loadToolset("my-toolset");
const getTool = (toolboxTool) => tool({
name: toolboxTool.getName(),
description: toolboxTool.getDescription(),
parameters: toolboxTool.getParamSchema(),
execute: toolboxTool
});
const tools = toolboxTools.map(getTool);
const myAgent = agent({
tools: tools,
llm,
memory,
systemPrompt: prompt,
});
const result = await myAgent.run(query);
console.log(result);
```
### Advanced Toolbox Features
Toolbox has a variety of features to make developing Gen AI tools for databases seamless.
For more information, read more about the following:
- [Authenticated Parameters](https://googleapis.github.io/genai-toolbox/resources/tools/#authenticated-parameters): bind tool inputs to values from OIDC tokens automatically, making it easy to run sensitive queries without potentially leaking data
- [Authorized Invocations](https://googleapis.github.io/genai-toolbox/resources/tools/#authorized-invocations): restrict access to use a tool based on the users Auth token
- [OpenTelemetry](https://googleapis.github.io/genai-toolbox/how-to/export_telemetry/): get metrics and tracing from Toolbox with [OpenTelemetry](https://opentelemetry.io/docs/)
@@ -1,22 +0,0 @@
---
title: OpenLLMetry
description: Learn how to integrate LlamaIndex.TS with OpenLLMetry.
---
[OpenLLMetry](https://github.com/traceloop/openllmetry-js) is an open-source project based on OpenTelemetry for tracing and monitoring
LLM applications. It connects to [all major observability platforms](https://www.traceloop.com/docs/openllmetry/integrations/introduction) and installs in minutes.
### Usage Pattern
```package-install
npm i @traceloop/node-server-sdk
```
```js
import * as traceloop from "@traceloop/node-server-sdk";
traceloop.initialize({
apiKey: process.env.TRACELOOP_API_KEY,
disableBatch: true
});
```
@@ -1,103 +0,0 @@
---
title: Vercel
description: Integrate LlamaIndex with Vercel's AI SDK
---
LlamaIndex provides integration with Vercel's AI SDK, allowing you to create powerful search and retrieval applications. You can:
- Use any of Vercel AI's [model providers](https://sdk.vercel.ai/docs/foundations/providers-and-models) as LLMs in LlamaIndex
- Use indexes (e.g. VectorStoreIndex, LlamaCloudIndex) from LlamaIndexTS in your Vercel AI applications
## Setup
First, install the required dependencies:
```package-install
npm i @llamaindex/vercel ai
```
## Using Vercel AI's Model Providers
Using the `VercelLLM` adapter, it's easy to use any of Vercel AI's [model providers](https://sdk.vercel.ai/docs/foundations/providers-and-models) as LLMs in LlamaIndex. Here's an example of how to use OpenAI's GPT-4o model:
```typescript
const llm = new VercelLLM({ model: openai("gpt-4o") });
const result = await llm.complete({
prompt: "What is the capital of France?",
stream: false, // Set to true if you want streaming responses
});
console.log(result.text);
```
## Use Indexes
### Using VectorStoreIndex
Here's how to create a simple vector store index and query it using Vercel's AI SDK:
```typescript
import { openai } from "@ai-sdk/openai";
import { llamaindex } from "@llamaindex/vercel";
import { streamText } from "ai";
import { Document } from "llamaindex";
import { LlamaCloudIndex } from "llama-cloud-services";
// Create an index from your documents
const document = new Document({ text: yourText, id_: "unique-id" });
const index = await VectorStoreIndex.fromDocuments([document]);
// Create a query tool
const queryTool = llamaindex({
model: openai("gpt-4"),
index,
description: "Search through the documents", // optional
});
// Use the tool with Vercel's AI SDK
streamText({
model: openai("gpt-4"),
prompt: "Your question here",
tools: { queryTool },
onFinish({ response }) {
console.log("Response:", response.messages); // log the response
},
}).toDataStream();
```
> Note: the Vercel AI model referenced in the `llamaindex` function is used by the response synthesizer to generate a response for the tool call.
### Using LlamaCloud
For production deployments, you can use LlamaCloud to store and manage your documents:
```typescript
import { LlamaCloudIndex } from "llama-cloud-services";
// Create a LlamaCloud index
const index = await LlamaCloudIndex.fromDocuments({
documents: [document],
name: "your-index-name",
projectName: "your-project",
apiKey: process.env.LLAMA_CLOUD_API_KEY,
});
// Use it the same way as VectorStoreIndex
const queryTool = llamaindex({
model: openai("gpt-4"),
index,
description: "Search through the documents",
options: { fields: ["sourceNodes", "messages"]}
});
// Use the tool with Vercel's AI SDK
streamText({
model: openai("gpt-4"),
prompt: "Your question here",
tools: { queryTool },
}).toDataStream();
```
## Next Steps
1. Explore [LlamaCloud](https://cloud.llamaindex.ai/) for managed document storage and retrieval
2. Join our [Discord community](https://discord.gg/dGcwcsnxhU) for support and discussions
-14
View File
@@ -1,14 +0,0 @@
{
"title": "LlamaIndex",
"description": "The Data framework for LLM",
"root": true,
"pages": [
"---Guide---",
"index",
"getting_started",
"tutorials",
"modules",
"integration",
"migration"
]
}
@@ -1,85 +0,0 @@
---
title: Migrating from v0.8 to v0.9
---
Version 0.9 of LlamaIndex.TS introduces significant architectural changes to improve package size and runtime compatibility. The main goals of this release are:
1. Reduce the package size of the main `llamaindex` package by moving dependencies into provider packages, making it more suitable for serverless environments
2. Enable consistent code across different environments by using unified imports (no separate imports for Node.js and Edge runtimes)
## Major Changes
### Installing Provider Packages
In v0.9, you need to explicitly install the provider packages you want to use. The main `llamaindex` package no longer includes these dependencies by default.
### Updating Imports
You'll need to update your imports to get classes directly from their respective provider packages. Here's how to migrate different components:
### 1. AI Model Providers
Previously:
```typescript
import { OpenAI } from "llamaindex";
```
Now:
```typescript
import { OpenAI } from "@llamaindex/openai";
```
> Note: This examples requires installing the `@llamaindex/openai` package:
```package-install
npm i @llamaindex/openai
```
For more details on available AI model providers and their configuration, see the [LLMs documentation](/typescript/framework/modules/models/llms) and the [Embedding Models documentation](/typescript/framework/modules/models/embeddings).
### 2. Storage Providers
Previously:
```typescript
import { PineconeVectorStore } from "llamaindex";
```
Now:
```typescript
import { PineconeVectorStore } from "@llamaindex/pinecone";
```
For more information about available storage options, refer to the [Data Stores documentation](/typescript/framework/modules/data/stores).
### 3. Data Loaders
Previously:
```typescript
import { SimpleDirectoryReader } from "llamaindex";
```
Now:
```typescript
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
```
For more details about available data loaders and their usage, check the [Loading Data](/typescript/framework/modules/data/readers).
### 4. Prefer using `llamaindex` instead of `@llamaindex/core`
`llamaindex` is now re-exporting most of `@llamaindex/core`. To simplify imports, just use `import { ... } from "llamaindex"` instead of `import { ... } from "@llamaindex/core"`. This is possible because `llamaindex` is now a smaller package.
We might change imports internally in `@llamaindex/core` in the future. Let us know if you're missing something.
## Benefits of the Changes
- **Smaller Bundle Size**: By moving dependencies to separate packages, your application only includes the features you actually use
- **Runtime Consistency**: The same code works across different environments without environment-specific imports
- **Improved Serverless Support**: Reduced package size makes it easier to deploy to serverless environments with size limitations
## Need Help?
If you encounter any issues during migration, please:
1. Check our [GitHub repository](https://github.com/run-llama/LlamaIndexTS) for the latest updates
2. Join our [Discord community](https://discord.gg/dGcwcsnxhU) for support
3. Open an issue on GitHub if you find a bug or have a feature request
@@ -1,2 +0,0 @@
label: Migration
collapsed: true
@@ -1,2 +0,0 @@
label: Deprecated
collapsed: true
@@ -1,2 +0,0 @@
label: Agent
collapsed: true
@@ -1,28 +0,0 @@
---
title: Agents
---
**Note**: Agents are deprecated, use [Agent Workflows](/typescript/framework/modules/agents/agent_workflow) instead.
An “agent” is an automated reasoning and decision engine. It takes in a user input/query and can make internal decisions for executing that query in order to return the correct result. The key agent components can include, but are not limited to:
- Breaking down a complex question into smaller ones
- Choosing an external Tool to use + coming up with parameters for calling the Tool
- Planning out a set of tasks
- Storing previously completed tasks in a memory module
## Getting Started
LlamaIndex.TS comes with a few built-in agents, but you can also create your own. The built-in agents include:
- OpenAI Agent
- Anthropic Agent both via Anthropic and Bedrock (in `@llamaIndex/community`)
- Gemini Agent
- ReACT Agent
- Meta3.1 504B via Bedrock (in `@llamaIndex/community`)
## Api References
- [OpenAIAgent](/typescript/framework-api-reference/classes/openaiagent/)
- [AnthropicAgent](/typescript/framework-api-reference/classes/anthropicagent/)
- [ReActAgent](/typescript/framework-api-reference/classes/reactagent/)
@@ -1,2 +0,0 @@
label: Modules
collapsed: true
@@ -1,2 +0,0 @@
label: Agents
collapsed: true
@@ -1,172 +0,0 @@
---
title: Agent Workflows
---
Agent Workflows are a powerful system that enables you to create and orchestrate one or multiple agents with tools to perform specific tasks. It's built on top of the base [`Workflow`](/typescript/framework/modules/agents/workflows) system and provides a streamlined interface for agent interactions.
## Usage
### Single Agent Workflow
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 { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
// Define a joke-telling tool
const jokeTool = tool(
() => "Baby Llama is called cria",
{
name: "joke",
description: "Use this tool to get a joke",
}
);
// Create an single agent workflow with the tool
const jokeAgent = agent({
tools: [jokeTool],
llm: openai({ model: "gpt-4o-mini" }),
});
// Run the workflow
const result = await jokeAgent.run("Tell me something funny");
console.log(result.data.result); // Baby Llama is called cria
console.log(result.data.message); // { role: 'assistant', content: 'Baby Llama is called cria' }
```
### Structured Output
You can extract structured data from agent responses by providing a `responseFormat` with a Zod schema. This is useful when you need the agent's response in a specific format for further processing:
```typescript
import { z } from "zod";
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
// Define a weather tool
const weatherTool = tool({
name: "weatherTool",
description: "Get weather information",
parameters: z.object({
location: z.string(),
}),
execute: ({ location }) => {
return `The weather in ${location} is sunny. The temperature is 72 degrees. The humidity is 50%. The wind speed is 10 mph.`;
},
});
// Define the structure you want for the response
const responseSchema = z.object({
temperature: z.number(),
humidity: z.number(),
windSpeed: z.number(),
});
// Create the agent
const weatherAgent = agent({
name: "weatherAgent",
tools: [weatherTool],
llm: openai({ model: "gpt-4.1-mini" }),
});
// Run with structured output
const result = await weatherAgent.run("What's the weather in Tokyo?", {
responseFormat: responseSchema,
});
console.log("Natural language result:", result.data.result);
console.log("Structured data:", result.data.object);
// Output: { temperature: 72, humidity: 50, windSpeed: 10 }
```
The agent will:
1. Use the weather tool to get the raw weather information
2. Process that information through the LLM
3. Extract structured data according to your schema
4. Return both the natural language response and the structured object
### Event Streaming
Agent Workflows provide a unified interface for event streaming, making it easy to track and respond to different events during execution:
```typescript
import { agentToolCallEvent, agentStreamEvent } from "@llamaindex/workflow";
// Get the workflow execution context
const events = jokeAgent.runStream("Tell me something funny");
// Stream and handle events
for await (const event of events) {
if (agentToolCallEvent.include(event)) {
console.log(`Tool being called: ${event.data.toolName}`);
}
if (agentStreamEvent.include(event)) {
process.stdout.write(event.data.delta);
}
}
```
### Multi-Agent Workflow
An Agent Workflow can orchestrate multiple agents, enabling complex interactions and task handoffs. Each agent in a multi-agent workflow requires:
- `name`: Unique identifier for the agent
- `description`: Purpose description used for task routing
- `tools`: Array of tools the agent can use
- `canHandoffTo` (optional): Array of agent names or agent instances that this agent can delegate tasks to
Here's an example of a multi-agent system that combines joke-telling and weather information:
```typescript
import { tool } from "llamaindex";
import { multiAgent, agent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";
import { z } from "zod";
// Create a weather agent
const weatherAgent = agent({
name: "WeatherAgent",
description: "Provides weather information for any city",
tools: [
tool(
{
name: "fetchWeather",
description: "Get weather information for a city",
parameters: z.object({
city: z.string(),
}),
execute: ({ city }) => `The weather in ${city} is sunny`,
}
),
],
llm: openai({ model: "gpt-4o-mini" }),
});
// Create a joke-telling agent
const jokeAgent = agent({
name: "JokeAgent",
description: "Tells jokes and funny stories",
tools: [jokeTool], // Using the joke tool defined earlier
llm: openai({ model: "gpt-4o-mini" }),
canHandoffTo: [weatherAgent], // Can hand off to the weather agent
});
// Create the multi-agent workflow
const agents = multiAgent({
agents: [jokeAgent, weatherAgent],
rootAgent: jokeAgent, // Start with the joke agent
});
// Run the workflow
const result = await agents.run(
"Give me a morning greeting with a joke and the weather in San Francisco"
);
console.log(result.data.result);
```
The workflow will coordinate between agents, allowing them to handle different aspects of the request and hand off tasks when appropriate.
@@ -1,198 +0,0 @@
---
title: Low-Level LLM Execution
---
Sometimes your need more control over LLM interactions than what high-level agents provide. The `llm.exec` method makes it simple for you to make a single LLM call with tools but hides the complexity of executing the tools and generating the tool messages.
## When to Use `llm.exec`
Use `llm.exec` when you need to:
- Build custom agent logic in [workflow](/typescript/framework/modules/agents/workflows) steps
- Have precise control over message handling and tool execution
- Extract structured data from LLM responses
## Basic Usage
The `llm.exec` method takes messages and tools as parameter and executes one LLM call.
The LLM might either request to call one or more of the tools or generate an assistant message as result.
For each tool call that is requested, `llm.exec` executes it and generates the two tool call messages (call and result). If no tool call is requested, just the assistant message is returned.
```ts
import { openai } from "@llamaindex/openai";
import { ChatMessage, tool } from "llamaindex";
import z from "zod";
const llm = openai({ model: "gpt-4.1-mini" });
const messages = [
{
content: "What's the weather like in San Francisco?",
role: "user",
} as ChatMessage,
];
const { newMessages, toolCalls } = await llm.exec({
messages,
tools: [
tool({
name: "get_weather",
description: "Get the current weather for a location",
parameters: z.object({
address: z.string().describe("The address"),
}),
execute: ({ address }) => {
return `It's sunny in ${address}!`;
},
}),
],
});
// Add the new messages (including tool calls and responses) to your conversation
messages.push(...newMessages);
```
> `newMessages` is an array as each tool call generates two messages: a tool call message and the tool call result message.
## Structured Output
You can use `responseFormat` with a Zod schema to get structured data from the LLM response:
```ts
import { openai } from "@llamaindex/openai";
import { ChatMessage } from "llamaindex";
import z from "zod";
const llm = openai({ model: "gpt-4.1-mini" });
const schema = z.object({
title: z.string(),
author: z.string(),
year: z.number(),
});
const messages = [
{
role: "user",
content: "I have been reading La Divina Commedia by Dante Alighieri, published in 1321",
} as ChatMessage,
];
const { newMessages, toolCalls, object } = await llm.exec({
messages,
responseFormat: schema,
});
console.log(object); // { title: "La Divina Commedia", author: "Dante Alighieri", year: 1321 }
```
## Agent Loop Pattern
A common pattern is to use `llm.exec` in a loop until the LLM stops making tool calls:
```ts
import { openai } from "@llamaindex/openai";
import { ChatMessage, tool } from "llamaindex";
import z from "zod";
async function runAgentLoop() {
const llm = openai({ model: "gpt-4.1-mini" });
const messages = [
{
content: "What's the weather like in San Francisco?",
role: "user",
} as ChatMessage,
];
let exit = false;
do {
const { newMessages, toolCalls } = await llm.exec({
messages,
tools: [
tool({
name: "get_weather",
description: "Get the current weather for a location",
parameters: z.object({
address: z.string().describe("The address"),
}),
execute: ({ address }) => {
return `It's sunny in ${address}!`;
},
}),
],
});
console.log(newMessages);
messages.push(...newMessages);
// Exit when no more tool calls are made
exit = toolCalls.length === 0;
} while (!exit);
}
```
## Streaming Support
For real-time responses, use the `stream` option to get the assistant's response as streamed tokens:
```ts
import { openai } from "@llamaindex/openai";
import { ChatMessage, tool } from "llamaindex";
import z from "zod";
async function streamingAgentLoop() {
const llm = openai({ model: "gpt-4o-mini" });
const messages = [
{
content: "What's the weather like in San Francisco?",
role: "user",
} as ChatMessage,
];
let exit = false;
do {
const { stream, newMessages, toolCalls } = await llm.exec({
messages,
tools: [
tool({
name: "get_weather",
description: "Get the current weather for a location",
parameters: z.object({
address: z.string().describe("The address"),
}),
execute: ({ address }) => {
return `It's sunny in ${address}!`;
},
}),
],
stream: true,
});
// Stream the response token by token
for await (const chunk of stream) {
process.stdout.write(chunk.delta);
}
messages.push(...newMessages());
exit = toolCalls.length === 0;
} while (!exit);
}
```
> `newMessages` is a function when streaming. The reason is that the result only is available after streaming. Calling it before, will throw an error.
## Return Values
`llm.exec` returns an object with:
- **`newMessages`**: Array of new chat messages including the LLM response and any tool call messages (call or result). This is a function return the array when streaming.
- **`toolCalls`**: Array of tool calls made by the LLM
- **`object`**: The structured object when using `responseFormat` with a Zod schema (undefined if no schema is provided)
- **`stream`**: Async iterable for streaming responses (only when `stream: true`)
## Best Practices
For using `llm.exec` in an agent loop, take care to:
1. **Maintain message history**: Always add `newMessages` to your conversation history
2. **Set exit conditions**: Implement proper logic to avoid infinite loops
3. **Handle structured output**: When using `responseFormat`, the `object` property contains your parsed data
@@ -1,103 +0,0 @@
---
title: Define workflows using natural language
---
When working with Workflows, you have to write code to handle an event in the workflow.
Often, the logic of the handler is not too complex so that it can be expressed using natural language and executed by an LLM.
Besides the instructions, we just need the expected result event of the step, possible tool calls and optionally other events that can be emitted.
## Usage
Let's take an example of a workflow that generates a joke, gets a critique for it, and then improves it.
### Define the events
First, we define the events for our workflow. We need one for writing the joke, one for critiquing it, and one for the final result:
```typescript
import { z } from "zod";
import { zodEvent } from "@llamaindex/workflow";
const writeJokeSchema = z.object({
description: z
.string()
.describe("The topic to write a joke or describe the joke to improve."),
writtenJoke: z.optional(z.string()).describe("The written joke."),
retriedTimes: z
.number()
.default(0)
.describe(
"The retried times for writing the joke. Always increase this from the input retriedTimes.",
),
});
const critiqueSchema = z.object({
joke: z.string().describe("The joke to critique"),
retriedTimes: z.number().describe("The retried times for writing the joke."),
});
const finalResultSchema = z.object({
joke: z.string().describe("The joke to critique"),
critique: z.string().describe("The critique of the joke"),
});
const writeJokeEvent = zodEvent(writeJokeSchema, {
debugLabel: "writeJokeEvent",
});
const critiqueEvent = zodEvent(critiqueSchema, {
debugLabel: "critiqueEvent",
});
const finalResultEvent = zodEvent(finalResultSchema, {
debugLabel: "finalResultEvent",
});
```
Note that your natural language workflows the events need to be created by the `zodEvent` function passing the zod schema as an argument. The agent needs the schema of the event data to correctly generate events.
Also, we need a `debugLabel` so the LLM can identify the event to emit in the workflow.
### Define the workflow
As usual you first create the workflow:
```typescript
import { agentHandler, createWorkflow } from "@llamaindex/workflow";
const jokeFlow = createWorkflow();
```
Then you need to handle the events. For the handlers, instead of code, you're now going to use natural language by calling the `agentHandler` function.
It only requires two parameters:
- `instructions`: A prompt to guide the agent how to handle the steps.
- `results`: The output events that the agent should return after handling the step.
Then you will have a simple code to handle the step:
```typescript
jokeFlow.handle(
[writeJokeEvent],
agentHandler({
instructions: `You are a joke writer. You are given a topic and you need to write a joke about it.`,
results: [critiqueEvent],
}),
);
jokeFlow.handle(
[critiqueEvent],
agentHandler({
instructions: `
You are given a joke and you need to critique it. Follow the following guidelines:
1. You have maximum 3 times to improve the joke.
2. If the joke is not good, increase the retriedTimes, describe how to improve the joke and send a writeJokeEvent.
3. If the joke is good, trigger the finalResultEvent event.
`,
results: [writeJokeEvent, finalResultEvent],
}),
);
```
For advanced usage, you can add more functionality to `agentHandler` by using these parameters:
- `events`: A list of additional events that the agent can emit to the workflow. E.g., your agent can emit a `uiEvent` to update the UI during the execution.
- `tools`: A list of tools that the agent can use to handle the step. E.g., your agent can use a `search` tool to search the web.
You can find more code examples in the [examples](https://github.com/run-llama/LlamaIndexTS/tree/main/examples/agents/natural) folder.
@@ -1,2 +0,0 @@
label: Tool
collapsed: true
@@ -1,156 +0,0 @@
---
title: Tools
---
A "tool" is a utility that can be called by an agent on behalf of an LLM.
A tool can be called to perform custom actions, or retrieve extra information based on the LLM-generated input.
A result from a tool call can be used by subsequent steps in a workflow, or to compute a final answer.
For example, a "weather tool" could fetch some live weather information from a geographical location.
## Tool Function
The `tool` function is a utility provided to define a tool that can be used by an agent. It takes a function and a configuration object as arguments. The configuration object includes the tool's name, description, and parameters.
### Parameters with Zod
The `parameters` field in the tool configuration is defined using `zod`, a TypeScript-first schema declaration and validation library. `zod` allows you to specify the expected structure and types of the input parameters, ensuring that the data passed to the tool is valid.
Example:
```ts
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { z } from "zod";
// first arg is LLM input, second is bound arg
const queryKnowledgeBase = async ({ question }, { userToken }) => {
const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
// ...
};
// define tool with zod validation
const kbTool = tool(queryKnowledgeBase, {
name: 'queryKnowledgeBase',
description: 'Query knowledge base',
parameters: z.object({
question: z.string({
description: 'The user question',
}),
}),
});
```
In this example, `z.object` is used to define a schema for the `parameters` where `question` is expected to be a string. This ensures that any input to the tool adheres to the specified structure, providing a layer of type safety and validation.
## Built-in tools
You can import built-in tools from the `@llamaindex/tools` package.
```ts
import { agent } from "@llamaindex/workflow";
import { wiki } from "@llamaindex/tools";
const researchAgent = agent({
name: "WikiAgent",
description: "Gathering information from the internet",
systemPrompt: `You are a research agent. Your role is to gather information from the internet using the provided tools.`,
tools: [wiki()],
});
```
## MCP tools
If you have a MCP server running, you can fetch tools from the server and use them in your agents.
```ts
// 1. Import MCP tools adapter
import { mcp } from "@llamaindex/tools";
import { agent } from "@llamaindex/workflow";
// 2. Initialize a MCP client
// by npx
const server = mcp({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
verbose: true,
});
// or by StreamableHTTP transport
const server = mcp({
url: "http://localhost:8000/mcp",
verbose: true,
});
// if your MCP server is not using StreamableHTTP transport, you can also use SSE transport
// by setting useSSETransport to true.
// See: https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse-deprecated
const server = mcp({
url: "http://localhost:8000/mcp",
useSSETransport: true,
verbose: true,
});
// 3. Get tools from MCP server
const tools = await server.tools();
// Now you can create an agent with the tools
const agent = agent({
name: "My Agent",
systemPrompt: "You are a helpful assistant that can use the provided tools to answer questions.",
llm: openai({ model: "gpt-4o" }),
tools: tools,
});
```
You can also use [MCP Toolbox for
Databases](/typescript/framework/integration/mcp-toolbox) to interact with MCP tools.
## Function tool
You can still use the `FunctionTool` class to define a tool.
A `FunctionTool` is constructed from a function with signature
```ts
(input: T, additionalArg?: AdditionalToolArgument) => R
```
where
- `input` is generated by the LLM, `T` is the type defined by the tool `parameters`
- `additionalArg` is an optional extra argument, see "Binding" below
- `R` is the return type
### Binding
An additional argument can be bound to a tool, each tool call will be passed
- the input provided by the LLM
- the additional argument (extends object)
Note: calling the `bind` method will return a new `FunctionTool` instance, without modifying the tool which `bind` is called on.
Example to pass a `userToken` as additional argument:
```ts
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
// first arg is LLM input, second is bound arg
const queryKnowledgeBase = async ({ question }, { userToken }) => {
const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
// ...
};
// define tool as usual
const kbTool = tool(queryKnowledgeBase, {
name: 'queryKnowledgeBase',
description: 'Query knowledge base',
parameters: z.object({
question: z.string({
description: 'The user question',
}),
}),
});
// create an agent
const additionalArg = { userToken: 'abcd1234' };
const workflow = agent({
tools: [kbTool.bind(additionalArg)],
// llm, systemPrompt etc
})
```
@@ -1,21 +0,0 @@
---
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.
To use workflows install this package:
```package-install
npm i @llamaindex/workflow-core
```
This contains the core functionality for the workflow system. You can read more about the core concepts in the [workflow-core](/typescript/workflows/) section.
In contrast, the `@llamaindex/workflow` package contains more utiltities, such as prebuilt agents.
```package-install
npm i @llamaindex/workflow
```
@@ -1,2 +0,0 @@
label: Data
collapsed: true
@@ -1,2 +0,0 @@
label: Data Index
collapsed: true
@@ -1,24 +0,0 @@
---
title: Index
---
An index is the basic container for organizing your data. Besides managed indexes using [LlamaCloud](/typescript/framework/modules/data/data_index/managed), LlamaIndex.TS supports three indexes:
- `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";
const document = new Document({ text: "test" });
const index = await VectorStoreIndex.fromDocuments([document]);
```
## API Reference
- [SummaryIndex](/typescript/framework-api-reference/classes/summaryindex/)
- [VectorStoreIndex](/typescript/framework-api-reference/classes/vectorstoreindex/)
- [KeywordTableIndex](/typescript/framework-api-reference/classes/keywordtableindex/)
@@ -1,31 +0,0 @@
---
title: Managed Index
description: Managed index using LlamaCloud
---
LlamaCloud is a new generation of managed parsing, ingestion, and retrieval services, designed to bring production-grade context-augmentation to your LLM and RAG applications.
LlamaCloud supports
- Managed Ingestion API, handling parsing and document management
- Managed Retrieval API, configuring optimal retrieval for your RAG system
## Access
Visit [LlamaCloud](https://cloud.llamaindex.ai) to sign in and get an API key.
## Create a Managed Index
Here's an example of how to create a managed index by ingesting a couple of documents:
<include cwd>../../examples/cloud/chat.ts</include>
## Use a Managed Index
Here's an example of how to use a managed index together with a chat engine:
<include cwd>../../examples/cloud/from-documents.ts</include>
## API Reference
- [LlamaCloud Documentation](https://docs.cloud.llamaindex.ai/)
@@ -1,17 +0,0 @@
---
title: Documents and Nodes
description: Data structure for storing data in LlamaIndex
---
`Document`s and `Node`s are the basic building blocks of data in LlamaIndexTS. 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.
```typescript
import { Document } from "llamaindex";
document = new Document({ text: "text", metadata: { key: "val" } });
```
## API Reference
- [Document](/typescript/framework-api-reference/classes/document/)
- [TextNode](/typescript/framework-api-reference/classes/textnode/)
@@ -1,2 +0,0 @@
label: Ingestion Pipeline
collapsed: true
@@ -1,110 +0,0 @@
---
title: Ingestion Pipeline
---
An `IngestionPipeline` uses a concept of `Transformations` that are applied to input data.
These `Transformations` are applied to your input data, and the resulting nodes are either returned or inserted into a vector database (if given).
## Installation
```package-install
npm i llamaindex @llamaindex/openai @llamaindex/qdrant
```
## Usage Pattern
The simplest usage is to instantiate an IngestionPipeline like so:
```ts
import fs from "node:fs/promises";
import { OpenAI, OpenAIEmbedding } from "@llamaindex/openai";
import {
Document,
IngestionPipeline,
MetadataMode,
TitleExtractor,
SentenceSplitter,
} from "llamaindex";
async function main() {
// Load essay from abramov.txt in Node
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
// Create Document object with essay
const document = new Document({ text: essay, id_: path });
const pipeline = new IngestionPipeline({
transformations: [
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
new TitleExtractor(),
new OpenAIEmbedding(),
],
});
// run the pipeline
const nodes = await pipeline.run({ documents: [document] });
// print out the result of the pipeline run
for (const node of nodes) {
console.log(node.getContent(MetadataMode.NONE));
}
}
main().catch(console.error);
```
## Connecting to Vector Databases
When running an ingestion pipeline, you can also chose to automatically insert the resulting nodes into a remote vector store.
Then, you can construct an index from that vector store later on.
```ts
import fs from "node:fs/promises";
import { OpenAIEmbedding } from "@llamaindex/openai";
import { QdrantVectorStore } from "@llamaindex/qdrant";
import {
Document,
IngestionPipeline,
MetadataMode,
TitleExtractor,
SentenceSplitter,
VectorStoreIndex,
} from "llamaindex";
async function main() {
// Load essay from abramov.txt in Node
const path = "node_modules/llamaindex/examples/abramov.txt";
const essay = await fs.readFile(path, "utf-8");
const vectorStore = new QdrantVectorStore({
host: "http://localhost:6333",
});
// Create Document object with essay
const document = new Document({ text: essay, id_: path });
const pipeline = new IngestionPipeline({
transformations: [
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
new TitleExtractor(),
new OpenAIEmbedding(),
],
vectorStore,
});
// run the pipeline
const nodes = await pipeline.run({ documents: [document] });
// create an index
const index = VectorStoreIndex.fromVectorStore(vectorStore);
}
main().catch(console.error);
```
## API Reference
- [IngestionPipeline](/typescript/framework-api-reference/classes/ingestionpipeline/)
@@ -1,2 +0,0 @@
label: Transformations
collapsed: true
@@ -1,83 +0,0 @@
---
title: Transformations
---
A transformation is something that takes a list of nodes as an input, and returns a list of nodes. Each component that implements the Transformation class has both a `transform` definition responsible for transforming the nodes.
Currently, the following components are Transformation objects:
- [SentenceSplitter](/typescript/framework/modules/data/ingestion_pipeline/transformations/node-parser)
- [MetadataExtractor](/typescript/framework/modules/data/ingestion_pipeline/transformations/metadata_extraction)
- [Embeddings](/typescript/framework/modules/models/embeddings)
## Usage Pattern
While transformations are best used with with an IngestionPipeline, they can also be used directly.
```ts
import { SentenceSplitter, TitleExtractor, Document } from "llamaindex";
async function main() {
let nodes = new SentenceSplitter().getNodesFromDocuments([
new Document({ text: "I am 10 years old. John is 20 years old." }),
]);
const titleExtractor = new TitleExtractor();
nodes = await titleExtractor.transform(nodes);
for (const node of nodes) {
console.log(node.getContent(MetadataMode.NONE));
}
}
main().catch(console.error);
```
## Custom Transformations
You can implement any transformation yourself by implementing the `TransformComponent`.
The following custom transformation will remove any special characters or punctuation in text.
```ts
import { TransformComponent, TextNode } from "llamaindex";
export class RemoveSpecialCharacters extends TransformComponent {
async transform(nodes: TextNode[]): Promise<TextNode[]> {
for (const node of nodes) {
node.text = node.text.replace(/[^\w\s]/gi, "");
}
return nodes;
}
}
```
These can then be used directly or in any IngestionPipeline.
```ts
import { IngestionPipeline, Document } from "llamaindex";
async function main() {
const pipeline = new IngestionPipeline({
transformations: [new RemoveSpecialCharacters()],
});
const nodes = await pipeline.run({
documents: [
new Document({ text: "I am 10 years old. John is 20 years old." }),
],
});
for (const node of nodes) {
console.log(node.getContent(MetadataMode.NONE));
}
}
main().catch(console.error);
```
## API Reference
- [TransformComponent](/typescript/framework-api-reference/classes/transformcomponent/)
@@ -1,49 +0,0 @@
---
title: Metadata Extraction
---
You can use LLMs to automate metadata extraction with our `Metadata Extractor` modules.
Our metadata extractor modules include the following "feature extractors":
- `SummaryExtractor` - automatically extracts a summary over a set of Nodes
- `QuestionsAnsweredExtractor` - extracts a set of questions that each Node can answer
- `TitleExtractor` - extracts a title over the context of each Node by document and combine them
- `KeywordExtractor` - extracts keywords over the context of each Node
Then you can chain the `Metadata Extractors` with the `IngestionPipeline` to extract metadata from a set of documents.
```ts
import { Document, IngestionPipeline, TitleExtractor, QuestionsAnsweredExtractor } from "llamaindex";
import { OpenAI } from "@llamaindex/openai";
async function main() {
const pipeline = new IngestionPipeline({
transformations: [
new TitleExtractor(),
new QuestionsAnsweredExtractor({
questions: 5,
}),
],
});
const nodes = await pipeline.run({
documents: [
new Document({ text: "I am 10 years old. John is 20 years old." }),
],
});
for (const node of nodes) {
console.log(node.metadata);
}
}
main().then(() => console.log("done"));
```
## API Reference
- [SummaryExtractor](/typescript/framework-api-reference/classes/summaryextractor/)
- [QuestionsAnsweredExtractor](/typescript/framework-api-reference/classes/questionsansweredextractor/)
- [TitleExtractor](/typescript/framework-api-reference/classes/titleextractor/)
- [KeywordExtractor](/typescript/framework-api-reference/classes/keywordextractor/)
@@ -1,200 +0,0 @@
---
title: Node Parsers / Text Splitters
description: Learn how to use Node Parsers and Text Splitters to extract data from documents.
---
Node parsers are a simple abstraction that take a list of `Document` objects, and chunk them into `Node` objects, such that each node is a specific chunk of the parent document. When a document is broken into nodes, all of it's attributes are inherited to the children nodes (i.e. `metadata`, text and metadata templates, etc.). You can read more about `Node` and `Document` properties [here](/typescript/framework/modules/data).
By default, we will use `Settings.nodeParser` to split the document into nodes. You can also assign a custom `NodeParser` to the `Settings` object.
## SentenceSplitter
The `SentenceSplitter` is the default `NodeParser` in LlamaIndex. It will split the text from a `Document` into sentences.
```ts twoslash
import { TextFileReader } from '@llamaindex/readers/text'
import { SentenceSplitter } from 'llamaindex';
import { Settings } from 'llamaindex';
const nodeParser = new SentenceSplitter();
Settings.nodeParser = nodeParser;
// ^?
```
The underlying text splitter will split text by sentences. It can also be used as a standalone module for splitting raw text.
```ts twoslash
import { SentenceSplitter } from "llamaindex";
const splitter = new SentenceSplitter({ chunkSize: 1 });
const texts = splitter.splitText("Hello World");
// ^?
```
## MarkdownNodeParser
The `MarkdownNodeParser` is a more advanced `NodeParser` that can handle markdown documents. It will split the markdown into nodes and then parse the nodes into a `Document` object.
<Tabs items={["with reader", "with node:fs"]}>
```ts twoslash tab="with reader"
import { MarkdownNodeParser } from "llamaindex";
import { MarkdownReader } from '@llamaindex/readers/markdown'
const reader = new MarkdownReader();
const markdownNodeParser = new MarkdownNodeParser();
const documents = await reader.loadData('path/to/file.md');
const parsedDocuments = markdownNodeParser(documents);
// ^?
```
```ts twoslash tab="with node:fs"
import fs from 'node:fs/promises';
import { MarkdownNodeParser, Document } from "llamaindex";
const markdownNodeParser = new MarkdownNodeParser();
const text = await fs.readFile('path/to/file.md', 'utf-8');
const document = new Document({ text });
const parsedDocuments = markdownNodeParser([document]);
// ^?
```
</Tabs>
The output metadata will be something like:
```bash
[
TextNode {
id_: '008e41a8-b097-487c-bee8-bd88b9455844',
metadata: { 'Header 1': 'Main Header' },
excludedEmbedMetadataKeys: [],
excludedLlmMetadataKeys: [],
relationships: { PARENT: [Array] },
hash: 'KJ5e/um/RkHaNR6bonj9ormtZY7I8i4XBPVYHXv1A5M=',
text: 'Main Header\nMain content',
textTemplate: '',
metadataSeparator: '\n'
},
TextNode {
id_: '0f5679b3-ba63-4aff-aedc-830c4208d0b5',
metadata: { 'Header 1': 'Header 2' },
excludedEmbedMetadataKeys: [],
excludedLlmMetadataKeys: [],
relationships: { PARENT: [Array] },
hash: 'IP/g/dIld3DcbK+uHzDpyeZ9IdOXY4brxhOIe7wc488=',
text: 'Header 2\nHeader 2 content',
textTemplate: '',
metadataSeparator: '\n'
},
TextNode {
id_: 'e81e9bd0-121c-4ead-8ca7-1639d65fdf90',
metadata: { 'Header 1': 'Header 2', 'Header 2': 'Sub-header' },
excludedEmbedMetadataKeys: [],
excludedLlmMetadataKeys: [],
relationships: { PARENT: [Array] },
hash: 'B3kYNnxaYi9ghtAgwza0ZEVKF4MozobkNUlcekDL7JQ=',
text: 'Sub-header\nSub-header content',
textTemplate: '',
metadataSeparator: '\n'
}
]
```
## CodeSplitter
The `CodeSplitter` is a more advanced `NodeParser` that can handle code documents.
It will split the code by AST nodes and then parse the nodes into a `Document` object.
<Tabs items={["with reader", "with node:fs"]}>
```ts twoslash tab="with reader"
import { TextFileReader } from '@llamaindex/readers/text'
import { CodeSplitter } from '@llamaindex/node-parser/code'
import Parser from "tree-sitter";
import TS from "tree-sitter-typescript";
const parser = new Parser();
parser.setLanguage(TS.typescript as Parser.Language);
const codeSplitter = new CodeSplitter({
getParser: () => parser,
});
const reader = new TextFileReader();
const documents = await reader.loadData('path/to/file.ts');
const parsedDocuments = codeSplitter(documents);
// ^?
```
```ts twoslash tab="with node:fs"
import fs from 'node:fs/promises';
import { CodeSplitter } from '@llamaindex/node-parser/code'
import Parser from "tree-sitter";
import TS from "tree-sitter-typescript";
const parser = new Parser();
parser.setLanguage(TS.typescript as Parser.Language);
const codeSplitter = new CodeSplitter({
getParser: () => parser,
});
const parsedDocuments = codeSplitter.splitText(await fs.readFile('path/to/file.ts', 'utf-8'));
// ^?
```
</Tabs>
Try it out ⬇️
<details>
<summary>Use it in browser</summary>
You might setup WASM files for `web-tree-sitter` and use it in the browser.
```ts
import Parser from 'web-tree-sitter';
Parser.init({
locateFile(scriptName: string) {
return '/' + scriptName
},
}).then(async () => {
const parser = new Parser();
const Lang = await Parser.Language.load('/tree-sitter-typescript.wasm');
parser.setLanguage(Lang);
return new CodeSplitter({
getParser: () => parser,
maxChars: 100
});
});
```
In this example, you should put `tree-sitter-typescript.wasm` to the `public` folder for Next.js.
And also update the `next.config.js` to make `@llamaindex/env` work properly.
```js
const config = {
webpack: (config) => {
if (Array.isArray(config.target) && config.target.includes('web')) {
config.target = ["web", "es2020"];
}
return config;
}
}
export default config;
```
</details>
## API Reference
- [SentenceSplitter](/typescript/framework-api-reference/classes/sentencesplitter/)
- [MarkdownNodeParser](/typescript/framework-api-reference/classes/markdownnodeparser/)
- [CodeSplitter](/typescript/framework-api-reference/classes/codesplitter/)
@@ -1,2 +0,0 @@
label: Memory
collapsed: true
@@ -1,228 +0,0 @@
---
title: Memory
description: Manage conversation history and context with agents
---
## Concept
Memory is a core component of agentic systems. It allows you to store and retrieve information from the past.
In LlamaIndexTS, you can create memory by using the `createMemory` function. This function will return a `Memory` object, which you can then use to store and retrieve information.
As the agent runs, it will make calls to `add()` to store information, and `get()` to retrieve information.
## Usage
A `Memory` object has both short-term memory (i.e. a FIFO queue of messages) and optionally long-term memory (i.e. extracting information over time).
`get()` always returns all messages stored in the memory. The longer the agent runs, this will exceed the context window of the agent. To avoid this, the agent is using the `getLLM` method to get the last X messages that fit into the context window.
### Configuring Memory for an Agent
Here we're creating a memory with a static block (read more about [memory blocks](#long-term-memory)) that contains some information about the user.
```ts twoslash
import { openai } from "@llamaindex/openai";
import { agent } from "@llamaindex/workflow";
import { createMemory, staticBlock } from "llamaindex";
const llm = openai({ model: "gpt-4.1-mini" });
// Create memory with predefined context
const memory = createMemory({
memoryBlocks: [
staticBlock({
content:
"The user is a software engineer who loves TypeScript and LlamaIndex.",
}),
],
});
// Create an agent with the memory
const workflow = agent({
name: "assistant",
llm,
memory,
});
const result = await workflow.run("What is my name?");
console.log("Response:", result.data.result);
```
### Using Vercel format
You can also put messages in Vercel format directly to the memory:
```ts
await memory.add({
id: "1",
createdAt: new Date(),
role: "user",
content: "Hello!",
options: {
parts: [
{
type: "file",
data: "base64...",
mimeType: "image/png",
},
],
},
});
```
If you call `get`, messages are usually retrieved in the LlamaIndexTS format (type `ChatMessage`). If you specify the `type` parameter using `get`, you can return the messages in different formats. E.g.: using `type: "vercel"`, you can return the messages in Vercel format:
```ts
const messages = await memory.get({ type: "vercel" });
console.log(messages);
```
## Customizing Memory
### Short-Term Memory
The `Memory` object will store all the messages that are added to the `Memory` object. Unless you call `clear()`, no messages are removed from the memory. This is the short-term memory (usually you will store the memory of one user session there) which is augmented by the long-term memory.
Calling `getLLM` will retrieve messages from long-term memory and ensure that the given `tokenLimit` is not reached. These are the messages that you will sent to the LLM.
For initialization, you call `createMemory` with the following options:
- `tokenLimit`: Maximum tokens for memory retrieval using `getLLM` (default: 30000).
- `shortTermTokenLimitRatio`: Ratio of tokens for short-term vs long-term memory (default: 0.7)
- `customAdapters`: Custom message adapters for different message formats. LlamaIndex (`ChatMessageAdapter`) and Vercel (`VercelMessageAdapter`) are built-in adapters.
- `memoryBlocks`: Memory blocks for long-term storage, see [Long-Term Memory](#long-term-memory)
Example:
```ts
const memory = createMemory({
tokenLimit=40000,
shortTermTokenLimitRatio=0.5,
});
```
### Long-Term Memory
Long-term memory is represented as `Memory Block` objects. These objects contain information that are from previous user sessions or from the beginning of the current conversation. When memory is retrieved (by calling `getLLM`), the short-term and long-term memories are merged together within the given `tokenLimit`.
Currently, there are three predefined memory blocks:
- `staticBlock`: A memory block that stores a static piece of information.
- `factExtractionBlock`: A memory block that extracts facts from the chat history.
- `vectorBlock`: A memory block that stores and retrieves chat messages from a vector database using semantic similarity search. Messages are stored individually and retrieved based on their relevance to recent conversation context. Here we've passed in the `vectorStore` to use to store and retrieve the chat messages.
This sounds a bit complicated, but it's actually quite simple. Let's look at an example:
```ts
import { createMemory, factExtractionBlock, staticBlock, vectorBlock } from "llamaindex";
import { QdrantVectorStore } from "@llamaindex/qdrant";
import { OpenAIEmbedding } from "@llamaindex/openai";
const memoryBlocks= [
staticBlock({
content: "My name is Logan, and I live in Saskatoon. I work at LlamaIndex.",
}),
factExtractionBlock({
priority: 1,
llm: llm,
maxFacts: 50,
}),
vectorBlock({
vectorStore: new QdrantVectorStore({ url: "http://localhost:6333" }),
priority: 2,
}),
];
```
Here, we've setup three memory blocks:
- `staticBlock`: A static memory block that stores some core information about the user. This information will always be inserted into the memory. The type used is `MessageContent` to support multi-modal content.
- `factExtractionBlock`: An extracted memory block that will extract information from the chat history. Here we've passed in the `llm` to use to extract facts from the chat history, and set the `maxFacts` to 50. If the number of extracted facts exceeds this limit, the `maxFacts` will be automatically summarized and reduced to leave room for new information.
- `vectorBlock`: A vector memory block that will store in a vector database and retrieve them from there. Messages are stored individually and retrieved based on their relevance to recent conversation context. Here we've passed in the `vectorStore` to use to store and retrieve the chat messages.
You'll also notice that we've set the `priority` for the `factExtractionBlock` block. This is used to determine the handling when the memory blocks content (i.e. long-term memory) + short-term memory exceeds the token limit on the `Memory` object.
- `priority=0`: This block will always be kept in memory (`staticBlocks` always have priority 0.)
- `priority=1, 2, 3, etc`: This determines the order in which memory blocks are truncated when the memory exceeds the token limit, to help the overall short-term memory + long-term memory content be less than or equal to the `tokenLimit`.
Now, let's pass these blocks into the `createMemory` function:
```ts
const memory = createMemory({
tokenLimit: 40000,
memoryBlocks: memoryBlocks,
)
```
When memory is retrieved (using `getLLM`), the short-term and long-term memories are merged together. The `Memory` object will ensure that the short-term memory + long-term memory content is less than or equal to the `tokenLimit`. If it is longer, messages are retrieved in the following order:
1. StaticMemoryBlock (information always included)
2. LongTermMemoryBlock (depending on priority)
3. ShortTermMemoryBlock
4. Transient messages
The amount of short-term memory included is specified by the `shortTermTokenLimitRatio`. If it's set to `0.7`, 70% of the `tokenLimit` is used for short-term memory (not including the static memory block).
#### VectorBlock Configuration Options
The `vectorBlock` offers several configuration options to customize its behavior:
```ts
vectorBlock({
vectorStore: new QdrantVectorStore({ url: "http://localhost:6333" }),
priority: 2,
retrievalContextWindow: 5, // Number of recent messages to use for context when retrieving
formatTemplate: new PromptTemplate({ template: "Context: {{ context }}" }), // Custom formatting template
nodePostprocessors: [/* custom postprocessors */], // Apply processing to retrieved nodes
queryOptions: {
similarityTopK: 3, // Number of top similar results to return (default: 2)
mode: VectorStoreQueryMode.DEFAULT, // Query mode for the vector store
sessionFilterKey: "session_id", // Metadata key for session filtering (default: "session_id")
// Custom filters can be added here - session filter is automatically included
filters: {
filters: [
{ key: "custom_field", value: "custom_value", operator: "==" }
],
condition: "and"
}
}
})
```
**Key Configuration Options:**
- **`retrievalContextWindow`**: Number of recent messages to consider when creating the retrieval query (default: 5). A larger window provides more context but may be less precise.
- **`formatTemplate`**: Template for formatting retrieved information before adding to memory. Defaults to a simple context template.
- **`nodePostprocessors`**: Array of postprocessors to apply to retrieved nodes, useful for filtering or transforming results.
- **`queryOptions.similarityTopK`**: Number of most similar messages to retrieve from the vector store (default: 2).
- **`queryOptions.sessionFilterKey`**: Metadata key used to isolate memory between different sessions (default: "session_id").
- **`queryOptions.filters`**: Additional metadata filters for retrieval. The session filter is automatically added to ensure memory isolation.
**Session Isolation:**
The vectorBlock automatically adds a session filter using the block's ID to ensure that memories from different sessions don't interfere with each other. This filter uses the `sessionFilterKey` (default: "session_id") and can be customized if needed.
## Persistence with Snapshots
Save and restore memory state:
```ts twoslash
import { createMemory, loadMemory } from "llamaindex";
const memory = createMemory();
// Add some messages
await memory.add({ role: "user", content: "Hello!" });
// Create snapshot
const snapshot = memory.snapshot();
// Later, restore from the snapshot
const restoredMemory = loadMemory(snapshot);
```
## Examples
Want to learn more about the Memory class? Check out our example codes in [Github](https://github.com/run-llama/LlamaIndexTS/tree/main/examples/agents/memory).
@@ -1,2 +0,0 @@
label: Readers
collapsed: true

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