Compare commits

..

3 Commits

Author SHA1 Message Date
Thuc Pham 7f988f4e09 fix: move groq-sdk to external webpack 2024-09-13 11:41:03 +07:00
Thuc Pham 38584f128b Create chilled-bottles-prove.md 2024-09-12 21:21:46 +07:00
Thuc Pham 473ef072a3 fix: cannot import groq-sdk in nextjs 2024-09-12 21:21:14 +07:00
245 changed files with 4354 additions and 10230 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"llamaindex": patch
---
fix: cannot import groq-sdk in nextjs
+1 -10
View File
@@ -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
-55
View File
@@ -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 -1
View File
@@ -1,2 +1,2 @@
label: "Agents"
position: 10
position: 3
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 13
sidebar_position: 4
---
# ChatEngine
+1 -2
View File
@@ -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
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples/readers?file=src/simple-directory-reader.ts&title=Simple%20Directory%20Reader)
@@ -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 -1
View File
@@ -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
+4 -9
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,2 +1,2 @@
label: "Prompts"
position: 7
position: 0
+1
View File
@@ -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 -1
View File
@@ -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,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)
-168
View File
@@ -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).
+2 -2
View File
@@ -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": [
-9
View File
@@ -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
+3 -3
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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";
+4 -6
View File
@@ -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) {
+4 -6
View File
@@ -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) {
+3 -3
View File
@@ -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,
);
+6 -8
View File
@@ -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);
}
-13
View File
@@ -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);
})();
+4 -4
View File
@@ -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 ."
+5 -2
View File
@@ -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,
+1 -1
View File
@@ -23,6 +23,6 @@
"devDependencies": {
"@types/node": "^22.5.1",
"tsx": "^4.19.0",
"typescript": "^5.6.2"
"typescript": "^5.5.4"
}
}
+4 -3
View File
@@ -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 -1
View File
@@ -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() {
+6 -2
View File
@@ -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]);
+6 -2
View File
@@ -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,
});
-7
View File
@@ -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`.
-122
View File
@@ -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);
-70
View File
@@ -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);
-38
View File
@@ -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);
-49
View File
@@ -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);
-37
View File
@@ -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);
-53
View File
@@ -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
View File
@@ -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": {
-43
View File
@@ -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"
}
}
+4 -4
View File
@@ -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"
}
+2 -2
View File
@@ -9,7 +9,7 @@ import td from "typedoc";
import type { SourceMapCompact } from "unplugin";
import type { InfoString } from "./internal";
export const isToolFile = (url: string) => /\.tool\.[jt]sx?$/.test(url);
export const isToolFile = (url: string) => /tool\.[jt]sx?$/.test(url);
export const isJSorTS = (url: string) => /\.m?[jt]sx?$/.test(url);
async function parseRoot(entryPoint: string) {
@@ -28,7 +28,7 @@ async function parseRoot(entryPoint: string) {
if (project) {
return app.serializer.projectToObject(project, process.cwd());
}
throw new Error(`Failed to parse root ${entryPoint}`);
throw new Error("Failed to parse root");
}
export async function transformAutoTool(
-36
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1 -24
View File
@@ -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"
}
}
-3
View File
@@ -1,3 +0,0 @@
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+2 -11
View File
@@ -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"]
}
-40
View File
@@ -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 -1
View File
@@ -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",
-47
View File
@@ -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 -60
View File
@@ -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"
}
}
+14 -25
View File
@@ -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
View File
@@ -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,
});
}
}
-62
View File
@@ -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);
}
}
-3
View File
@@ -1,3 +0,0 @@
export { BaseMemory } from "./base";
export { ChatMemoryBuffer } from "./chat-memory-buffer";
export { ChatSummaryMemoryBuffer } from "./summary-memory";
+7 -32
View File
@@ -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
View File
@@ -1,2 +1 @@
export { BaseQueryEngine, type QueryBundle, type QueryType } from "./base";
export type { QueryEndEvent, QueryStartEvent } from "./type";
export type { BaseQueryEngine, QueryBundle, QueryType } from "./base";
-12
View File
@@ -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>;
};
+17 -32
View File
@@ -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 -3
View File
@@ -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";
-106
View File
@@ -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