mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-19 18:43:34 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f988f4e09 | |||
| 38584f128b | |||
| 473ef072a3 |
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
---
|
||||
|
||||
fix: cannot import groq-sdk in nextjs
|
||||
@@ -13,10 +13,8 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
POSTGRES_USER: runneradmin
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
TURBO_REMOTE_ONLY: true
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
@@ -106,7 +104,6 @@ jobs:
|
||||
- nextjs-edge-runtime
|
||||
- nextjs-node-runtime
|
||||
- waku-query-engine
|
||||
- llama-parse-browser
|
||||
runs-on: ubuntu-latest
|
||||
name: Build LlamaIndex Example (${{ matrix.packages }})
|
||||
steps:
|
||||
@@ -145,12 +142,6 @@ jobs:
|
||||
- name: Pack @llamaindex/cloud
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/cloud
|
||||
- name: Pack @llamaindex/openai
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/llm/openai
|
||||
- name: Pack @llamaindex/groq
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/llm/groq
|
||||
- name: Pack @llamaindex/core
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/core
|
||||
|
||||
@@ -1,60 +1,5 @@
|
||||
# docs
|
||||
|
||||
## 0.0.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- llamaindex@0.6.4
|
||||
|
||||
## 0.0.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- Updated dependencies [5c4badb]
|
||||
- llamaindex@0.6.3
|
||||
|
||||
## 0.0.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- llamaindex@0.6.2
|
||||
|
||||
## 0.0.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [fbd5e01]
|
||||
- Updated dependencies [6b70c54]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [85c2e19]
|
||||
- llamaindex@0.6.1
|
||||
|
||||
## 0.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- llamaindex@0.6.0
|
||||
- @llamaindex/examples@0.0.8
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Agents"
|
||||
position: 10
|
||||
position: 3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 13
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# ChatEngine
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 12
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Index
|
||||
@@ -8,7 +8,6 @@ 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,19 +6,6 @@ import CodeSource2 from "!raw-loader!../../../../../examples/readers/src/custom-
|
||||
|
||||
Before you can start indexing your documents, you need to load them into memory.
|
||||
|
||||
All "basic" data loaders can be seen below, mapped to their respective filetypes in `SimpleDirectoryReader`. More loaders are shown in the sidebar on the left.
|
||||
Additionally the following loaders exist without separate documentation:
|
||||
|
||||
- `AssemblyAIReader` transcribes audio using [AssemblyAI](https://www.assemblyai.com/).
|
||||
- [AudioTranscriptReader](../../api/classes/AudioTranscriptReader.md): loads entire transcript as a single document.
|
||||
- [AudioTranscriptParagraphsReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document per paragraph.
|
||||
- [AudioTranscriptSentencesReader](../../api/classes/AudioTranscriptSentencesReader.md): creates a document per sentence.
|
||||
- [AudioSubtitlesReader](../../api/classes/AudioTranscriptParagraphsReader.md): creates a document containing the subtitles of a transcript.
|
||||
- [NotionReader](../../api/classes/NotionReader.md) loads [Notion](https://www.notion.so/) pages.
|
||||
- [SimpleMongoReader](../../api/classes/SimpleMongoReader) loads data from a [MongoDB](https://www.mongodb.com/).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## SimpleDirectoryReader
|
||||
|
||||
[](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples/readers?file=src/simple-directory-reader.ts&title=Simple%20Directory%20Reader)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
label: "Data Stores"
|
||||
position: 2
|
||||
@@ -1 +0,0 @@
|
||||
label: "Chat Stores"
|
||||
@@ -1,13 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,2 +0,0 @@
|
||||
label: "Document Stores"
|
||||
position: 2
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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,2 +0,0 @@
|
||||
label: "Index Stores"
|
||||
position: 3
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,2 +0,0 @@
|
||||
label: "Key-Value Stores"
|
||||
position: 4
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,22 +0,0 @@
|
||||
# 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,3 +1,7 @@
|
||||
---
|
||||
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: 6
|
||||
position: 3
|
||||
|
||||
@@ -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](#usage-with-llamaindex)
|
||||
2. [Usage with LlamaIndex](#integration-with-llamaindex)
|
||||
3. [Embeddings with Custom Parameters](#embeddings-with-custom-parameters)
|
||||
|
||||
## Setup
|
||||
|
||||
@@ -16,16 +16,6 @@ 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: 9
|
||||
position: 3
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Ingestion Pipeline"
|
||||
position: 4
|
||||
position: 2
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "LLMs"
|
||||
position: 5
|
||||
position: 3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fireworks LLM
|
||||
|
||||
[Fireworks.ai](https://fireworks.ai/) focus on production use cases for open source LLMs, offering speed and quality.
|
||||
Fireworks.ai focus on production use cases for open source LLMs, offering speed and quality.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
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`.
|
||||
@@ -26,15 +30,6 @@ export AZURE_OPENAI_DEPLOYMENT="gpt-4" # or some other deployment name
|
||||
|
||||
For local LLMs, currently we recommend the use of [Ollama](./available_llms/ollama.md) LLM.
|
||||
|
||||
## Available LLMs
|
||||
|
||||
Most available LLMs are listed in the sidebar on the left. Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [HuggingFaceLLM](../../api/classes/HuggingFaceLLM.md) and [HuggingFaceInferenceAPI](../../api/classes/HuggingFaceInferenceAPI.md).
|
||||
- [ReplicateLLM](../../api/classes/ReplicateLLM.md) see [replicate.com](https://replicate.com/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAI](../../api/classes/OpenAI.md)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# NodeParser
|
||||
|
||||
@@ -107,4 +107,3 @@ 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](#usage-with-llamaindex)
|
||||
2. [Usage with LlamaIndex](#integration-with-llamaindex)
|
||||
3. [Simple Reranking Guide](#simple-reranking-guide)
|
||||
4. [Reranking with Objects](#reranking-with-objects)
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
label: "Prompts"
|
||||
position: 7
|
||||
position: 0
|
||||
|
||||
@@ -73,5 +73,6 @@ 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: 8
|
||||
position: 2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 15
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# ResponseSynthesizer
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 14
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Retriever
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Storage
|
||||
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a
|
||||
@@ -53,4 +57,4 @@ const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
|
||||
## API Reference
|
||||
|
||||
- [StorageContext](../../api/interfaces/StorageContext.md)
|
||||
- [StorageContext](../api/interfaces/StorageContext.md)
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
# 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
|
||||
@@ -89,4 +87,4 @@ main().catch(console.error);
|
||||
|
||||
## API Reference
|
||||
|
||||
- [QdrantVectorStore](../../../api/classes/QdrantVectorStore.md)
|
||||
- [QdrantVectorStore](../../api/classes/QdrantVectorStore.md)
|
||||
@@ -1,168 +0,0 @@
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import CodeSource from "!raw-loader!../../../../examples/workflow/joke.ts";
|
||||
|
||||
# Workflows
|
||||
|
||||
A `Workflow` in LlamaIndexTS is an event-driven abstraction used to chain together several events. Workflows are made up of `steps`, with each step responsible for handling certain event types and emitting new events.
|
||||
|
||||
Workflows in LlamaIndexTS work by defining step functions that handle specific event types and emit new events.
|
||||
|
||||
When a step function is added to a workflow, you need to specify the input and optionally the output event types (used for validation). The specification of the input events ensures each step only runs when an accepted event is ready.
|
||||
|
||||
You can create a `Workflow` to do anything! Build an agent, a RAG flow, an extraction flow, or anything else you want.
|
||||
|
||||
## Getting Started
|
||||
|
||||
As an illustrative example, let's consider a naive workflow where a joke is generated and then critiqued.
|
||||
|
||||
<CodeBlock language="ts">{CodeSource}</CodeBlock>
|
||||
|
||||
There's a few moving pieces here, so let's go through this piece by piece.
|
||||
|
||||
### Defining Workflow Events
|
||||
|
||||
```typescript
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
```
|
||||
|
||||
Events are user-defined classes that extend `WorkflowEvent` and contain arbitrary data provided as template argument. In this case, our workflow relies on a single user-defined event, the `JokeEvent` with a `joke` attribute of type `string`.
|
||||
|
||||
### Setting up the Workflow Class
|
||||
|
||||
```typescript
|
||||
const llm = new OpenAI();
|
||||
...
|
||||
const jokeFlow = new Workflow({ verbose: true });
|
||||
```
|
||||
|
||||
Our workflow is implemented by initiating the `Workflow` class. For simplicity, we created a `OpenAI` llm instance.
|
||||
|
||||
### Workflow Entry Points
|
||||
|
||||
```typescript
|
||||
const generateJoke = async (_context: Context, ev: StartEvent) => {
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Here, we come to the entry-point of our workflow. While events are user-defined, there are two special-case events, the `StartEvent` and the `StopEvent`. Here, the `StartEvent` signifies where to send the initial workflow input.
|
||||
|
||||
The `StartEvent` is a bit of a special object since it can hold arbitrary attributes. Here, we accessed the topic with `ev.data.input`.
|
||||
|
||||
At this point, you may have noticed that we haven't explicitly told the workflow what events are handled by which steps.
|
||||
|
||||
To do so, we use the `addStep` method which adds a step to the workflow. The first argument is the event type that the step will handle, and the second argument is the previously defined step function:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(StartEvent, generateJoke);
|
||||
```
|
||||
|
||||
### Workflow Exit Points
|
||||
|
||||
```typescript
|
||||
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Here, we have our second, and last step, in the workflow. We know its the last step because the special `StopEvent` is returned. When the workflow encounters a returned `StopEvent`, it immediately stops the workflow and returns whatever the result was.
|
||||
|
||||
In this case, the result is a string, but it could be a map, array, or any other object.
|
||||
|
||||
Don't forget to add the step to the workflow:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke);
|
||||
```
|
||||
|
||||
### Running the Workflow
|
||||
|
||||
```typescript
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data.result);
|
||||
```
|
||||
|
||||
Lastly, we run the workflow. The `.run()` method is async, so we use await here to wait for the result.
|
||||
|
||||
### Validating Workflows
|
||||
|
||||
To tell the workflow what events are produced by each step, you can optionally provide a third argument to `addStep` to specify the output event type:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(StartEvent, generateJoke, { outputs: JokeEvent });
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke, { outputs: StopEvent });
|
||||
```
|
||||
|
||||
To validate a workflow, you need to call the `validate` method:
|
||||
|
||||
```typescript
|
||||
jokeFlow.validate();
|
||||
```
|
||||
|
||||
To automatically validate a workflow when you run it, you can set the `validate` flag to `true` at initialization:
|
||||
|
||||
```typescript
|
||||
const jokeFlow = new Workflow({ verbose: true, validate: true });
|
||||
```
|
||||
|
||||
## Working with Global Context/State
|
||||
|
||||
Optionally, you can choose to use global context between steps. For example, maybe multiple steps access the original `query` input from the user. You can store this in global context so that every step has access.
|
||||
|
||||
```typescript
|
||||
import { Context } from "@llamaindex/core/workflow";
|
||||
|
||||
const query = async (context: Context, ev: MyEvent) => {
|
||||
// get the query from the context
|
||||
const query = context.get("query");
|
||||
// do something with context and event
|
||||
const val = ...
|
||||
const result = ...
|
||||
// store in context
|
||||
context.set("key", val);
|
||||
|
||||
return new StopEvent({ result });
|
||||
};
|
||||
```
|
||||
|
||||
## Waiting for Multiple Events
|
||||
|
||||
The context does more than just hold data, it also provides utilities to buffer and wait for multiple events.
|
||||
|
||||
For example, you might have a step that waits for a query and retrieved nodes before synthesizing a response:
|
||||
|
||||
```typescript
|
||||
const synthesize = async (context: Context, ev: QueryEvent | RetrieveEvent) => {
|
||||
const events = context.collectEvents(ev, [QueryEvent | RetrieveEvent]);
|
||||
if (!events) {
|
||||
return;
|
||||
}
|
||||
const prompt = events
|
||||
.map((event) => {
|
||||
if (event instanceof QueryEvent) {
|
||||
return `Answer this query using the context provided: ${event.data.query}`;
|
||||
} else if (event instanceof RetrieveEvent) {
|
||||
return `Context: ${event.data.context}`;
|
||||
}
|
||||
return "";
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Using `ctx.collectEvents()` we can buffer and wait for ALL expected events to arrive. This function will only return events (in the requested order) once all events have arrived.
|
||||
|
||||
## Manually Triggering Events
|
||||
|
||||
Normally, events are triggered by returning another event during a step. However, events can also be manually dispatched using the `ctx.sendEvent(event)` method within a workflow.
|
||||
|
||||
## Examples
|
||||
|
||||
You can find many useful examples of using workflows in the [examples folder](https://github.com/run-llama/LlamaIndexTS/blob/main/examples/workflow).
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.73",
|
||||
"version": "0.0.66",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
@@ -37,7 +37,7 @@
|
||||
"docusaurus-plugin-typedoc": "1.0.5",
|
||||
"typedoc": "0.26.6",
|
||||
"typedoc-plugin-markdown": "4.2.6",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
# examples
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 11feef8: Add workflows
|
||||
- Updated dependencies [11feef8]
|
||||
- @llamaindex/core@0.2.0
|
||||
- llamaindex@0.6.0
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Anthropic, ChatMemoryBuffer, SimpleChatEngine } from "llamaindex";
|
||||
import { Anthropic, SimpleChatEngine, SimpleChatHistory } from "llamaindex";
|
||||
import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
@@ -8,8 +8,8 @@ import readline from "node:readline/promises";
|
||||
model: "claude-3-opus",
|
||||
});
|
||||
// chatHistory will store all the messages in the conversation
|
||||
const chatHistory = new ChatMemoryBuffer({
|
||||
chatHistory: [
|
||||
const chatHistory = new SimpleChatHistory({
|
||||
messages: [
|
||||
{
|
||||
content: "You want to talk in rhymes.",
|
||||
role: "system",
|
||||
|
||||
@@ -2,10 +2,10 @@ import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
import {
|
||||
ChatSummaryMemoryBuffer,
|
||||
OpenAI,
|
||||
Settings,
|
||||
SimpleChatEngine,
|
||||
SummaryChatHistory,
|
||||
} from "llamaindex";
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
@@ -18,7 +18,7 @@ async function main() {
|
||||
// Set maxTokens to 75% of the context window size of 4096
|
||||
// This will trigger the summarizer once the chat history reaches 25% of the context window size (1024 tokens)
|
||||
const llm = new OpenAI({ model: "gpt-3.5-turbo", maxTokens: 4096 * 0.75 });
|
||||
const chatHistory = new ChatSummaryMemoryBuffer({ llm });
|
||||
const chatHistory = new SummaryChatHistory({ llm });
|
||||
const chatEngine = new SimpleChatEngine({ llm });
|
||||
const rl = readline.createInterface({ input, output });
|
||||
|
||||
|
||||
+1
-12
@@ -1,23 +1,12 @@
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
import {
|
||||
Document,
|
||||
Groq,
|
||||
HuggingFaceEmbedding,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import { Document, Groq, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
// Update llm to use Groq
|
||||
Settings.llm = new Groq({
|
||||
apiKey: process.env.GROQ_API_KEY,
|
||||
});
|
||||
|
||||
// Use HuggingFace for embeddings
|
||||
Settings.embedModel = new HuggingFaceEmbedding({
|
||||
modelType: "Xenova/all-mpnet-base-v2",
|
||||
});
|
||||
|
||||
async function main() {
|
||||
// Load essay from abramov.txt in Node
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
|
||||
@@ -27,12 +27,10 @@ async function main() {
|
||||
|
||||
// Query the index
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const stream = await queryEngine.query(
|
||||
{
|
||||
query: "What did the author do in college?",
|
||||
},
|
||||
true,
|
||||
);
|
||||
const stream = await queryEngine.query({
|
||||
query: "What did the author do in college?",
|
||||
stream: true,
|
||||
});
|
||||
|
||||
// Output response
|
||||
for await (const chunk of stream) {
|
||||
|
||||
@@ -37,12 +37,10 @@ async function main() {
|
||||
|
||||
// Query the index
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const stream = await queryEngine.query(
|
||||
{
|
||||
query: "What did the author do in college?",
|
||||
},
|
||||
true,
|
||||
);
|
||||
const stream = await queryEngine.query({
|
||||
query: "What did the author do in college?",
|
||||
stream: true,
|
||||
});
|
||||
|
||||
// Output response
|
||||
for await (const chunk of stream) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
Document,
|
||||
getResponseSynthesizer,
|
||||
NodeWithScore,
|
||||
ResponseSynthesizer,
|
||||
SentenceSplitter,
|
||||
TextNode,
|
||||
} from "llamaindex";
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
|
||||
console.log(nodes);
|
||||
|
||||
const responseSynthesizer = getResponseSynthesizer("compact");
|
||||
const responseSynthesizer = new ResponseSynthesizer();
|
||||
|
||||
const nodesWithScore: NodeWithScore[] = [
|
||||
{
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
const stream = await responseSynthesizer.synthesize(
|
||||
{
|
||||
query: "What age am I?",
|
||||
nodes: nodesWithScore,
|
||||
nodesWithScore,
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
getResponseSynthesizer,
|
||||
MultiModalResponseSynthesizer,
|
||||
OpenAI,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
@@ -27,15 +27,13 @@ async function main() {
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine({
|
||||
responseSynthesizer: getResponseSynthesizer("multi_modal"),
|
||||
responseSynthesizer: new MultiModalResponseSynthesizer(),
|
||||
retriever: index.asRetriever({ topK: { TEXT: 3, IMAGE: 1 } }),
|
||||
});
|
||||
const stream = await queryEngine.query(
|
||||
{
|
||||
query: "Tell me more about Vincent van Gogh's famous paintings",
|
||||
},
|
||||
true,
|
||||
);
|
||||
const stream = await queryEngine.query({
|
||||
query: "Tell me more about Vincent van Gogh's famous paintings",
|
||||
stream: true,
|
||||
});
|
||||
for await (const chunk of stream) {
|
||||
process.stdout.write(chunk.response);
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
(async () => {
|
||||
const llm = new OpenAI({ model: "o1-preview", temperature: 1 });
|
||||
|
||||
const prompt = `What are three compounds we should consider investigating to advance research
|
||||
into new antibiotics? Why should we consider them?
|
||||
`;
|
||||
|
||||
// complete api
|
||||
const response = await llm.complete({ prompt });
|
||||
console.log(response.text);
|
||||
})();
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@llamaindex/examples",
|
||||
"private": true,
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.7",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"@azure/identity": "^4.4.1",
|
||||
"@datastax/astra-db-ts": "^1.4.1",
|
||||
"@llamaindex/core": "^0.2.0",
|
||||
"@llamaindex/core": "^0.1.0",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^3.0.2",
|
||||
"@zilliz/milvus2-sdk-node": "^2.4.6",
|
||||
@@ -14,14 +14,14 @@
|
||||
"commander": "^12.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"js-tiktoken": "^1.0.14",
|
||||
"llamaindex": "^0.6.0",
|
||||
"llamaindex": "^0.5.0",
|
||||
"mongodb": "^6.7.0",
|
||||
"pathe": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.1",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint ."
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {
|
||||
Document,
|
||||
getResponseSynthesizer,
|
||||
PromptTemplate,
|
||||
ResponseSynthesizer,
|
||||
TreeSummarize,
|
||||
TreeSummarizePrompt,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -26,7 +27,9 @@ async function main() {
|
||||
|
||||
const query = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
const responseSynthesizer = getResponseSynthesizer("tree_summarize");
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new TreeSummarize(),
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine({
|
||||
responseSynthesizer,
|
||||
|
||||
@@ -23,6 +23,6 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.1",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {
|
||||
getResponseSynthesizer,
|
||||
CompactAndRefine,
|
||||
OpenAI,
|
||||
PromptTemplate,
|
||||
ResponseSynthesizer,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
@@ -28,8 +29,8 @@ Given the CSV file, generate me Typescript code to answer the question: {query}.
|
||||
`,
|
||||
});
|
||||
|
||||
const responseSynthesizer = getResponseSynthesizer("compact", {
|
||||
textQATemplate: csvPrompt,
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new CompactAndRefine(undefined, csvPrompt),
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine({ responseSynthesizer });
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { createMessageContent } from "@llamaindex/core/utils";
|
||||
import {
|
||||
Document,
|
||||
ImageNode,
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
PromptTemplate,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
import { createMessageContent } from "llamaindex/synthesizers/utils";
|
||||
|
||||
const reader = new LlamaParseReader();
|
||||
async function main() {
|
||||
|
||||
@@ -2,10 +2,12 @@ import fs from "node:fs/promises";
|
||||
|
||||
import {
|
||||
Anthropic,
|
||||
CompactAndRefine,
|
||||
Document,
|
||||
ResponseSynthesizer,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
getResponseSynthesizer,
|
||||
anthropicTextQaPrompt,
|
||||
} from "llamaindex";
|
||||
|
||||
// Update llm to use Anthropic
|
||||
@@ -21,7 +23,9 @@ async function main() {
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
|
||||
// Split text and create embeddings. Store them in a VectorStoreIndex
|
||||
const responseSynthesizer = getResponseSynthesizer("compact");
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new CompactAndRefine(undefined, anthropicTextQaPrompt),
|
||||
});
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import {
|
||||
getResponseSynthesizer,
|
||||
OpenAI,
|
||||
OpenAIEmbedding,
|
||||
ResponseSynthesizer,
|
||||
RetrieverQueryEngine,
|
||||
Settings,
|
||||
TextNode,
|
||||
TreeSummarize,
|
||||
VectorIndexRetriever,
|
||||
VectorStore,
|
||||
VectorStoreIndex,
|
||||
@@ -164,7 +165,10 @@ async function main() {
|
||||
similarityTopK: 500,
|
||||
});
|
||||
|
||||
const responseSynthesizer = getResponseSynthesizer("tree_summarize");
|
||||
const responseSynthesizer = new ResponseSynthesizer({
|
||||
responseBuilder: new TreeSummarize(),
|
||||
});
|
||||
|
||||
return new RetrieverQueryEngine(retriever, responseSynthesizer, {
|
||||
filter,
|
||||
});
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Workflow Examples
|
||||
|
||||
These examples demonstrate LlamaIndexTS's workflow system. Check out [its documentation](https://ts.llamaindex.ai/modules/workflows) for more information.
|
||||
|
||||
## Running the Examples
|
||||
|
||||
To run the examples, make sure to run them from the parent folder called `examples`). For example, to run the joke workflow, run `npx tsx workflow/joke.ts`.
|
||||
@@ -1,122 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/core/workflow";
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
const MAX_REVIEWS = 3;
|
||||
|
||||
// Using the o1-preview model (see https://platform.openai.com/docs/guides/reasoning?reasoning-prompt-examples=coding-planning)
|
||||
const llm = new OpenAI({ model: "o1-preview", temperature: 1 });
|
||||
|
||||
// example specification from https://platform.openai.com/docs/guides/reasoning?reasoning-prompt-examples=coding-planning
|
||||
const specification = `Python app that takes user questions and looks them up in a
|
||||
database where they are mapped to answers. If there is a close match, it retrieves
|
||||
the matched answer. If there isn't, it asks the user to provide an answer and
|
||||
stores the question/answer pair in the database.`;
|
||||
|
||||
// Create custom event types
|
||||
export class MessageEvent extends WorkflowEvent<{ msg: string }> {}
|
||||
export class CodeEvent extends WorkflowEvent<{ code: string }> {}
|
||||
export class ReviewEvent extends WorkflowEvent<{
|
||||
review: string;
|
||||
code: string;
|
||||
}> {}
|
||||
|
||||
// Helper function to truncate long strings
|
||||
const truncate = (str: string) => {
|
||||
const MAX_LENGTH = 60;
|
||||
if (str.length <= MAX_LENGTH) return str;
|
||||
return str.slice(0, MAX_LENGTH) + "...";
|
||||
};
|
||||
|
||||
// the architect is responsible for writing the structure and the initial code based on the specification
|
||||
const architect = async (context: Context, ev: StartEvent) => {
|
||||
// get the specification from the start event and save it to context
|
||||
context.set("specification", ev.data.input);
|
||||
const spec = context.get("specification");
|
||||
// write a message to send an update to the user
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({
|
||||
msg: `Writing app using this specification: ${truncate(spec)}`,
|
||||
}),
|
||||
);
|
||||
const prompt = `Build an app for this specification: <spec>${spec}</spec>. Make a plan for the directory structure you'll need, then return each file in full. Don't supply any reasoning, just code.`;
|
||||
const code = await llm.complete({ prompt });
|
||||
return new CodeEvent({ code: code.text });
|
||||
};
|
||||
|
||||
// the coder is responsible for updating the code based on the review
|
||||
const coder = async (context: Context, ev: ReviewEvent) => {
|
||||
// get the specification from the context
|
||||
const spec = context.get("specification");
|
||||
// get the latest review and code
|
||||
const { review, code } = ev.data;
|
||||
// write a message to send an update to the user
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({
|
||||
msg: `Update code based on review: ${truncate(review)}`,
|
||||
}),
|
||||
);
|
||||
const prompt = `We need to improve code that should implement this specification: <spec>${spec}</spec>. Here is the current code: <code>${code}</code>. And here is a review of the code: <review>${review}</review>. Improve the code based on the review, keep the specification in mind, and return the full updated code. Don't supply any reasoning, just code.`;
|
||||
const updatedCode = await llm.complete({ prompt });
|
||||
return new CodeEvent({ code: updatedCode.text });
|
||||
};
|
||||
|
||||
// the reviewer is responsible for reviewing the code and providing feedback
|
||||
const reviewer = async (context: Context, ev: CodeEvent) => {
|
||||
// get the specification from the context
|
||||
const spec = context.get("specification");
|
||||
// get latest code from the event
|
||||
const { code } = ev.data;
|
||||
// update and check the number of reviews
|
||||
const numberReviews = context.get("numberReviews", 0) + 1;
|
||||
context.set("numberReviews", numberReviews);
|
||||
if (numberReviews > MAX_REVIEWS) {
|
||||
// the we've done this too many times - return the code
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({
|
||||
msg: `Already reviewed ${numberReviews - 1} times, stopping!`,
|
||||
}),
|
||||
);
|
||||
return new StopEvent({ result: code });
|
||||
}
|
||||
// write a message to send an update to the user
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({ msg: `Review #${numberReviews}: ${truncate(code)}` }),
|
||||
);
|
||||
const prompt = `Review this code: <code>${code}</code>. Check if the code quality and whether it correctly implements this specification: <spec>${spec}</spec>. If you're satisfied, just return 'Looks great', nothing else. If not, return a review with a list of changes you'd like to see.`;
|
||||
const review = (await llm.complete({ prompt })).text;
|
||||
if (review.includes("Looks great")) {
|
||||
// the reviewer is satisfied with the code, let's return the review
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({
|
||||
msg: `Reviewer says: ${review}`,
|
||||
}),
|
||||
);
|
||||
return new StopEvent({ result: code });
|
||||
}
|
||||
|
||||
return new ReviewEvent({ review, code });
|
||||
};
|
||||
|
||||
const codeAgent = new Workflow({ validate: true });
|
||||
codeAgent.addStep(StartEvent, architect, { outputs: CodeEvent });
|
||||
codeAgent.addStep(ReviewEvent, coder, { outputs: CodeEvent });
|
||||
codeAgent.addStep(CodeEvent, reviewer, { outputs: ReviewEvent });
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const run = codeAgent.run(specification);
|
||||
for await (const event of codeAgent.streamEvents()) {
|
||||
const msg = (event as MessageEvent).data.msg;
|
||||
console.log(`${msg}\n`);
|
||||
}
|
||||
const result = await run;
|
||||
console.log("Final code:\n", result.data.result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,70 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/core/workflow";
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create custom event types
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
export class CritiqueEvent extends WorkflowEvent<{ critique: string }> {}
|
||||
export class AnalysisEvent extends WorkflowEvent<{ analysis: string }> {}
|
||||
|
||||
const generateJoke = async (_context: Context, ev: StartEvent) => {
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new CritiqueEvent({ critique: response.text });
|
||||
};
|
||||
|
||||
const analyzeJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough analysis of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new AnalysisEvent({ analysis: response.text });
|
||||
};
|
||||
|
||||
const reportJoke = async (
|
||||
context: Context,
|
||||
ev: AnalysisEvent | CritiqueEvent,
|
||||
) => {
|
||||
const events = context.collectEvents(ev, [AnalysisEvent, CritiqueEvent]);
|
||||
if (!events) {
|
||||
return;
|
||||
}
|
||||
const subPrompts = events.map((event) => {
|
||||
if (event instanceof AnalysisEvent) {
|
||||
return `Analysis: ${event.data.analysis}`;
|
||||
} else if (event instanceof CritiqueEvent) {
|
||||
return `Critique: ${event.data.critique}`;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
const prompt = `Based on the following information about a joke:\n${subPrompts.join("\n")}\nProvide a comprehensive report on the joke's quality and impact.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow();
|
||||
jokeFlow.addStep(StartEvent, generateJoke);
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke);
|
||||
jokeFlow.addStep(JokeEvent, analyzeJoke);
|
||||
jokeFlow.addStep([AnalysisEvent, CritiqueEvent], reportJoke);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data.result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,38 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/core/workflow";
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create a custom event type
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
|
||||
const generateJoke = async (_context: Context, ev: StartEvent) => {
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow({ verbose: true });
|
||||
jokeFlow.addStep(StartEvent, generateJoke);
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data.result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,49 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/core/workflow";
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create custom event types
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
export class MessageEvent extends WorkflowEvent<{ msg: string }> {}
|
||||
|
||||
const generateJoke = async (context: Context, ev: StartEvent) => {
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({ msg: `Generating a joke about: ${ev.data.input}` }),
|
||||
);
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (context: Context, ev: JokeEvent) => {
|
||||
context.writeEventToStream(
|
||||
new MessageEvent({ msg: `Write a critique of this joke: ${ev.data.joke}` }),
|
||||
);
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow();
|
||||
jokeFlow.addStep(StartEvent, generateJoke);
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const run = jokeFlow.run("pirates");
|
||||
for await (const event of jokeFlow.streamEvents()) {
|
||||
console.log((event as MessageEvent).data.msg);
|
||||
}
|
||||
const result = await run;
|
||||
console.log(result.data.result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,37 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
} from "@llamaindex/core/workflow";
|
||||
|
||||
const longRunning = async (_context: Context, ev: StartEvent) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait for 2 seconds
|
||||
return new StopEvent({ result: "We waited 2 seconds" });
|
||||
};
|
||||
|
||||
async function timeout() {
|
||||
const workflow = new Workflow({ verbose: true, timeout: 1 });
|
||||
workflow.addStep(StartEvent, longRunning);
|
||||
// This will timeout
|
||||
try {
|
||||
await workflow.run("Let's start");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function notimeout() {
|
||||
// Increase timeout to 3 seconds - no timeout
|
||||
const workflow = new Workflow({ verbose: true, timeout: 3 });
|
||||
workflow.addStep(StartEvent, longRunning);
|
||||
const result = await workflow.run("Let's start");
|
||||
console.log(result.data.result);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await timeout();
|
||||
await notimeout();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,53 +0,0 @@
|
||||
import {
|
||||
Context,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/core/workflow";
|
||||
import { OpenAI } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create a custom event type
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
|
||||
const generateJoke = async (_context: Context, ev: StartEvent) => {
|
||||
const prompt = `Write your best joke about ${ev.data.input}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
|
||||
async function validateFails() {
|
||||
try {
|
||||
const jokeFlow = new Workflow({ verbose: true, validate: true });
|
||||
jokeFlow.addStep(StartEvent, generateJoke, { outputs: StopEvent });
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke, { outputs: StopEvent });
|
||||
await jokeFlow.run("pirates");
|
||||
} catch (e) {
|
||||
console.error("Validation failed:", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function validate() {
|
||||
const jokeFlow = new Workflow({ verbose: true, validate: true });
|
||||
jokeFlow.addStep(StartEvent, generateJoke, { outputs: JokeEvent });
|
||||
jokeFlow.addStep(JokeEvent, critiqueJoke, { outputs: StopEvent });
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data.result);
|
||||
}
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
await validateFails();
|
||||
await validate();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
+4
-4
@@ -2,9 +2,9 @@
|
||||
"name": "@llamaindex/monorepo",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"build:release": "turbo run build --filter=\"./packages/*\"",
|
||||
"dev": "turbo run dev --filter=\"./packages/*\"",
|
||||
"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",
|
||||
"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.6.2"
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"packageManager": "pnpm@9.5.0",
|
||||
"pnpm": {
|
||||
|
||||
@@ -1,48 +1,5 @@
|
||||
# @llamaindex/autotool
|
||||
|
||||
## 3.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- llamaindex@0.6.4
|
||||
|
||||
## 3.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- Updated dependencies [5c4badb]
|
||||
- llamaindex@0.6.3
|
||||
|
||||
## 3.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- llamaindex@0.6.2
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1a6137b: feat: experimental support for browser
|
||||
|
||||
If you see bundler issue in next.js edge runtime, please bump to `next@14` latest version.
|
||||
|
||||
- Updated dependencies [fbd5e01]
|
||||
- Updated dependencies [6b70c54]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [85c2e19]
|
||||
- llamaindex@0.6.1
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- llamaindex@0.6.0
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,66 +1,5 @@
|
||||
# @llamaindex/autotool-01-node-example
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- llamaindex@0.6.4
|
||||
- @llamaindex/autotool@3.0.4
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- Updated dependencies [5c4badb]
|
||||
- llamaindex@0.6.3
|
||||
- @llamaindex/autotool@3.0.3
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- llamaindex@0.6.2
|
||||
- @llamaindex/autotool@3.0.2
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [fbd5e01]
|
||||
- Updated dependencies [6b70c54]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [85c2e19]
|
||||
- llamaindex@0.6.1
|
||||
- @llamaindex/autotool@3.0.1
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- llamaindex@0.6.0
|
||||
- @llamaindex/autotool@3.0.0
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"scripts": {
|
||||
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
|
||||
},
|
||||
"version": "0.0.13"
|
||||
"version": "0.0.6"
|
||||
}
|
||||
|
||||
@@ -1,66 +1,5 @@
|
||||
# @llamaindex/autotool-02-next-example
|
||||
|
||||
## 0.1.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- llamaindex@0.6.4
|
||||
- @llamaindex/autotool@3.0.4
|
||||
|
||||
## 0.1.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- Updated dependencies [5c4badb]
|
||||
- llamaindex@0.6.3
|
||||
- @llamaindex/autotool@3.0.3
|
||||
|
||||
## 0.1.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- llamaindex@0.6.2
|
||||
- @llamaindex/autotool@3.0.2
|
||||
|
||||
## 0.1.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [fbd5e01]
|
||||
- Updated dependencies [6b70c54]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [85c2e19]
|
||||
- llamaindex@0.6.1
|
||||
- @llamaindex/autotool@3.0.1
|
||||
|
||||
## 0.1.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- llamaindex@0.6.0
|
||||
- @llamaindex/autotool@3.0.0
|
||||
|
||||
## 0.1.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.1.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.1.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,9 +5,9 @@ import { runWithStreamableUI } from "@/context";
|
||||
import "@/tool";
|
||||
import { convertTools } from "@llamaindex/autotool";
|
||||
import { createStreamableUI } from "ai/rsc";
|
||||
import type { ReactNode } from "react";
|
||||
import type { JSX } from "react";
|
||||
|
||||
export async function chatWithAI(message: string): Promise<ReactNode> {
|
||||
export async function chatWithAI(message: string): Promise<JSX.Element> {
|
||||
const agent = new OpenAIAgent({
|
||||
tools: convertTools("llamaindex"),
|
||||
});
|
||||
@@ -25,7 +25,7 @@ export async function chatWithAI(message: string): Promise<ReactNode> {
|
||||
uiStream.append("\n");
|
||||
},
|
||||
write: async (message) => {
|
||||
uiStream.append(message.response);
|
||||
uiStream.append(message.response.delta);
|
||||
},
|
||||
close: () => {
|
||||
uiStream.done();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/autotool-02-next-example",
|
||||
"private": true,
|
||||
"version": "0.1.57",
|
||||
"version": "0.1.50",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
@@ -32,6 +32,6 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"postcss": "^8.4.41",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/autotool",
|
||||
"type": "module",
|
||||
"version": "3.0.4",
|
||||
"version": "2.0.1",
|
||||
"description": "auto transpile your JS function to LLM Agent compatible",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -51,7 +51,7 @@
|
||||
"unplugin": "^1.12.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"llamaindex": "workspace:*",
|
||||
"llamaindex": "^0.5.25",
|
||||
"openai": "^4",
|
||||
"typescript": "^4"
|
||||
},
|
||||
@@ -72,10 +72,10 @@
|
||||
"@types/node": "^22.5.1",
|
||||
"bunchee": "5.3.2",
|
||||
"llamaindex": "workspace:*",
|
||||
"next": "14.2.11",
|
||||
"next": "14.2.7",
|
||||
"rollup": "^4.21.2",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.6.2",
|
||||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5",
|
||||
"webpack": "^5.94.0"
|
||||
}
|
||||
|
||||
@@ -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 ${entryPoint}`);
|
||||
throw new Error("Failed to parse root");
|
||||
}
|
||||
|
||||
export async function transformAutoTool(
|
||||
|
||||
@@ -1,41 +1,5 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
## 0.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fb36eff: fix: backport for node.js 18
|
||||
|
||||
There could have one missing API in the node.js 18, so we need to backport it to make it work.
|
||||
|
||||
- d24d3d1: fix: print warning when llama parse reader has error
|
||||
- Updated dependencies [2cd1383]
|
||||
- @llamaindex/core@0.2.3
|
||||
|
||||
## 0.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b42adeb: fix: get job result in llama parse reader
|
||||
- Updated dependencies [749b43a]
|
||||
- @llamaindex/core@0.2.2
|
||||
|
||||
## 0.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 85c2e19: feat: `@llamaindex/cloud` package update
|
||||
|
||||
- Bump to latest openapi schema
|
||||
- Move LlamaParse class from llamaindex, this will allow you use llamaparse in more non-node.js environment
|
||||
|
||||
- Updated dependencies [ac07e3c]
|
||||
- Updated dependencies [70ccb4a]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [ac07e3c]
|
||||
- @llamaindex/core@0.2.1
|
||||
- @llamaindex/env@0.1.11
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+337
-2522
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloud",
|
||||
"version": "0.2.7",
|
||||
"version": "0.2.4",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -26,20 +26,6 @@
|
||||
"types": "./dist/api.d.ts",
|
||||
"default": "./dist/api.js"
|
||||
}
|
||||
},
|
||||
"./reader": {
|
||||
"require": {
|
||||
"types": "./dist/reader.d.cts",
|
||||
"default": "./dist/reader.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/reader.d.ts",
|
||||
"default": "./dist/reader.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/reader.d.ts",
|
||||
"default": "./dist/reader.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
@@ -50,15 +36,6 @@
|
||||
"devDependencies": {
|
||||
"@hey-api/client-fetch": "^0.2.4",
|
||||
"@hey-api/openapi-ts": "^0.53.0",
|
||||
"@llamaindex/core": "workspace:^0.2.3",
|
||||
"@llamaindex/env": "workspace:^0.1.11",
|
||||
"bunchee": "5.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@llamaindex/core": "workspace:^0.2.3",
|
||||
"@llamaindex/env": "workspace:^0.1.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"magic-bytes.js": "^1.10.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export async function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
@@ -8,17 +8,8 @@
|
||||
"moduleResolution": "Bundler",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"types": []
|
||||
"lib": ["DOM", "ESNext"]
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../core/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "../env/tsconfig.json"
|
||||
}
|
||||
]
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
@@ -1,45 +1,5 @@
|
||||
# @llamaindex/community
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- @llamaindex/core@0.2.4
|
||||
- @llamaindex/env@0.1.12
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2cd1383]
|
||||
- @llamaindex/core@0.2.3
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [749b43a]
|
||||
- @llamaindex/core@0.2.2
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ac07e3c]
|
||||
- Updated dependencies [70ccb4a]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [ac07e3c]
|
||||
- @llamaindex/core@0.2.1
|
||||
- @llamaindex/env@0.1.11
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [11feef8]
|
||||
- @llamaindex/core@0.2.0
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/community",
|
||||
"description": "Community package for LlamaIndexTS",
|
||||
"version": "0.0.38",
|
||||
"version": "0.0.33",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,52 +1,5 @@
|
||||
# @llamaindex/core
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b48bcc3: feat: add `load-transformers` event type when loading `@xenova/transformers` module
|
||||
|
||||
This would benefit user who want to customize the transformer env.
|
||||
|
||||
- Updated dependencies [b48bcc3]
|
||||
- @llamaindex/env@0.1.12
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2cd1383: refactor: align `response-synthesizers` & `chat-engine` module
|
||||
|
||||
- builtin event system
|
||||
- correct class extends
|
||||
- aligin APIs, naming with llama-index python
|
||||
- move stream out of first parameter to second parameter for the better tyep checking
|
||||
- remove JSONQueryEngine in `@llamaindex/experimental`, as the code quality is not satisify and we will bring it back later
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 749b43a: fix: clip embedding transform function
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ac07e3c: fix: replace instanceof check with `.type` check
|
||||
- 70ccb4a: Allow arbitrary types in workflow's StartEvent and StopEvent
|
||||
- ac07e3c: fix: add `console.warn` when import dual module
|
||||
- Updated dependencies [ac07e3c]
|
||||
- Updated dependencies [1a6137b]
|
||||
- Updated dependencies [ac07e3c]
|
||||
- @llamaindex/env@0.1.11
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 11feef8: Add workflows
|
||||
|
||||
## 0.1.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/core",
|
||||
"type": "module",
|
||||
"version": "0.2.4",
|
||||
"version": "0.1.12",
|
||||
"description": "LlamaIndex Core Module",
|
||||
"exports": {
|
||||
"./node-parser": {
|
||||
@@ -143,62 +143,6 @@
|
||||
"types": "./dist/indices/index.d.ts",
|
||||
"default": "./dist/indices/index.js"
|
||||
}
|
||||
},
|
||||
"./workflow": {
|
||||
"require": {
|
||||
"types": "./dist/workflow/index.d.cts",
|
||||
"default": "./dist/workflow/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/workflow/index.d.ts",
|
||||
"default": "./dist/workflow/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/workflow/index.d.ts",
|
||||
"default": "./dist/workflow/index.js"
|
||||
}
|
||||
},
|
||||
"./memory": {
|
||||
"require": {
|
||||
"types": "./dist/memory/index.d.cts",
|
||||
"default": "./dist/memory/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/memory/index.d.ts",
|
||||
"default": "./dist/memory/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/memory/index.d.ts",
|
||||
"default": "./dist/memory/index.js"
|
||||
}
|
||||
},
|
||||
"./storage/chat-store": {
|
||||
"require": {
|
||||
"types": "./dist/storage/chat-store/index.d.cts",
|
||||
"default": "./dist/storage/chat-store/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/storage/chat-store/index.d.ts",
|
||||
"default": "./dist/storage/chat-store/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/storage/chat-store/index.d.ts",
|
||||
"default": "./dist/storage/chat-store/index.js"
|
||||
}
|
||||
},
|
||||
"./response-synthesizers": {
|
||||
"require": {
|
||||
"types": "./dist/response-synthesizers/index.d.cts",
|
||||
"default": "./dist/response-synthesizers/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/response-synthesizers/index.d.ts",
|
||||
"default": "./dist/response-synthesizers/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/response-synthesizers/index.d.ts",
|
||||
"default": "./dist/response-synthesizers/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
@@ -214,17 +158,14 @@
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"@types/node": "^22.5.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,34 +23,23 @@ export abstract class BaseEmbedding extends TransformComponent {
|
||||
embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
|
||||
embedInfo?: EmbeddingInfo;
|
||||
|
||||
protected constructor(
|
||||
transformFn?: (
|
||||
nodes: BaseNode[],
|
||||
options?: BaseEmbeddingOptions,
|
||||
) => Promise<BaseNode[]>,
|
||||
) {
|
||||
if (transformFn) {
|
||||
super(transformFn);
|
||||
} else {
|
||||
super(
|
||||
async (
|
||||
nodes: BaseNode[],
|
||||
options?: BaseEmbeddingOptions,
|
||||
): Promise<BaseNode[]> => {
|
||||
const texts = nodes.map((node) =>
|
||||
node.getContent(MetadataMode.EMBED),
|
||||
);
|
||||
constructor() {
|
||||
super(
|
||||
async (
|
||||
nodes: BaseNode[],
|
||||
options?: BaseEmbeddingOptions,
|
||||
): Promise<BaseNode[]> => {
|
||||
const texts = nodes.map((node) => node.getContent(MetadataMode.EMBED));
|
||||
|
||||
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
|
||||
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
nodes[i]!.embedding = embeddings[i];
|
||||
}
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
nodes[i]!.embedding = embeddings[i];
|
||||
}
|
||||
|
||||
return nodes;
|
||||
},
|
||||
);
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
similarity(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export { BaseEmbedding, batchEmbeddings } from "./base";
|
||||
export type { BaseEmbeddingOptions, EmbeddingInfo } from "./base";
|
||||
export { MultiModalEmbedding } from "./muti-model";
|
||||
export { truncateMaxTokens } from "./tokenizer";
|
||||
export { DEFAULT_SIMILARITY_TOP_K, SimilarityType, similarity } from "./utils";
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
import type { MessageContentDetail } from "../llms";
|
||||
import {
|
||||
ImageNode,
|
||||
MetadataMode,
|
||||
ModalityType,
|
||||
splitNodesByType,
|
||||
type BaseNode,
|
||||
type ImageType,
|
||||
} from "../schema";
|
||||
import { extractImage, extractSingleText } from "../utils";
|
||||
import {
|
||||
BaseEmbedding,
|
||||
batchEmbeddings,
|
||||
type BaseEmbeddingOptions,
|
||||
} from "./base";
|
||||
|
||||
/*
|
||||
* Base class for Multi Modal embeddings.
|
||||
*/
|
||||
export abstract class MultiModalEmbedding extends BaseEmbedding {
|
||||
abstract getImageEmbedding(images: ImageType): Promise<number[]>;
|
||||
|
||||
protected constructor() {
|
||||
super(
|
||||
async (
|
||||
nodes: BaseNode[],
|
||||
options?: BaseEmbeddingOptions,
|
||||
): Promise<BaseNode[]> => {
|
||||
const nodeMap = splitNodesByType(nodes);
|
||||
const imageNodes = nodeMap[ModalityType.IMAGE] ?? [];
|
||||
const textNodes = nodeMap[ModalityType.TEXT] ?? [];
|
||||
|
||||
const embeddings = await batchEmbeddings(
|
||||
textNodes.map((node) => node.getContent(MetadataMode.EMBED)),
|
||||
this.getTextEmbeddings.bind(this),
|
||||
this.embedBatchSize,
|
||||
options,
|
||||
);
|
||||
for (let i = 0; i < textNodes.length; i++) {
|
||||
textNodes[i]!.embedding = embeddings[i];
|
||||
}
|
||||
|
||||
const imageEmbeddings = await batchEmbeddings(
|
||||
imageNodes.map((n) => (n as ImageNode).image),
|
||||
this.getImageEmbeddings.bind(this),
|
||||
this.embedBatchSize,
|
||||
options,
|
||||
);
|
||||
for (let i = 0; i < imageNodes.length; i++) {
|
||||
imageNodes[i]!.embedding = imageEmbeddings[i];
|
||||
}
|
||||
|
||||
return nodes;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally override this method to retrieve multiple image embeddings in a single request
|
||||
* @param images
|
||||
*/
|
||||
async getImageEmbeddings(images: ImageType[]): Promise<number[][]> {
|
||||
return Promise.all(
|
||||
images.map((imgFilePath) => this.getImageEmbedding(imgFilePath)),
|
||||
);
|
||||
}
|
||||
|
||||
async getQueryEmbedding(
|
||||
query: MessageContentDetail,
|
||||
): Promise<number[] | null> {
|
||||
const image = extractImage(query);
|
||||
if (image) {
|
||||
return await this.getImageEmbedding(image);
|
||||
}
|
||||
const text = extractSingleText(query);
|
||||
if (text) {
|
||||
return await this.getTextEmbedding(text);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,8 @@ import type {
|
||||
ToolCall,
|
||||
ToolOutput,
|
||||
} from "../../llms";
|
||||
import type { QueryEndEvent, QueryStartEvent } from "../../query-engine";
|
||||
import type {
|
||||
SynthesizeEndEvent,
|
||||
SynthesizeStartEvent,
|
||||
} from "../../response-synthesizers";
|
||||
import { TextNode } from "../../schema";
|
||||
import { EventCaller, getEventCaller } from "../../utils";
|
||||
import { EventCaller, getEventCaller } from "../../utils/event-caller";
|
||||
import type { UUID } from "../type";
|
||||
|
||||
export type LLMStartEvent = {
|
||||
@@ -65,10 +60,6 @@ export interface LlamaIndexEventMaps {
|
||||
"chunking-end": ChunkingEndEvent;
|
||||
"node-parsing-start": NodeParsingStartEvent;
|
||||
"node-parsing-end": NodeParsingEndEvent;
|
||||
"query-start": QueryStartEvent;
|
||||
"query-end": QueryEndEvent;
|
||||
"synthesize-start": SynthesizeStartEvent;
|
||||
"synthesize-end": SynthesizeEndEvent;
|
||||
}
|
||||
|
||||
export class LlamaIndexCustomEvent<T = any> extends CustomEvent<T> {
|
||||
@@ -128,29 +119,16 @@ export class CallbackManager {
|
||||
dispatchEvent<K extends keyof LlamaIndexEventMaps>(
|
||||
event: K,
|
||||
detail: LlamaIndexEventMaps[K],
|
||||
sync = false,
|
||||
) {
|
||||
const cbs = this.#handlers.get(event);
|
||||
if (!cbs) {
|
||||
return;
|
||||
}
|
||||
if (typeof queueMicrotask === "undefined") {
|
||||
console.warn(
|
||||
"queueMicrotask is not available, dispatching synchronously",
|
||||
);
|
||||
sync = true;
|
||||
}
|
||||
if (sync) {
|
||||
queueMicrotask(() => {
|
||||
cbs.forEach((handler) =>
|
||||
handler(LlamaIndexCustomEvent.fromEvent(event, { ...detail })),
|
||||
);
|
||||
} else {
|
||||
queueMicrotask(() => {
|
||||
cbs.forEach((handler) =>
|
||||
handler(LlamaIndexCustomEvent.fromEvent(event, { ...detail })),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { type Tokenizer, tokenizers } from "@llamaindex/env";
|
||||
import {
|
||||
DEFAULT_CHUNK_OVERLAP_RATIO,
|
||||
DEFAULT_CHUNK_SIZE,
|
||||
DEFAULT_CONTEXT_WINDOW,
|
||||
DEFAULT_NUM_OUTPUTS,
|
||||
DEFAULT_PADDING,
|
||||
Settings,
|
||||
} from "../global";
|
||||
import type { LLMMetadata } from "../llms";
|
||||
import { SentenceSplitter } from "../node-parser";
|
||||
import type { PromptTemplate } from "../prompts";
|
||||
|
||||
@@ -136,29 +133,4 @@ export class PromptHelper {
|
||||
const combinedStr = textChunks.join("\n\n");
|
||||
return textSplitter.splitText(combinedStr);
|
||||
}
|
||||
|
||||
static fromLLMMetadata(
|
||||
metadata: LLMMetadata,
|
||||
options?: {
|
||||
chunkOverlapRatio?: number;
|
||||
chunkSizeLimit?: number;
|
||||
tokenizer?: Tokenizer;
|
||||
separator?: string;
|
||||
},
|
||||
) {
|
||||
const {
|
||||
chunkOverlapRatio = DEFAULT_CHUNK_OVERLAP_RATIO,
|
||||
chunkSizeLimit = DEFAULT_CHUNK_SIZE,
|
||||
tokenizer = Settings.tokenizer,
|
||||
separator = " ",
|
||||
} = options ?? {};
|
||||
return new PromptHelper({
|
||||
contextWindow: metadata.contextWindow,
|
||||
numOutput: metadata.maxTokens ?? DEFAULT_NUM_OUTPUTS,
|
||||
chunkOverlapRatio,
|
||||
chunkSizeLimit,
|
||||
tokenizer,
|
||||
separator,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage, MessageContent } from "../llms";
|
||||
import { type BaseChatStore, SimpleChatStore } from "../storage/chat-store";
|
||||
import { extractText } from "../utils";
|
||||
|
||||
export const DEFAULT_TOKEN_LIMIT_RATIO = 0.75;
|
||||
export const DEFAULT_CHAT_STORE_KEY = "chat_history";
|
||||
|
||||
/**
|
||||
* A ChatMemory is used to keep the state of back and forth chat messages
|
||||
*/
|
||||
export abstract class BaseMemory<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
abstract getMessages(
|
||||
input?: MessageContent | undefined,
|
||||
):
|
||||
| ChatMessage<AdditionalMessageOptions>[]
|
||||
| Promise<ChatMessage<AdditionalMessageOptions>[]>;
|
||||
abstract getAllMessages():
|
||||
| ChatMessage<AdditionalMessageOptions>[]
|
||||
| Promise<ChatMessage<AdditionalMessageOptions>[]>;
|
||||
abstract put(messages: ChatMessage<AdditionalMessageOptions>): void;
|
||||
abstract reset(): void;
|
||||
|
||||
protected _tokenCountForMessages(messages: ChatMessage[]): number {
|
||||
if (messages.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const tokenizer = Settings.tokenizer;
|
||||
const str = messages.map((m) => extractText(m.content)).join(" ");
|
||||
return tokenizer.encode(str).length;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseChatStoreMemory<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends BaseMemory<AdditionalMessageOptions> {
|
||||
protected constructor(
|
||||
public chatStore: BaseChatStore<AdditionalMessageOptions> = new SimpleChatStore<AdditionalMessageOptions>(),
|
||||
public chatStoreKey: string = DEFAULT_CHAT_STORE_KEY,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
getAllMessages(): ChatMessage<AdditionalMessageOptions>[] {
|
||||
return this.chatStore.getMessages(this.chatStoreKey);
|
||||
}
|
||||
|
||||
put(messages: ChatMessage<AdditionalMessageOptions>) {
|
||||
this.chatStore.addMessage(this.chatStoreKey, messages);
|
||||
}
|
||||
|
||||
set(messages: ChatMessage<AdditionalMessageOptions>[]) {
|
||||
this.chatStore.setMessages(this.chatStoreKey, messages);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.chatStore.deleteMessages(this.chatStoreKey);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage, LLM, MessageContent } from "../llms";
|
||||
import { type BaseChatStore } from "../storage/chat-store";
|
||||
import { BaseChatStoreMemory, DEFAULT_TOKEN_LIMIT_RATIO } from "./base";
|
||||
|
||||
type ChatMemoryBufferOptions<AdditionalMessageOptions extends object = object> =
|
||||
{
|
||||
tokenLimit?: number | undefined;
|
||||
chatStore?: BaseChatStore<AdditionalMessageOptions> | undefined;
|
||||
chatStoreKey?: string | undefined;
|
||||
chatHistory?: ChatMessage<AdditionalMessageOptions>[] | undefined;
|
||||
llm?: LLM<object, AdditionalMessageOptions> | undefined;
|
||||
};
|
||||
|
||||
export class ChatMemoryBuffer<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends BaseChatStoreMemory<AdditionalMessageOptions> {
|
||||
tokenLimit: number;
|
||||
|
||||
constructor(
|
||||
options?: Partial<ChatMemoryBufferOptions<AdditionalMessageOptions>>,
|
||||
) {
|
||||
super(options?.chatStore, options?.chatStoreKey);
|
||||
|
||||
const llm = options?.llm ?? Settings.llm;
|
||||
const contextWindow = llm.metadata.contextWindow;
|
||||
this.tokenLimit =
|
||||
options?.tokenLimit ??
|
||||
Math.ceil(contextWindow * DEFAULT_TOKEN_LIMIT_RATIO);
|
||||
|
||||
if (options?.chatHistory) {
|
||||
this.chatStore.setMessages(this.chatStoreKey, options.chatHistory);
|
||||
}
|
||||
}
|
||||
|
||||
getMessages(
|
||||
input?: MessageContent | undefined,
|
||||
initialTokenCount: number = 0,
|
||||
) {
|
||||
const messages = this.getAllMessages();
|
||||
|
||||
if (initialTokenCount > this.tokenLimit) {
|
||||
throw new Error("Initial token count exceeds token limit");
|
||||
}
|
||||
|
||||
let messageCount = messages.length;
|
||||
let currentMessages = messages.slice(-messageCount);
|
||||
let tokenCount = this._tokenCountForMessages(messages) + initialTokenCount;
|
||||
|
||||
while (tokenCount > this.tokenLimit && messageCount > 1) {
|
||||
messageCount -= 1;
|
||||
if (messages.at(-messageCount)!.role === "assistant") {
|
||||
messageCount -= 1;
|
||||
}
|
||||
currentMessages = messages.slice(-messageCount);
|
||||
tokenCount =
|
||||
this._tokenCountForMessages(currentMessages) + initialTokenCount;
|
||||
}
|
||||
|
||||
if (tokenCount > this.tokenLimit && messageCount <= 0) {
|
||||
return [];
|
||||
}
|
||||
return messages.slice(-messageCount);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export { BaseMemory } from "./base";
|
||||
export { ChatMemoryBuffer } from "./chat-memory-buffer";
|
||||
export { ChatSummaryMemoryBuffer } from "./summary-memory";
|
||||
@@ -1,9 +1,5 @@
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import { Settings } from "../global";
|
||||
import type { MessageContent } from "../llms";
|
||||
import { PromptMixin } from "../prompts";
|
||||
import { EngineResponse } from "../schema";
|
||||
import { wrapEventCaller } from "../utils";
|
||||
import { EngineResponse, type NodeWithScore } from "../schema";
|
||||
|
||||
/**
|
||||
* @link https://docs.llamaindex.ai/en/stable/api_reference/schema/?h=querybundle#llama_index.core.schema.QueryBundle
|
||||
@@ -18,37 +14,16 @@ export type QueryBundle = {
|
||||
|
||||
export type QueryType = string | QueryBundle;
|
||||
|
||||
export type QueryFn = (
|
||||
strOrQueryBundle: QueryType,
|
||||
stream?: boolean,
|
||||
) => Promise<AsyncIterable<EngineResponse> | EngineResponse>;
|
||||
|
||||
export abstract class BaseQueryEngine extends PromptMixin {
|
||||
protected constructor(protected readonly _query: QueryFn) {
|
||||
super();
|
||||
}
|
||||
|
||||
export interface BaseQueryEngine {
|
||||
query(
|
||||
strOrQueryBundle: QueryType,
|
||||
stream: true,
|
||||
): Promise<AsyncIterable<EngineResponse>>;
|
||||
query(strOrQueryBundle: QueryType, stream?: false): Promise<EngineResponse>;
|
||||
@wrapEventCaller
|
||||
async query(
|
||||
|
||||
synthesize?(
|
||||
strOrQueryBundle: QueryType,
|
||||
stream = false,
|
||||
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
|
||||
const id = randomUUID();
|
||||
const callbackManager = Settings.callbackManager;
|
||||
callbackManager.dispatchEvent("query-start", {
|
||||
id,
|
||||
query: strOrQueryBundle,
|
||||
});
|
||||
const response = await this._query(strOrQueryBundle, stream);
|
||||
callbackManager.dispatchEvent("query-end", {
|
||||
id,
|
||||
response,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
nodes: NodeWithScore[],
|
||||
additionalSources?: Iterator<NodeWithScore>,
|
||||
): Promise<EngineResponse>;
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export { BaseQueryEngine, type QueryBundle, type QueryType } from "./base";
|
||||
export type { QueryEndEvent, QueryStartEvent } from "./type";
|
||||
export type { BaseQueryEngine, QueryBundle, QueryType } from "./base";
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { EngineResponse } from "../schema";
|
||||
import type { QueryType } from "./base";
|
||||
|
||||
export type QueryStartEvent = {
|
||||
id: string;
|
||||
query: QueryType;
|
||||
};
|
||||
|
||||
export type QueryEndEvent = {
|
||||
id: string;
|
||||
response: EngineResponse | AsyncIterable<EngineResponse>;
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import { Settings } from "../global";
|
||||
import { PromptHelper } from "../indices";
|
||||
import type { LLM, MessageContent } from "../llms";
|
||||
import { PromptMixin } from "../prompts";
|
||||
import { EngineResponse, type NodeWithScore } from "../schema";
|
||||
import type { SynthesizeQuery } from "./type";
|
||||
|
||||
export type BaseSynthesizerOptions = {
|
||||
llm?: LLM;
|
||||
promptHelper?: PromptHelper;
|
||||
};
|
||||
|
||||
export abstract class BaseSynthesizer extends PromptMixin {
|
||||
llm: LLM;
|
||||
promptHelper: PromptHelper;
|
||||
|
||||
protected constructor(options: Partial<BaseSynthesizerOptions>) {
|
||||
super();
|
||||
this.llm = options.llm ?? Settings.llm;
|
||||
this.promptHelper =
|
||||
options.promptHelper ?? PromptHelper.fromLLMMetadata(this.llm.metadata);
|
||||
}
|
||||
|
||||
protected abstract getResponse(
|
||||
query: MessageContent,
|
||||
textChunks: NodeWithScore[],
|
||||
stream: boolean,
|
||||
): Promise<EngineResponse | AsyncIterable<EngineResponse>>;
|
||||
|
||||
synthesize(
|
||||
query: SynthesizeQuery,
|
||||
stream: true,
|
||||
): Promise<AsyncIterable<EngineResponse>>;
|
||||
synthesize(query: SynthesizeQuery, stream?: false): Promise<EngineResponse>;
|
||||
async synthesize(
|
||||
query: SynthesizeQuery,
|
||||
stream = false,
|
||||
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
|
||||
const callbackManager = Settings.callbackManager;
|
||||
const id = randomUUID();
|
||||
callbackManager.dispatchEvent("synthesize-start", { id, query });
|
||||
let response: EngineResponse | AsyncIterable<EngineResponse>;
|
||||
if (query.nodes.length === 0) {
|
||||
if (stream) {
|
||||
response = EngineResponse.fromResponse("Empty Response", true);
|
||||
} else {
|
||||
response = EngineResponse.fromResponse("Empty Response", false);
|
||||
}
|
||||
} else {
|
||||
const queryMessage: MessageContent =
|
||||
typeof query.query === "string" ? query.query : query.query.query;
|
||||
response = await this.getResponse(queryMessage, query.nodes, stream);
|
||||
}
|
||||
callbackManager.dispatchEvent("synthesize-end", { id, query, response });
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
export {
|
||||
BaseSynthesizer,
|
||||
type BaseSynthesizerOptions,
|
||||
} from "./base-synthesizer";
|
||||
export { getResponseSynthesizer, type ResponseMode } from "./factory";
|
||||
export type {
|
||||
SynthesizeEndEvent,
|
||||
SynthesizeQuery,
|
||||
SynthesizeStartEvent,
|
||||
} from "./type";
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { QueryType } from "../query-engine";
|
||||
import { EngineResponse, type NodeWithScore } from "../schema";
|
||||
|
||||
export type SynthesizeQuery = {
|
||||
query: QueryType;
|
||||
nodes: NodeWithScore[];
|
||||
additionalSourceNodes?: NodeWithScore[];
|
||||
};
|
||||
|
||||
export type SynthesizeStartEvent = {
|
||||
id: string;
|
||||
query: SynthesizeQuery;
|
||||
};
|
||||
|
||||
export type SynthesizeEndEvent = {
|
||||
id: string;
|
||||
query: SynthesizeQuery;
|
||||
response: EngineResponse | AsyncIterable<EngineResponse>;
|
||||
};
|
||||
@@ -437,16 +437,9 @@ export function splitNodesByType(nodes: BaseNode[]): NodesByType {
|
||||
|
||||
for (const node of nodes) {
|
||||
let type: ModalityType;
|
||||
if (
|
||||
node.type === ObjectType.IMAGE ||
|
||||
node.type === ObjectType.IMAGE_DOCUMENT
|
||||
) {
|
||||
if (node instanceof ImageNode) {
|
||||
type = ModalityType.IMAGE;
|
||||
} else if (
|
||||
node.type === ObjectType.TEXT ||
|
||||
node.type === ObjectType.DOCUMENT ||
|
||||
node.type === ObjectType.INDEX
|
||||
) {
|
||||
} else if (node instanceof TextNode) {
|
||||
type = ModalityType.TEXT;
|
||||
} else {
|
||||
throw new Error(`Unknown node type: ${node.type}`);
|
||||
@@ -472,36 +465,28 @@ export function buildNodeFromSplits(
|
||||
};
|
||||
|
||||
textSplits.forEach((textChunk, i) => {
|
||||
if (
|
||||
doc.type === ObjectType.IMAGE ||
|
||||
doc.type === ObjectType.IMAGE_DOCUMENT
|
||||
) {
|
||||
const imageDoc = doc as ImageNode;
|
||||
if (doc instanceof ImageDocument) {
|
||||
const imageNode = new ImageNode({
|
||||
id_: idGenerator(i, imageDoc),
|
||||
id_: idGenerator(i, doc),
|
||||
text: textChunk,
|
||||
image: imageDoc.image,
|
||||
embedding: imageDoc.embedding,
|
||||
excludedEmbedMetadataKeys: [...imageDoc.excludedEmbedMetadataKeys],
|
||||
excludedLlmMetadataKeys: [...imageDoc.excludedLlmMetadataKeys],
|
||||
metadataSeparator: imageDoc.metadataSeparator,
|
||||
textTemplate: imageDoc.textTemplate,
|
||||
image: doc.image,
|
||||
embedding: doc.embedding,
|
||||
excludedEmbedMetadataKeys: [...doc.excludedEmbedMetadataKeys],
|
||||
excludedLlmMetadataKeys: [...doc.excludedLlmMetadataKeys],
|
||||
metadataSeparator: doc.metadataSeparator,
|
||||
textTemplate: doc.textTemplate,
|
||||
relationships: { ...relationships },
|
||||
});
|
||||
nodes.push(imageNode);
|
||||
} else if (
|
||||
doc.type === ObjectType.DOCUMENT ||
|
||||
doc.type === ObjectType.TEXT
|
||||
) {
|
||||
const textDoc = doc as TextNode;
|
||||
} else if (doc instanceof Document || doc instanceof TextNode) {
|
||||
const node = new TextNode({
|
||||
id_: idGenerator(i, textDoc),
|
||||
id_: idGenerator(i, doc),
|
||||
text: textChunk,
|
||||
embedding: textDoc.embedding,
|
||||
excludedEmbedMetadataKeys: [...textDoc.excludedEmbedMetadataKeys],
|
||||
excludedLlmMetadataKeys: [...textDoc.excludedLlmMetadataKeys],
|
||||
metadataSeparator: textDoc.metadataSeparator,
|
||||
textTemplate: textDoc.textTemplate,
|
||||
embedding: doc.embedding,
|
||||
excludedEmbedMetadataKeys: [...doc.excludedEmbedMetadataKeys],
|
||||
excludedLlmMetadataKeys: [...doc.excludedLlmMetadataKeys],
|
||||
metadataSeparator: doc.metadataSeparator,
|
||||
textTemplate: doc.textTemplate,
|
||||
relationships: { ...relationships },
|
||||
});
|
||||
nodes.push(node);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { ChatMessage } from "../../llms";
|
||||
|
||||
export abstract class BaseChatStore<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
abstract setMessages(
|
||||
key: string,
|
||||
messages: ChatMessage<AdditionalMessageOptions>[],
|
||||
): void;
|
||||
abstract getMessages(key: string): ChatMessage<AdditionalMessageOptions>[];
|
||||
abstract addMessage(
|
||||
key: string,
|
||||
message: ChatMessage<AdditionalMessageOptions>,
|
||||
idx?: number,
|
||||
): void;
|
||||
abstract deleteMessages(key: string): void;
|
||||
abstract deleteMessage(key: string, idx: number): void;
|
||||
abstract getKeys(): IterableIterator<string>;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export { BaseChatStore } from "./base-chat-store";
|
||||
export { SimpleChatStore } from "./simple-chat-store";
|
||||
@@ -1,43 +0,0 @@
|
||||
import type { ChatMessage } from "../../llms";
|
||||
import { BaseChatStore } from "./base-chat-store";
|
||||
|
||||
export class SimpleChatStore<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends BaseChatStore<AdditionalMessageOptions> {
|
||||
#store = new Map<string, ChatMessage<AdditionalMessageOptions>[]>();
|
||||
setMessages(key: string, messages: ChatMessage<AdditionalMessageOptions>[]) {
|
||||
this.#store.set(key, messages);
|
||||
}
|
||||
|
||||
getMessages(key: string) {
|
||||
return this.#store.get(key) ?? [];
|
||||
}
|
||||
|
||||
addMessage(
|
||||
key: string,
|
||||
message: ChatMessage<AdditionalMessageOptions>,
|
||||
idx?: number,
|
||||
) {
|
||||
const messages = this.#store.get(key) ?? [];
|
||||
if (idx === undefined) {
|
||||
messages.push(message);
|
||||
} else {
|
||||
messages.splice(idx, 0, message);
|
||||
}
|
||||
this.#store.set(key, messages);
|
||||
}
|
||||
|
||||
deleteMessages(key: string) {
|
||||
this.#store.delete(key);
|
||||
}
|
||||
|
||||
deleteMessage(key: string, idx: number) {
|
||||
const messages = this.#store.get(key) ?? [];
|
||||
messages.splice(idx, 1);
|
||||
this.#store.set(key, messages);
|
||||
}
|
||||
|
||||
getKeys() {
|
||||
return this.#store.keys();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export { EventCaller, getEventCaller, wrapEventCaller } from "./event-caller";
|
||||
export { wrapEventCaller } from "./event-caller";
|
||||
|
||||
export async function* streamConverter<S, D>(
|
||||
stream: AsyncIterable<S>,
|
||||
@@ -47,12 +47,10 @@ export async function* streamReducer<S, D>(params: {
|
||||
export { wrapLLMEvent } from "./wrap-llm-event";
|
||||
|
||||
export {
|
||||
createMessageContent,
|
||||
extractDataUrlComponents,
|
||||
extractImage,
|
||||
extractSingleText,
|
||||
extractText,
|
||||
imageToDataUrl,
|
||||
messagesToHistory,
|
||||
toToolDescriptions,
|
||||
} from "./llms";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { fs } from "@llamaindex/env";
|
||||
import { filetypemime } from "magic-bytes.js";
|
||||
import type {
|
||||
ChatMessage,
|
||||
MessageContent,
|
||||
@@ -7,16 +5,8 @@ import type {
|
||||
MessageContentTextDetail,
|
||||
ToolMetadata,
|
||||
} from "../llms";
|
||||
import type { BasePromptTemplate } from "../prompts";
|
||||
import type { QueryType } from "../query-engine";
|
||||
import type { ImageType } from "../schema";
|
||||
import {
|
||||
type BaseNode,
|
||||
ImageNode,
|
||||
MetadataMode,
|
||||
ModalityType,
|
||||
splitNodesByType,
|
||||
} from "../schema";
|
||||
|
||||
/**
|
||||
* Extracts just the text whether from
|
||||
@@ -117,99 +107,3 @@ export function toToolDescriptions(tools: ToolMetadata[]): string {
|
||||
|
||||
return JSON.stringify(toolsObj, null, 4);
|
||||
}
|
||||
|
||||
async function blobToDataUrl(input: Blob) {
|
||||
const buffer = Buffer.from(await input.arrayBuffer());
|
||||
const mimes = filetypemime(buffer);
|
||||
if (mimes.length < 1) {
|
||||
throw new Error("Unsupported image type");
|
||||
}
|
||||
return "data:" + mimes[0] + ";base64," + buffer.toString("base64");
|
||||
}
|
||||
|
||||
export async function imageToDataUrl(
|
||||
input: ImageType | Uint8Array,
|
||||
): Promise<string> {
|
||||
// first ensure, that the input is a Blob
|
||||
if (
|
||||
(input instanceof URL && input.protocol === "file:") ||
|
||||
typeof input === "string"
|
||||
) {
|
||||
// string or file URL
|
||||
const dataBuffer = await fs.readFile(
|
||||
input instanceof URL ? input.pathname : input,
|
||||
);
|
||||
input = new Blob([dataBuffer]);
|
||||
} else if (!(input instanceof Blob)) {
|
||||
if (input instanceof URL) {
|
||||
throw new Error(`Unsupported URL with protocol: ${input.protocol}`);
|
||||
} else if (input instanceof Uint8Array) {
|
||||
input = new Blob([input]); // convert Uint8Array to Blob
|
||||
} else {
|
||||
throw new Error(`Unsupported input type: ${typeof input}`);
|
||||
}
|
||||
}
|
||||
return await blobToDataUrl(input);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-params
|
||||
async function createContentPerModality(
|
||||
prompt: BasePromptTemplate,
|
||||
type: ModalityType,
|
||||
nodes: BaseNode[],
|
||||
extraParams: Record<string, string>,
|
||||
metadataMode: MetadataMode,
|
||||
): Promise<MessageContentDetail[]> {
|
||||
switch (type) {
|
||||
case ModalityType.TEXT:
|
||||
return [
|
||||
{
|
||||
type: "text",
|
||||
text: prompt.format({
|
||||
...extraParams,
|
||||
context: nodes.map((r) => r.getContent(metadataMode)).join("\n\n"),
|
||||
}),
|
||||
},
|
||||
];
|
||||
case ModalityType.IMAGE:
|
||||
const images: MessageContentDetail[] = await Promise.all(
|
||||
(nodes as ImageNode[]).map(async (node) => {
|
||||
return {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: await imageToDataUrl(node.image),
|
||||
},
|
||||
} satisfies MessageContentDetail;
|
||||
}),
|
||||
);
|
||||
return images;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function createMessageContent(
|
||||
prompt: BasePromptTemplate,
|
||||
nodes: BaseNode[],
|
||||
extraParams: Record<string, string> = {},
|
||||
metadataMode: MetadataMode = MetadataMode.NONE,
|
||||
): Promise<MessageContentDetail[]> {
|
||||
const content: MessageContentDetail[] = [];
|
||||
const nodeMap = splitNodesByType(nodes);
|
||||
for (const type in nodeMap) {
|
||||
// for each retrieved modality type, create message content
|
||||
const nodes = nodeMap[type as ModalityType];
|
||||
if (nodes) {
|
||||
content.push(
|
||||
...(await createContentPerModality(
|
||||
prompt,
|
||||
type as ModalityType,
|
||||
nodes,
|
||||
extraParams,
|
||||
metadataMode,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user