Compare commits

..

36 Commits

Author SHA1 Message Date
Marcus Schiesser 951f215723 Merge branch 'main' into feat/build-wasm-with-extism 2024-09-16 15:40:17 +07:00
Alex Yang 7eb331774d chore: bump typescript (#1205) 2024-09-13 13:18:35 -07:00
Alex Yang 24a3f058a3 chore: update build script (#1204) 2024-09-13 11:44:40 -07:00
Fabian Wimmer 84c28f95f9 docs: restructure, add API references (#1196) 2024-09-13 11:22:37 -07:00
Alex Yang 7af57982fe test: enable dom & edge runtime (#1203) 2024-09-13 10:43:18 -07:00
Aaron Ji 6b70c5408f chore: update JinaEmbedding for v3 release (#1187) 2024-09-13 09:44:43 -07:00
Thuc Pham 9447654332 Create shy-bottles-shop.md 2024-09-12 14:42:33 +07:00
Thuc Pham 3293c22ade Merge branch 'main' into feat/build-wasm-with-extism 2024-09-12 14:41:43 +07:00
Thuc Pham 33d57d1caf update test 2024-09-12 14:24:10 +07:00
Thuc Pham 92d0d098ab add todo tool example 2024-09-12 14:14:18 +07:00
Thuc Pham f76abceb8f refactor: remove enum 2024-09-12 14:09:34 +07:00
Thuc Pham 191986b337 refactor: create tool class params 2024-09-12 13:59:17 +07:00
Thuc Pham d718f4334e fix: upgrade extism to fix worker bug 2024-09-12 13:47:57 +07:00
Thuc Pham f34ea4563a Merge branch 'main' into feat/build-wasm-with-extism 2024-09-11 09:45:52 +07:00
Thuc Pham fda48fae63 fix: wrong path ts config.json 2024-09-09 18:43:14 +07:00
Thuc Pham 660eab8045 fix: e2e 2024-09-09 18:41:50 +07:00
Thuc Pham d95ed78ca4 fix: lint depend on build 2024-09-09 18:36:05 +07:00
Thuc Pham 8a73dac583 test wiki 2024-09-09 18:32:24 +07:00
Thuc Pham f7b666e24a refactor: add package.json to examples 2024-09-09 18:24:39 +07:00
Thuc Pham d48724fa1e fix: update doc 2024-09-09 17:28:01 +07:00
Thuc Pham 879c15f951 fix: lint 2024-09-09 17:22:34 +07:00
Thuc Pham 6cc8595d44 fix: typo and use same d.ts file for all tools 2024-09-09 17:20:22 +07:00
Thuc Pham 7710d9669f add getMetadata to wiki python example 2024-09-09 12:18:29 +07:00
Thuc Pham 1eddb6e8f3 export type 2024-09-09 12:13:04 +07:00
Thuc Pham 54abd709b2 feat: example with agent 2024-09-09 12:10:15 +07:00
Thuc Pham 507012a0c9 feat: ExtismToolFactory 2024-09-09 12:01:36 +07:00
Thuc Pham 4b74096fb6 update readme 2024-09-06 17:59:02 +07:00
Thuc Pham dfb6c2563a feat: add js example 2024-09-06 17:55:14 +07:00
Thuc Pham 9df0d63821 feat: make agent example 2024-09-06 17:42:11 +07:00
Thuc Pham 5c34d3a9cc create abstract ExtismTool 2024-09-06 17:08:13 +07:00
Thuc Pham fbb5ece07e fix: install extism for all tests 2024-09-06 16:39:05 +07:00
Thuc Pham de4d8ffb1d install extism for all actions 2024-09-06 16:34:42 +07:00
Thuc Pham efbd61f124 install extism-js 2024-09-06 16:30:15 +07:00
Thuc Pham ecc54cb540 fix: lock 2024-09-06 16:09:42 +07:00
Thuc Pham 02c81989c6 feat: detach packages for extism 2024-09-06 16:07:55 +07:00
Thuc Pham ccfc11c8cb feat: build wasm with extism 2024-09-06 12:39:28 +07:00
80 changed files with 2347 additions and 1362 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"llamaindex": patch
---
feat: update JinaAIEmbedding, support embedding v3
+5
View File
@@ -0,0 +1,5 @@
---
"@llamaindex/extism-tools": patch
---
Build WASM tools with extism
@@ -19,6 +19,10 @@ jobs:
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Run lint
+5
View File
@@ -18,6 +18,11 @@ jobs:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
+5
View File
@@ -23,6 +23,11 @@ jobs:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
+20
View File
@@ -42,6 +42,10 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Run E2E Tests
@@ -62,6 +66,10 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Run tests
@@ -77,6 +85,10 @@ jobs:
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Build
@@ -114,6 +126,10 @@ jobs:
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Build llamaindex
@@ -133,6 +149,10 @@ jobs:
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install Extism
run: |
curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh
- name: Install dependencies
run: pnpm install
- name: Build
+1 -1
View File
@@ -1,2 +1,2 @@
label: "Agents"
position: 3
position: 10
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 13
---
# ChatEngine
+2 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 12
---
# Index
@@ -8,6 +8,7 @@ An index is the basic container and organization for your data. LlamaIndex.TS su
- `VectorStoreIndex` - will send the top-k `Node`s to the LLM when generating a response. The default top-k is 2.
- `SummaryIndex` - will send every `Node` in the index to the LLM in order to generate a response
- `KeywordTableIndex` extracts and provides keywords from `Node`s to the LLM
```typescript
import { Document, VectorStoreIndex } from "llamaindex";
@@ -6,6 +6,19 @@ import CodeSource2 from "!raw-loader!../../../../../examples/readers/src/custom-
Before you can start indexing your documents, you need to load them into memory.
All "basic" data loaders can be seen below, mapped to their respective filetypes in `SimpleDirectoryReader`. More loaders are shown in the sidebar on the left.
Additionally the following loaders exist without separate documentation:
- `AssemblyAIReader` transcribes audio using [AssemblyAI](https://www.assemblyai.com/).
- [AudioTranscriptReader](../../api/classes/AudioTranscriptReader.md): loads entire transcript as a single document.
- [AudioTranscriptParagraphsReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document per paragraph.
- [AudioTranscriptSentencesReader](../../api/classes/AudioTranscriptSentencesReader.md): creates a document per sentence.
- [AudioSubtitlesReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document containing the subtitles of a transcript.
- [NotionReader](../../api/classes/NotionReader.md) loads [Notion](https://www.notion.so/) pages.
- [SimpleMongoReader](../../api/classes/SimpleMongoReader) loads data from a [MongoDB](https://www.mongodb.com/).
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## SimpleDirectoryReader
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples/readers?file=src/simple-directory-reader.ts&title=Simple%20Directory%20Reader)
@@ -0,0 +1,2 @@
label: "Data Stores"
position: 2
@@ -0,0 +1 @@
label: "Chat Stores"
@@ -0,0 +1,13 @@
# Chat Stores
Chat stores manage chat history by storing sequences of messages in a structured way, ensuring the order of messages is maintained for accurate conversation flow.
## Available Chat Stores
- [SimpleChatStore](../../../api/classes/SimpleChatStore.md): A simple in-memory chat store with support for [persisting](../index.md#local-storage) data to disk.
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [BaseChatStore](../../../api/interfaces/BaseChatStore.md)
@@ -0,0 +1,2 @@
label: "Document Stores"
position: 2
@@ -0,0 +1,14 @@
# Document Stores
Document stores contain ingested document chunks, i.e. [Node](../../documents_and_nodes/index.md)s.
## Available Document Stores
- [SimpleDocumentStore](../../../api/classes/SimpleDocumentStore.md): A simple in-memory document store with support for [persisting](../index.md#local-storage) data to disk.
- [PostgresDocumentStore](../../../api/classes/PostgresDocumentStore.md): A PostgreSQL document store, see [PostgreSQL Storage](../index.md#postgresql-storage).
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [BaseDocumentStore](../../../api/classes/BaseDocumentStore.md)
@@ -1,7 +1,3 @@
---
sidebar_position: 7
---
# Storage
Storage in LlamaIndex.TS works automatically once you've configured a
@@ -57,4 +53,4 @@ const index = await VectorStoreIndex.fromDocuments([document], {
## API Reference
- [StorageContext](../api/interfaces/StorageContext.md)
- [StorageContext](../../api/interfaces/StorageContext.md)
@@ -0,0 +1,2 @@
label: "Index Stores"
position: 3
@@ -0,0 +1,14 @@
# Index Stores
Index stores are underlying storage components that contain metadata(i.e. information created when indexing) about the [index](../../data_index.md) itself.
## Available Index Stores
- [SimpleIndexStore](../../../api/classes/SimpleIndexStore.md): A simple in-memory index store with support for [persisting](../index.md#local-storage) data to disk.
- [PostgresIndexStore](../../../api/classes/PostgresIndexStore.md): A PostgreSQL index store, , see [PostgreSQL Storage](../index.md#postgresql-storage).
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [BaseIndexStore](../../../api/classes/BaseIndexStore.md)
@@ -0,0 +1,2 @@
label: "Key-Value Stores"
position: 4
@@ -0,0 +1,14 @@
# Key-Value Stores
Key-Value Stores represent underlying storage components used in [Document Stores](../doc_stores/index.md) and [Index Stores](../index_stores/index.md)
## Available Key-Value Stores
- [SimpleKVStore](../../../api/classes/SimpleKVStore.md): A simple Key-Value store with support of [persisting](../index.md#local-storage) data to disk.
- [PostgresKVStore](../../../api/classes/PostgresKVStore.md): A PostgreSQL Key-Value store, see [PostgreSQL Storage](../index.md#postgresql-storage).
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [BaseKVStore](../../../api/classes/BaseKVStore.md)
@@ -0,0 +1,22 @@
# Vector Stores
Vector stores save embedding vectors of your ingested document chunks.
## Available Vector Stores
Available Vector Stores are shown on the sidebar to the left. Additionally the following integrations exist without separate documentation:
- [SimpleVectorStore](../../../api/classes/SimpleVectorStore.md): A simple in-memory vector store with optional [persistance](../index.md#local-storage) to disk.
- [AstraDBVectorStore](../../../api/classes/AstraDBVectorStore.md): A cloud-native, scalable Database-as-a-Service built on Apache Cassandra, see [datastax.com](https://www.datastax.com/products/datastax-astra)
- [ChromaVectorStore](../../../api/classes/ChromaVectorStore.md): An open-source vector database, focused on ease of use and performance, see [trychroma.com](https://www.trychroma.com/)
- [MilvusVectorStore](../../../api/classes/MilvusVectorStore.md): An open-source, high-performance, highly scalable vector database, see [milvus.io](https://milvus.io/)
- [MongoDBAtlasVectorSearch](../../../api/classes/MongoDBAtlasVectorSearch.md): A cloud-based vector search solution for MongoDB, see [mongodb.com](https://www.mongodb.com/products/platform/atlas-vector-search)
- [PGVectorStore](../../../api/classes/PGVectorStore.md): An open-source vector store built on PostgreSQL, see [pgvector Github](https://github.com/pgvector/pgvector)
- [PineconeVectorStore](../../../api/classes/PineconeVectorStore.md): A managed, cloud-native vector database, see [pinecone.io](https://www.pinecone.io/)
- [WeaviateVectorStore](../../../api/classes/WeaviateVectorStore.md): An open-source, ai-native vector database, see [weaviate.io](https://weaviate.io/)
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [VectorStoreBase](../../../api/classes/VectorStoreBase.md)
@@ -1,5 +1,7 @@
# Qdrant Vector Store
[qdrant.tech](https://qdrant.tech/)
To run this example, you need to have a Qdrant instance running. You can run it with Docker:
```bash
@@ -87,4 +89,4 @@ main().catch(console.error);
## API Reference
- [QdrantVectorStore](../../api/classes/QdrantVectorStore.md)
- [QdrantVectorStore](../../../api/classes/QdrantVectorStore.md)
@@ -1,7 +1,3 @@
---
sidebar_position: 1
---
# Documents and Nodes
`Document`s and `Node`s are the basic building blocks of any index. While the API for these objects is similar, `Document` objects represent entire files, while `Node`s are smaller pieces of that original document, that are suitable for an LLM and Q&A.
@@ -1,2 +1,2 @@
label: "Embeddings"
position: 3
position: 6
@@ -7,7 +7,7 @@ To find out more about the latest features, updates, and available models, visit
## Table of Contents
1. [Setup](#setup)
2. [Usage with LlamaIndex](#integration-with-llamaindex)
2. [Usage with LlamaIndex](#usage-with-llamaindex)
3. [Embeddings with Custom Parameters](#embeddings-with-custom-parameters)
## Setup
@@ -16,6 +16,16 @@ Settings.embedModel = new OpenAIEmbedding({
For local embeddings, you can use the [HuggingFace](./available_embeddings/huggingface.md) embedding model.
## Available Embeddings
Most available embeddings are listed in the sidebar on the left.
Additionally the following integrations exist without separate documentation:
- [ClipEmbedding](../../api/classes/ClipEmbedding.md) using `@xenova/transformers`
- [FireworksEmbedding](../../api/classes/FireworksEmbedding.md) see [fireworks.ai](https://fireworks.ai/)
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [OpenAIEmbedding](../../api/classes/OpenAIEmbedding.md)
@@ -1,2 +1,2 @@
label: "Evaluating"
position: 3
position: 9
@@ -1,2 +1,2 @@
label: "Ingestion Pipeline"
position: 2
position: 4
+1 -1
View File
@@ -1,2 +1,2 @@
label: "LLMs"
position: 3
position: 5
@@ -1,6 +1,6 @@
# Fireworks LLM
Fireworks.ai focus on production use cases for open source LLMs, offering speed and quality.
[Fireworks.ai](https://fireworks.ai/) focus on production use cases for open source LLMs, offering speed and quality.
## Usage
+9 -4
View File
@@ -1,7 +1,3 @@
---
sidebar_position: 3
---
# Large Language Models (LLMs)
The LLM is responsible for reading text and generating natural language responses to queries. By default, LlamaIndex.TS uses `gpt-3.5-turbo`.
@@ -30,6 +26,15 @@ export AZURE_OPENAI_DEPLOYMENT="gpt-4" # or some other deployment name
For local LLMs, currently we recommend the use of [Ollama](./available_llms/ollama.md) LLM.
## Available LLMs
Most available LLMs are listed in the sidebar on the left. Additionally the following integrations exist without separate documentation:
- [HuggingFaceLLM](../../api/classes/HuggingFaceLLM.md) and [HuggingFaceInferenceAPI](../../api/classes/HuggingFaceInferenceAPI.md).
- [ReplicateLLM](../../api/classes/ReplicateLLM.md) see [replicate.com](https://replicate.com/)
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
## API Reference
- [OpenAI](../../api/classes/OpenAI.md)
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 11
---
# NodeParser
@@ -107,3 +107,4 @@ const filteredNodes = processor.postprocessNodes(nodes);
## API Reference
- [SimilarityPostprocessor](../../api/classes/SimilarityPostprocessor.md)
- [MetadataReplacementPostProcessor](../../api/classes/MetadataReplacementPostProcessor.md)
@@ -7,7 +7,7 @@ To find out more about the latest features and updates, visit the [mixedbread.ai
## Table of Contents
1. [Setup](#setup)
2. [Usage with LlamaIndex](#integration-with-llamaindex)
2. [Usage with LlamaIndex](#usage-with-llamaindex)
3. [Simple Reranking Guide](#simple-reranking-guide)
4. [Reranking with Objects](#reranking-with-objects)
+1 -1
View File
@@ -1,2 +1,2 @@
label: "Prompts"
position: 0
position: 7
-1
View File
@@ -73,6 +73,5 @@ const response = await queryEngine.query({
## API Reference
- [TextQaPrompt](../../api/type-aliases/TextQaPrompt.md)
- [ResponseSynthesizer](../../api/classes/ResponseSynthesizer.md)
- [CompactAndRefine](../../api/classes/CompactAndRefine.md)
@@ -1,2 +1,2 @@
label: "Query Engines"
position: 2
position: 8
@@ -1,5 +1,5 @@
---
sidebar_position: 6
sidebar_position: 15
---
# ResponseSynthesizer
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 5
sidebar_position: 14
---
# Retriever
+1 -1
View File
@@ -37,7 +37,7 @@
"docusaurus-plugin-typedoc": "1.0.5",
"typedoc": "0.26.6",
"typedoc-plugin-markdown": "4.2.6",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
},
"browserslist": {
"production": [
+1 -1
View File
@@ -21,7 +21,7 @@
"devDependencies": {
"@types/node": "^22.5.1",
"tsx": "^4.19.0",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
},
"scripts": {
"lint": "eslint ."
+1 -1
View File
@@ -23,6 +23,6 @@
"devDependencies": {
"@types/node": "^22.5.1",
"tsx": "^4.19.0",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
}
}
+4 -4
View File
@@ -2,9 +2,9 @@
"name": "@llamaindex/monorepo",
"private": true,
"scripts": {
"build": "turbo run build --filter=\"!docs\" --filter=\"!*-test\" --filter=\"!*-example\"",
"build:release": "turbo run build lint test --filter=\"!docs\" --filter=\"!*-test\" --filter=\"!*-example\"",
"dev": "turbo run dev",
"build": "turbo run build",
"build:release": "turbo run build --filter=\"./packages/*\"",
"dev": "turbo run dev --filter=\"./packages/*\"",
"format": "prettier --ignore-unknown --cache --check .",
"format:write": "prettier --ignore-unknown --write .",
"lint": "turbo run lint",
@@ -31,7 +31,7 @@
"prettier": "^3.3.3",
"prettier-plugin-organize-imports": "^4.0.0",
"turbo": "^2.1.0",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
},
"packageManager": "pnpm@9.5.0",
"pnpm": {
@@ -5,9 +5,9 @@ import { runWithStreamableUI } from "@/context";
import "@/tool";
import { convertTools } from "@llamaindex/autotool";
import { createStreamableUI } from "ai/rsc";
import type { JSX } from "react";
import type { ReactNode } from "react";
export async function chatWithAI(message: string): Promise<JSX.Element> {
export async function chatWithAI(message: string): Promise<ReactNode> {
const agent = new OpenAIAgent({
tools: convertTools("llamaindex"),
});
@@ -25,7 +25,7 @@ export async function chatWithAI(message: string): Promise<JSX.Element> {
uiStream.append("\n");
},
write: async (message) => {
uiStream.append(message.response.delta);
uiStream.append(message.response);
},
close: () => {
uiStream.done();
@@ -32,6 +32,6 @@
"cross-env": "^7.0.3",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.10",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
}
}
+2 -2
View File
@@ -51,7 +51,7 @@
"unplugin": "^1.12.2"
},
"peerDependencies": {
"llamaindex": "^0.6.0",
"llamaindex": "workspace:*",
"openai": "^4",
"typescript": "^4"
},
@@ -75,7 +75,7 @@
"next": "14.2.7",
"rollup": "^4.21.2",
"tsx": "^4.19.0",
"typescript": "^5.5.4",
"typescript": "^5.6.2",
"vitest": "^2.0.5",
"webpack": "^5.94.0"
}
+2 -2
View File
@@ -9,7 +9,7 @@ import td from "typedoc";
import type { SourceMapCompact } from "unplugin";
import type { InfoString } from "./internal";
export const isToolFile = (url: string) => /tool\.[jt]sx?$/.test(url);
export const isToolFile = (url: string) => /\.tool\.[jt]sx?$/.test(url);
export const isJSorTS = (url: string) => /\.m?[jt]sx?$/.test(url);
async function parseRoot(entryPoint: string) {
@@ -28,7 +28,7 @@ async function parseRoot(entryPoint: string) {
if (project) {
return app.serializer.projectToObject(project, process.cwd());
}
throw new Error("Failed to parse root");
throw new Error(`Failed to parse root ${entryPoint}`);
}
export async function transformAutoTool(
+2
View File
@@ -172,8 +172,10 @@
"url": "https://github.com/himself65/LlamaIndexTS.git"
},
"devDependencies": {
"@edge-runtime/vm": "^4.0.3",
"ajv": "^8.17.1",
"bunchee": "5.3.2",
"happy-dom": "^15.7.4",
"natural": "^8.0.1",
"python-format-js": "^1.4.3"
},
+1 -1
View File
@@ -95,7 +95,7 @@ export class Context {
this.#streamingQueue.push(event);
}
async *streamEvents(): AsyncGenerator<WorkflowEvent, void, undefined> {
async *streamEvents(): AsyncGenerator<WorkflowEvent, void, void> {
while (true) {
const event = this.#streamingQueue.shift();
if (event) {
+1 -1
View File
@@ -62,7 +62,7 @@ export class Workflow {
return stepInfo.inputs.includes(eventType);
}
async *streamEvents(): AsyncGenerator<WorkflowEvent, void, unknown> {
async *streamEvents(): AsyncGenerator<WorkflowEvent, void> {
if (this.#contexts.size > 1) {
throw new Error(
"This workflow has multiple concurrent runs in progress and cannot stream events. " +
+19
View File
@@ -0,0 +1,19 @@
import { defineWorkspace } from "vitest/config";
export default defineWorkspace([
{
test: {
environment: "edge-runtime",
},
},
{
test: {
environment: "happy-dom",
},
},
{
test: {
environment: "node",
},
},
]);
+24
View File
@@ -0,0 +1,24 @@
## Extism Tools
### Prerequisites for Development
- [Extism PDK](https://github.com/extism/js-pdk?tab=readme-ov-file#linux-macos)
### Build WASM files
```bash
pnpm run build
```
### Run WASM files in Node.js using Extism SDK (https://github.com/extism/js-sdk)
```bash
cd examples
pnpm run test:wiki
```
### Run WASM files in Python using Extism SDK (https://github.com/extism/python-sdk)
```bash
python examples/wasm/wiki.py
```
+31
View File
@@ -0,0 +1,31 @@
// needed as extism-js doesn't support compiling multiple files
import { execSync } from "child_process";
import { mkdirSync, readdirSync } from "fs";
const WASM_SRC_FOLDER = "wasm";
const WASM_OUTPUT_FOLDER = "dist/wasm";
// get list of tools from files (except index.d.ts)
const tools = readdirSync(WASM_SRC_FOLDER)
.filter((file) => !file.includes("index.d.ts"))
.map((file) => file.split(".")[0]);
// create dist/wasm folder if it doesn't exist using fs
try {
mkdirSync(WASM_OUTPUT_FOLDER, { recursive: true });
} catch (error) {
console.error("Error creating dist/wasm folder:", error.message);
process.exit(1);
}
// loop through each tool, compile it to wasm using extism-js
tools.forEach((tool) => {
try {
execSync(
`extism-js ${WASM_SRC_FOLDER}/${tool}.js -i ${WASM_SRC_FOLDER}/index.d.ts -o ${WASM_OUTPUT_FOLDER}/${tool}.wasm`,
);
} catch (error) {
console.error(`Error compiling module ${tool}:`, error.message);
process.exit(1);
}
});
@@ -0,0 +1,17 @@
{
"name": "@llamaindex/extism-tools-examples",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"test:wiki": "tsx ./src/wiki.ts",
"test:todo": "tsx ./src/todo.ts"
},
"dependencies": {
"@llamaindex/extism-tools": "workspace:*",
"llamaindex": "workspace:*"
},
"devDependencies": {
"tsx": "^4.19.0"
}
}
@@ -0,0 +1,13 @@
import { ExtismToolFactory } from "@llamaindex/extism-tools";
import { OpenAI, OpenAIAgent, Settings } from "llamaindex";
async function main() {
const TodoTool = await ExtismToolFactory.createToolClass("todo");
const todoTool = new TodoTool();
Settings.llm = new OpenAI();
const agent = new OpenAIAgent({ tools: [todoTool] });
const result = await agent.chat({ message: "Get first todo" });
console.log(result.message);
}
void main();
@@ -0,0 +1,34 @@
import extism
import json
from os.path import join, dirname
def read_local_wasm(file_name):
path = join(dirname(__file__), file_name) # Change this to your wasm file path
with open(path, "rb") as wasm_file:
return wasm_file.read()
def _manifest(file_name):
wasm = read_local_wasm(file_name)
return {
"wasm": [{"data": wasm}],
"allowed_hosts": ["*.wikipedia.org"],
}
manifest = _manifest("wiki.wasm")
with extism.Plugin(manifest, wasi=True) as plugin:
metadata = plugin.call(
"getMetadata",
"",
parse=lambda output: json.loads(bytes(output).decode("utf-8")),
)
data = plugin.call(
"call",
json.dumps({"query": "Ho Chi Minh City"}),
parse=lambda output: json.loads(bytes(output).decode("utf-8")),
)
print(metadata)
print(data)
@@ -0,0 +1,13 @@
import { ExtismToolFactory } from "@llamaindex/extism-tools";
import { OpenAI, OpenAIAgent, Settings } from "llamaindex";
async function main() {
const WikiTool = await ExtismToolFactory.createToolClass("wiki");
const wikiTool = new WikiTool();
Settings.llm = new OpenAI();
const agent = new OpenAIAgent({ tools: [wikiTool] });
const result = await agent.chat({ message: "Ho Chi Minh City" });
console.log(result.message);
}
void main();
@@ -0,0 +1,9 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "./lib",
"module": "node16",
"moduleResolution": "node16"
},
"include": ["./src"]
}
+62
View File
@@ -0,0 +1,62 @@
{
"name": "@llamaindex/extism-tools",
"version": "0.0.1",
"license": "MIT",
"type": "module",
"dependencies": {
"@extism/extism": "^2.0.0-rc8",
"ajv": "^8.17.1",
"@llamaindex/core": "workspace:*",
"@llamaindex/env": "workspace:*",
"llamaindex": "workspace:*"
},
"devDependencies": {
"@swc/cli": "^0.4.0",
"@swc/core": "^1.7.22",
"typescript": "^5.5.4",
"@types/node": "^22.5.1"
},
"engines": {
"node": ">=18.0.0"
},
"types": "./dist/index.d.ts",
"main": "./dist/cjs/index.js",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/cjs/index.js"
}
},
"./*": {
"import": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"
},
"require": {
"types": "./dist/*.d.ts",
"default": "./dist/cjs/*.js"
}
}
},
"files": [
"dist",
"CHANGELOG.md"
],
"repository": {
"type": "git",
"url": "https://github.com/run-llama/LlamaIndexTS.git",
"directory": "packages/extism-tools"
},
"scripts": {
"build": "rm -rf ./dist && pnpm run build:wasm && pnpm run build:esm && pnpm run build:cjs && pnpm run build:type",
"build:esm": "swc src -d dist --strip-leading-paths --config-file ../../.swcrc",
"build:cjs": "swc src -d dist/cjs --strip-leading-paths --config-file ../../.cjs.swcrc",
"build:type": "tsc -p tsconfig.json",
"build:wasm": "node bin/compile.js"
}
}
@@ -0,0 +1,82 @@
import createPlugin, { type Plugin } from "@extism/extism";
import type { JSONSchemaType } from "ajv";
import type { BaseToolWithCall, ToolMetadata } from "llamaindex";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export const WASM_DIRECTORY = path.join(__dirname, "..", "dist", "wasm");
export const DEFAULT_MAX_HTTP_RESPONSE_BYTES = 100 * 1024 * 1024; // 100 MB
export type ToolParams = Record<string, any>;
export type ToolClassParams = {
metadata?: ToolMetadata<JSONSchemaType<ToolParams>>;
};
export type CreateToolClassParams = {
wasmFilename: string;
allowedHosts: string[];
maxHttpResponseBytes: number;
transformResponse: (response: any) => any;
};
export const createPluginInstance = async (
params: Omit<CreateToolClassParams, "transformResponse">,
): Promise<Plugin> => {
const { wasmFilename, allowedHosts, maxHttpResponseBytes } = params;
const plugin = await createPlugin(`${WASM_DIRECTORY}/${wasmFilename}`, {
useWasi: true,
runInWorker: true,
allowedHosts,
memory: { maxHttpResponseBytes },
});
return plugin;
};
export const DEFAULT_TOOL_PARAMS: Omit<CreateToolClassParams, "wasmFilename"> =
{
allowedHosts: ["*"],
maxHttpResponseBytes: DEFAULT_MAX_HTTP_RESPONSE_BYTES,
transformResponse: (response: any) => response,
};
export class ExtismToolFactory {
static async createToolClass(
toolName: string,
params: Omit<CreateToolClassParams, "wasmFilename"> = DEFAULT_TOOL_PARAMS,
): Promise<new (params?: ToolClassParams) => BaseToolWithCall<ToolParams>> {
const config = { ...params, wasmFilename: `${toolName}.wasm` };
const plugin = await createPluginInstance(config);
try {
const wasmMetadata = await plugin.call("getMetadata");
if (!wasmMetadata) {
throw new Error("The WASM plugin did not return metadata.");
}
const defaultMetadata = wasmMetadata.json();
return class implements BaseToolWithCall<ToolParams> {
metadata: ToolMetadata<JSONSchemaType<ToolParams>>;
constructor(params?: ToolClassParams) {
this.metadata = params?.metadata || defaultMetadata;
}
async call(input: ToolParams): Promise<string> {
const pluginInstance = await createPluginInstance(config);
const data = await pluginInstance.call("call", JSON.stringify(input));
if (!data) return "No result";
const result = config.transformResponse(data.json());
await pluginInstance.close();
return result;
}
};
} catch (e) {
console.error(e);
throw new Error("Failed to create Tool instance.");
} finally {
await plugin.close();
}
}
}
+1
View File
@@ -0,0 +1 @@
export { ExtismToolFactory } from "./ExtismToolFactory.js";
+21
View File
@@ -0,0 +1,21 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/.tsbuildinfo",
"emitDeclarationOnly": true,
"module": "node16",
"moduleResolution": "node16",
"skipLibCheck": true,
"strict": true,
"types": ["node"]
},
"include": ["./src"],
"exclude": ["node_modules"],
"references": [
{
"path": "../env/tsconfig.json"
}
]
}
+4
View File
@@ -0,0 +1,4 @@
declare module "main" {
export function getMetadata(): I32;
export function call(): I32;
}
+34
View File
@@ -0,0 +1,34 @@
function getMetadata() {
const metadata = {
name: "todo_tool",
description: "A tool helps search todo.",
parameters: {
type: "object",
properties: {
index: {
type: "number",
description: "The index of the todo to search for.",
},
},
required: ["index"],
},
};
Host.outputString(JSON.stringify(metadata));
}
function call() {
const params = JSON.parse(Host.inputString());
const index = params?.index;
if (!index) throw new Error("No index provided");
const request = {
method: "GET",
url: `https://jsonplaceholder.typicode.com/todos/${encodeURIComponent(index)}`,
};
const response = Http.request(request);
if (response.status != 200)
throw new Error(`Got non 200 response ${response.status}`);
Host.outputString(response.body);
}
module.exports = { getMetadata, call };
+33
View File
@@ -0,0 +1,33 @@
function getMetadata() {
const metadata = {
name: "wikipedia_tool",
description: "A tool that uses a query engine to search Wikipedia.",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "The query to search for",
},
},
required: ["query"],
},
};
Host.outputString(JSON.stringify(metadata));
}
function call() {
const params = JSON.parse(Host.inputString());
const query = params?.query;
if (!query) throw new Error("No query provided");
const request = {
method: "GET",
url: `https://en.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(query)}`,
};
const response = Http.request(request);
if (response.status != 200)
throw new Error(`Got non 200 response ${response.status}`);
Host.outputString(response.body);
}
module.exports = { getMetadata, call };
@@ -16,7 +16,7 @@
"@cloudflare/workers-types": "^4.20240821.1",
"@vitest/runner": "1.5.3",
"@vitest/snapshot": "1.5.3",
"typescript": "^5.5.4",
"typescript": "^5.6.2",
"vitest": "1.5.3",
"wrangler": "^3.73.0"
},
@@ -23,6 +23,6 @@
"eslint-config-next": "14.2.7",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.10",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
}
}
@@ -17,6 +17,6 @@
"@types/node": "^22.5.1",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
}
}
@@ -22,6 +22,6 @@
"eslint-config-next": "14.2.7",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.10",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
}
}
@@ -20,7 +20,7 @@
"@types/react-dom": "18.3.0",
"autoprefixer": "10.4.20",
"tailwindcss": "3.4.10",
"typescript": "5.5.4",
"typescript": "5.6.2",
"vite-plugin-wasm": "^3.3.0"
}
}
+1 -1
View File
@@ -94,7 +94,7 @@
"glob": "^11.0.0",
"pg": "^8.12.0",
"pgvector": "0.2.0",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
},
"engines": {
"node": ">=18.0.0"
@@ -8,10 +8,20 @@ function isLocal(url: ImageType): boolean {
return new URL(url).protocol === "file:";
}
type TaskType =
| "retrieval.passage"
| "retrieval.query"
| "separation"
| "classification"
| "text-matching";
type EncodingType = "float" | "binary" | "ubinary";
export type JinaEmbeddingRequest = {
input: Array<{ text: string } | { url: string } | { bytes: string }>;
model?: string;
encoding_type?: "float" | "binary" | "ubinary";
encoding_type?: EncodingType;
task_type?: TaskType;
dimensions?: number;
};
export type JinaEmbeddingResponse = {
@@ -34,6 +44,9 @@ export class JinaAIEmbedding extends MultiModalEmbedding {
apiKey: string;
model: string;
baseURL: string;
taskType: TaskType | undefined;
encodingType?: EncodingType | undefined;
dimensions?: number | undefined;
async getTextEmbedding(text: string): Promise<number[]> {
const result = await this.getJinaEmbedding({ input: [{ text }] });
@@ -71,9 +84,11 @@ export class JinaAIEmbedding extends MultiModalEmbedding {
);
}
this.apiKey = apiKey;
this.model = init?.model ?? "jina-embeddings-v2-base-en";
this.model = init?.model ?? "jina-embeddings-v3";
this.baseURL = init?.baseURL ?? "https://api.jina.ai/v1/embeddings";
init?.embedBatchSize && (this.embedBatchSize = init?.embedBatchSize);
this.taskType = init?.taskType;
this.encodingType = init?.encodingType;
}
private async getImageInput(
@@ -89,11 +104,11 @@ export class JinaAIEmbedding extends MultiModalEmbedding {
}
private async getJinaEmbedding(
input: JinaEmbeddingRequest,
params: JinaEmbeddingRequest,
): Promise<JinaEmbeddingResponse> {
// if input includes image, check if model supports multimodal embeddings
if (
input.input.some((i) => "url" in i || "bytes" in i) &&
params.input.some((i) => "url" in i || "bytes" in i) &&
!JINA_MULTIMODAL_MODELS.includes(this.model)
) {
throw new Error(
@@ -109,13 +124,17 @@ export class JinaAIEmbedding extends MultiModalEmbedding {
},
body: JSON.stringify({
model: this.model,
encoding_type: "float",
...input,
encoding_type: this.encodingType ?? "float",
...(this.taskType && { task_type: this.taskType }),
...(this.dimensions !== undefined && { dimensions: this.dimensions }),
...params,
}),
});
if (!response.ok) {
const reason = await response.text();
throw new Error(
`Request ${this.baseURL} failed with status ${response.status}`,
`Request failed with status ${response.status}: ${reason}`,
);
}
const result: JinaEmbeddingResponse = await response.json();
+2 -2
View File
@@ -71,8 +71,8 @@ export class Portkey extends BaseLLM {
this.baseURL = baseURL;
this.session = getPortkeySession({
...rest,
apiKey: this.apiKey,
baseURL: this.baseURL,
apiKey: this.apiKey ?? null,
baseURL: this.baseURL ?? null,
});
}
@@ -245,13 +245,13 @@ export class LlamaParseReader extends FileReader {
) {
super();
Object.assign(this, params);
params.apiKey = params.apiKey ?? getEnv("LLAMA_CLOUD_API_KEY");
if (!params.apiKey) {
const apiKey = params.apiKey ?? getEnv("LLAMA_CLOUD_API_KEY");
if (!apiKey) {
throw new Error(
"API Key is required for LlamaParseReader. Please pass the apiKey parameter or set the LLAMA_CLOUD_API_KEY environment variable.",
);
}
this.apiKey = params.apiKey;
this.apiKey = apiKey;
if (params.gpt4oMode) {
params.gpt4oApiKey =
-11
View File
@@ -1,11 +0,0 @@
import { expect, test } from "vitest";
test("Node classes should be included in the top level", async () => {
const { Document, IndexNode, TextNode, BaseNode } = await import(
"llamaindex"
);
expect(Document).toBeDefined();
expect(IndexNode).toBeDefined();
expect(TextNode).toBeDefined();
expect(BaseNode).toBeDefined();
});
+1 -1
View File
@@ -11,7 +11,7 @@
"@swc/cli": "^0.4.0",
"@swc/core": "^1.7.22",
"assemblyscript": "^0.27.27",
"typescript": "^5.5.4"
"typescript": "^5.6.2"
},
"engines": {
"node": ">=18.0.0"
+1703 -1285
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -9,3 +9,4 @@ packages:
- "packages/autotool/examples/*"
- "examples/"
- "examples/*"
- "packages/extism-tools/examples"
+6
View File
@@ -82,6 +82,12 @@
},
{
"path": "./packages/experimental/tsconfig.json"
},
{
"path": "./packages/extism-tools/tsconfig.json"
},
{
"path": "./packages/extism-tools/examples/tsconfig.json"
}
]
}