mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-01 22:14:03 -04:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a18a2eb3d | |||
| 206b491724 | |||
| 9b2e25a184 | |||
| b29521bf6c | |||
| 73e25787e7 | |||
| 3ce80540fe | |||
| dbc1ee3089 | |||
| 3b45191228 | |||
| aaf2f8b2db | |||
| 6ddf1c1b1f | |||
| a8717d5ece | |||
| 7e8e4549f2 | |||
| cc3fe92a22 | |||
| 63ab0dba4e | |||
| 2225ffd1d4 | |||
| bc5334249b | |||
| 41953a3ef9 | |||
| fa66c9ca8e | |||
| 3ee8c83200 | |||
| e919bab568 | |||
| d28b6b7c4f | |||
| 1c7a262ff7 | |||
| 5a1838cc91 | |||
| b9805f4899 | |||
| 109ec63779 | |||
| 82d4b46fe4 | |||
| f8c2d0b8ad | |||
| 6d7bc4ccbb | |||
| 294f502441 |
@@ -23,7 +23,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x, 23.x]
|
||||
node-version: [20.x, 22.x, 23.x]
|
||||
name: E2E on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x, 23.x]
|
||||
node-version: [20.x, 22.x, 23.x]
|
||||
name: Test on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -7,3 +7,4 @@ dist/
|
||||
.source/
|
||||
# prttier doesn't support mdx3 we are using
|
||||
*.mdx
|
||||
packages/server/server/
|
||||
@@ -1,5 +1,44 @@
|
||||
# @llamaindex/doc
|
||||
|
||||
## 0.2.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9b2e25a]
|
||||
- @llamaindex/openai@0.3.6
|
||||
- @llamaindex/core@0.6.4
|
||||
- llamaindex@0.10.5
|
||||
- @llamaindex/cloud@4.0.6
|
||||
- @llamaindex/node-parser@2.0.4
|
||||
- @llamaindex/readers@3.1.2
|
||||
- @llamaindex/workflow@1.1.1
|
||||
|
||||
## 0.2.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7e8e454]
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [bc53342]
|
||||
- Updated dependencies [41953a3]
|
||||
- @llamaindex/workflow@1.1.0
|
||||
- @llamaindex/cloud@4.0.5
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.2.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- @llamaindex/core@0.6.3
|
||||
- llamaindex@0.10.3
|
||||
- @llamaindex/openai@0.3.5
|
||||
- @llamaindex/cloud@4.0.4
|
||||
- @llamaindex/node-parser@2.0.3
|
||||
- @llamaindex/readers@3.1.1
|
||||
- @llamaindex/workflow@1.0.4
|
||||
|
||||
## 0.2.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/doc",
|
||||
"version": "0.2.14",
|
||||
"version": "0.2.17",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "fumadocs-mdx",
|
||||
@@ -15,7 +15,7 @@
|
||||
"dependencies": {
|
||||
"@huggingface/transformers": "^3.5.0",
|
||||
"@icons-pack/react-simple-icons": "^10.1.0",
|
||||
"@llama-flow/docs": "0.0.5",
|
||||
"@llama-flow/docs": "0.0.8",
|
||||
"@llamaindex/chat-ui": "0.2.0",
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
|
||||
@@ -26,7 +26,7 @@ const llm = openai();
|
||||
const response = await llm.chat({
|
||||
messages: [{ content: "Tell me a joke.", role: "user" }],
|
||||
});`,
|
||||
`import { agent } from "llamaindex";
|
||||
`import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
const analyseAgent = agent({
|
||||
@@ -36,7 +36,7 @@ const analyseAgent = agent({
|
||||
});
|
||||
const response = await analyseAgent.run(\`Analyse the given data:
|
||||
\${data}\`);`,
|
||||
`import { agent, multiAgent } from "llamaindex";
|
||||
`import { agent, multiAgent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
const analyseAgent = agent({
|
||||
@@ -113,8 +113,9 @@ export default function HomePage() {
|
||||
description="Truly powerful retrieval-augmented generation applications use agentic techniques, and LlamaIndex.TS makes it easy to build them."
|
||||
>
|
||||
<CodeBlock
|
||||
code={`import { agent, SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
|
||||
code={`import { SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// load documents from current directoy into an index
|
||||
const reader = new SimpleDirectoryReader();
|
||||
|
||||
@@ -11,8 +11,3 @@ export const CodeNodeParserDemo = dynamic(() =>
|
||||
(mod) => mod.CodeNodeParserDemo,
|
||||
),
|
||||
);
|
||||
export const WorkflowStreamingDemo = dynamic(() =>
|
||||
import("@/components/demo/workflow-streaming-ui").then(
|
||||
(mod) => mod.WorkflowStreamingDemo,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
"use client";
|
||||
import FlowInput from "@/components/flow-input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "@llamaindex/workflow";
|
||||
import { ReactNode, startTransition, useState } from "react";
|
||||
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
||||
|
||||
class ComputeEvent extends WorkflowEvent<number> {
|
||||
constructor(data: number) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
class ComputeResultEvent extends WorkflowEvent<number> {
|
||||
constructor(data: number) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
|
||||
type ContextData = {
|
||||
sum: number;
|
||||
};
|
||||
|
||||
const workflow = new Workflow<ContextData, number, number>();
|
||||
|
||||
const max = 1000;
|
||||
const min = 100;
|
||||
|
||||
workflow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<number>],
|
||||
outputs: [StopEvent<number>],
|
||||
},
|
||||
async (context, event) => {
|
||||
const total = event.data;
|
||||
for (let i = 0; i < total; i++) {
|
||||
context.sendEvent(new ComputeEvent(i));
|
||||
}
|
||||
console.log("waiting");
|
||||
const computeResults = await Promise.all(
|
||||
Array.from({ length: total }).map(() =>
|
||||
context.requireEvent(ComputeResultEvent),
|
||||
),
|
||||
);
|
||||
context.data.sum = computeResults.reduce(
|
||||
(acc, result) => acc + result.data,
|
||||
0,
|
||||
);
|
||||
console.log("stop");
|
||||
return new StopEvent(context.data.sum);
|
||||
},
|
||||
);
|
||||
|
||||
workflow.addStep(
|
||||
{
|
||||
inputs: [ComputeEvent],
|
||||
outputs: [ComputeResultEvent],
|
||||
},
|
||||
async (context, event) => {
|
||||
await new Promise((resolve) =>
|
||||
setTimeout(resolve, Math.floor(Math.random() * (max - min + 1) + min)),
|
||||
);
|
||||
return new ComputeResultEvent(event.data);
|
||||
},
|
||||
);
|
||||
|
||||
function ScrollToBottom() {
|
||||
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
||||
|
||||
return (
|
||||
!isAtBottom && (
|
||||
<button
|
||||
className="i-ph-arrow-circle-down-fill absolute bottom-0 left-[50%] translate-x-[-50%] rounded-lg text-4xl"
|
||||
onClick={() => scrollToBottom()}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function WorkflowStreamingDemo() {
|
||||
const [ui, setUI] = useState<ReactNode[]>([
|
||||
<div key={0} className="bg-gray-100 dark:bg-gray-800">
|
||||
Waiting for workflow to start
|
||||
</div>,
|
||||
]);
|
||||
const [total, setTotal] = useState<number>(10);
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-col items-start gap-2">
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<div className="mr-2 text-lg">Compute total</div>{" "}
|
||||
<FlowInput value={total} onChange={(value) => setTotal(value)} />
|
||||
</div>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
startTransition(() => {
|
||||
setUI([]);
|
||||
});
|
||||
const context = workflow.run(total, {
|
||||
sum: 0,
|
||||
});
|
||||
let i = 0;
|
||||
for await (const event of context) {
|
||||
console.log(event);
|
||||
if (event instanceof ComputeEvent) {
|
||||
setUI((ui) => [
|
||||
...ui,
|
||||
<div key={i++} className="bg-yellow-100 dark:bg-yellow-800">
|
||||
Computing task id: {event.data}
|
||||
</div>,
|
||||
]);
|
||||
} else if (event instanceof ComputeResultEvent) {
|
||||
setUI((ui) => [
|
||||
...ui,
|
||||
<div key={i++} className="bg-green-100 dark:bg-green-800">
|
||||
Computed task id: {event.data}
|
||||
</div>,
|
||||
]);
|
||||
} else if (event instanceof StartEvent) {
|
||||
setUI((ui) => [
|
||||
...ui,
|
||||
<div key={i++} className="bg-blue-100 dark:bg-blue-800">
|
||||
Started workflow with total {event.data}
|
||||
</div>,
|
||||
]);
|
||||
} else if (event instanceof StopEvent) {
|
||||
setUI((ui) => [
|
||||
...ui,
|
||||
<div key={i++} className="bg-red-100 dark:bg-red-800">
|
||||
Workflow stopped
|
||||
</div>,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
Start Workflow
|
||||
</Button>
|
||||
<StickToBottom className="flex max-h-96 w-full flex-col gap-2 overflow-y-auto rounded-lg border border-gray-200 p-2">
|
||||
<StickToBottom.Content className="flex flex-col gap-2">
|
||||
{ui}
|
||||
</StickToBottom.Content>
|
||||
<ScrollToBottom />
|
||||
</StickToBottom>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -9,10 +9,10 @@ To install llamaindex, run the following command:
|
||||
npm i llamaindex
|
||||
```
|
||||
|
||||
In most cases, you'll also need an LLM package to use LlamaIndex. For example, to use the OpenAI LLM, you would install the following:
|
||||
In most cases, you'll also need an LLM package and the Workflow package to use LlamaIndex. For example, to use the OpenAI LLM with agents, you would install the following:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/openai
|
||||
npm i @llamaindex/openai @llamaindex/workflow
|
||||
```
|
||||
|
||||
Go to [LLM APIs](/docs/llamaindex/modules/models/llms) to find out how to use other LLMs.
|
||||
|
||||
@@ -40,19 +40,7 @@ Make sure to set [moduleResolution](https://www.typescriptlang.org/docs/handbook
|
||||
}
|
||||
```
|
||||
|
||||
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it, but with import path limitations.
|
||||
|
||||
So you may encounter type errors when importing sub paths from the `llamaindex` package like:
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
```
|
||||
|
||||
The simplest way to fix this without changing `moduleResolution` is to import directly from `llamaindex`:
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
```
|
||||
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it.
|
||||
|
||||
## Enable AsyncIterable for `Web Stream` API
|
||||
|
||||
@@ -68,7 +56,8 @@ Some modules uses `Web Stream` API like `ReadableStream` and `WritableStream`, y
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { agent, tool } from 'llamaindex'
|
||||
import { tool } from 'llamaindex'
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
Settings.llm = openai({
|
||||
|
||||
@@ -12,7 +12,8 @@ Agent Workflows are a powerful system that enables you to create and orchestrate
|
||||
The simplest use case is creating a single agent with specific tools. Here's an example of creating an assistant that tells jokes:
|
||||
|
||||
```typescript
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
// Define a joke-telling tool
|
||||
@@ -40,17 +41,17 @@ console.log(result); // Baby Llama is called cria
|
||||
Agent Workflows provide a unified interface for event streaming, making it easy to track and respond to different events during execution:
|
||||
|
||||
```typescript
|
||||
import { AgentToolCall, AgentStream } from "llamaindex";
|
||||
import { agentToolCallEvent, agentStreamEvent } from "@llamaindex/workflow";
|
||||
|
||||
// Get the workflow execution context
|
||||
const context = workflow.run("Tell me something funny");
|
||||
const events = workflow.runStream("Tell me something funny");
|
||||
|
||||
// Stream and handle events
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentToolCall) {
|
||||
for await (const event of events) {
|
||||
if (agentToolCallEvent.include(event)) {
|
||||
console.log(`Tool being called: ${event.data.toolName}`);
|
||||
}
|
||||
if (event instanceof AgentStream) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
process.stdout.write(event.data.delta);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +69,8 @@ An Agent Workflow can orchestrate multiple agents, enabling complex interactions
|
||||
Here's an example of a multi-agent system that combines joke-telling and weather information:
|
||||
|
||||
```typescript
|
||||
import { multiAgent, agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { multiAgent, agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ The `parameters` field in the tool configuration is defined using `zod`, a TypeS
|
||||
|
||||
Example:
|
||||
```ts
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
@@ -46,7 +47,7 @@ In this example, `z.object` is used to define a schema for the `parameters` wher
|
||||
You can import built-in tools from the `@llamaindex/tools` package.
|
||||
|
||||
```ts
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
|
||||
const researchAgent = agent({
|
||||
@@ -57,6 +58,41 @@ const researchAgent = agent({
|
||||
});
|
||||
```
|
||||
|
||||
## MCP tools
|
||||
|
||||
If you have a MCP server running, you can fetch tools from the server and use them in your agents.
|
||||
|
||||
```ts
|
||||
// 1. Import MCP tools adapter
|
||||
import { mcp } from "@llamaindex/tools";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// 2. Initialize a MCP client
|
||||
// by npx
|
||||
const server = mcp({
|
||||
command: "npx",
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
||||
verbose: true,
|
||||
});
|
||||
// or by SSE
|
||||
const server = mcp({
|
||||
url: "http://localhost:8000/mcp",
|
||||
verbose: true,
|
||||
});
|
||||
|
||||
// 3. Get tools from MCP server
|
||||
const tools = await server.tools();
|
||||
|
||||
// Now you can create an agent with the tools
|
||||
const agent = agent({
|
||||
name: "My Agent",
|
||||
systemPrompt: "You are a helpful assistant that can use the provided tools to answer questions.",
|
||||
llm: openai({ model: "gpt-4o" }),
|
||||
tools: tools,
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Function tool
|
||||
|
||||
You can still use the `FunctionTool` class to define a tool.
|
||||
@@ -79,7 +115,8 @@ Note: calling the `bind` method will return a new `FunctionTool` instance, witho
|
||||
|
||||
Example to pass a `userToken` as additional argument:
|
||||
```ts
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
const queryKnowledgeBase = async ({ question }, { userToken }) => {
|
||||
|
||||
@@ -2,149 +2,17 @@
|
||||
title: 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.
|
||||
A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to chain together several events. Workflows are made up of `handlers`, with each one responsible for processing specific event types and emitting new events.
|
||||
|
||||
Workflows 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.
|
||||
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
|
||||
|
||||
To use workflows install this package:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/workflow
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
This package is a stable, production-ready version of our [llama-flow](../../../llamaflow) project.
|
||||
|
||||
As an illustrative example, let's consider a naive workflow where a joke is generated and then critiqued.
|
||||
While you can still reference the llama-flow documentation for detailed information about the underlying concepts, we recommend using the `@llamaindex/workflow` package for all new projects to ensure stability and long-term availability.
|
||||
|
||||
<include cwd>../../examples/workflow/joke.ts</include>
|
||||
|
||||
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<unknown, string, string>();
|
||||
```
|
||||
|
||||
Our workflow is implemented by initiating the `Workflow` class with three generic types: the context type (unknown), input type (string), and output type (string). The context type is `unknown`, as we're not using a shared context in this example.
|
||||
|
||||
For simplicity, we created an `OpenAI` llm instance that we're using for inference in our workflow.
|
||||
|
||||
### Workflow Entry Points
|
||||
|
||||
```typescript
|
||||
const generateJoke = async (_: unknown, ev: StartEvent<string>) => {
|
||||
const prompt = `Write your best joke about ${ev.data}.`;
|
||||
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`. These events are predefined, but we can specify the payload type using generic types. We're using `StartEvent<string>` to indicate that we're going to send an input of type string.
|
||||
|
||||
To add this step to the workflow, we use the `addStep` method with an object specifying the input and output event types:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [JokeEvent],
|
||||
},
|
||||
generateJoke
|
||||
);
|
||||
```
|
||||
|
||||
### Workflow Exit Points
|
||||
|
||||
```typescript
|
||||
const critiqueJoke = async (_: unknown, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent(response.text);
|
||||
};
|
||||
```
|
||||
|
||||
Here, we have our second and last step in the workflow. We know it's the last step because the special `StopEvent` is returned. When the workflow encounters a returned `StopEvent`, it immediately stops the workflow and returns the result. Note that we're using the generic type `StopEvent<string>` to indicate that we're returning a string.
|
||||
|
||||
Add this step to the workflow:
|
||||
|
||||
```typescript
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
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.
|
||||
|
||||
## Working with Shared Context/State
|
||||
|
||||
Optionally, you can choose to use a shared context between steps by specifying a context type when creating the workflow. Here's an example where multiple steps access a shared state:
|
||||
|
||||
```typescript
|
||||
import { HandlerContext } from "llamaindex";
|
||||
|
||||
type MyContextData = {
|
||||
query: string;
|
||||
intermediateResults: any[];
|
||||
}
|
||||
|
||||
const query = async (context: HandlerContext<MyContextData>, ev: MyEvent) => {
|
||||
// get the query from the context
|
||||
const query = context.data.query;
|
||||
// do something with context and event
|
||||
const val = ...
|
||||
// store in context
|
||||
context.data.intermediateResults.push(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, ev1: QueryEvent, ev2: RetrieveEvent) => {
|
||||
const subPrompts = [`Answer this query using the context provided: ${ev1.data.query}`, `Context: ${ev2.data.context}`];
|
||||
const prompt = subPrompts.join("\n");
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent({ result: response.text });
|
||||
};
|
||||
```
|
||||
|
||||
Passing multiple events, we can buffer and wait for ALL expected events to arrive. The receiving step function will only be called 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).
|
||||
|
||||
@@ -120,11 +120,11 @@ async function main() {
|
||||
|
||||
```ts
|
||||
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
|
||||
import { FunctionTool, LLMAgent } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
const sumNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
const sumNumbers = tool(
|
||||
{
|
||||
name: "sumNumbers",
|
||||
description: "Use this function to sum two numbers",
|
||||
@@ -136,11 +136,11 @@ const sumNumbers = FunctionTool.from(
|
||||
description: "The second number",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
},
|
||||
);
|
||||
|
||||
const divideNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
const divideNumbers = tool(
|
||||
{
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
@@ -152,6 +152,7 @@ const divideNumbers = FunctionTool.from(
|
||||
description: "The divisor b to divide by",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -161,15 +162,15 @@ const bedrock = new Bedrock({
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const agent = new LLMAgent({
|
||||
const myAgent = agent({
|
||||
llm: bedrock,
|
||||
tools: [sumNumbers, divideNumbers],
|
||||
});
|
||||
|
||||
const response = await agent.chat({
|
||||
message: "How much is 5 + 5? then divide by 2",
|
||||
});
|
||||
const response = await myAgent.run(
|
||||
"How much is 5 + 5? then divide by 2",
|
||||
);
|
||||
|
||||
console.log(response.message);
|
||||
console.log(response);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -15,7 +15,7 @@ In LlamaIndex, an agent is a semi-autonomous piece of software powered by an LLM
|
||||
You'll need to have a recent version of [Node.js](https://nodejs.org/en) installed. Then you can install LlamaIndex.TS by running
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface
|
||||
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface @llamaindex/workflow
|
||||
```
|
||||
|
||||
## Choose your model
|
||||
|
||||
@@ -35,11 +35,16 @@ First we'll need to pull in our dependencies. These are:
|
||||
import "dotenv/config";
|
||||
import {
|
||||
agent,
|
||||
AgentStream,
|
||||
tool,
|
||||
agentStreamEvent,
|
||||
openai,
|
||||
} from "@llamaindex/workflow";
|
||||
import {
|
||||
tool,
|
||||
Settings,
|
||||
} from "llamaindex";
|
||||
import {
|
||||
openai,
|
||||
} from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
```
|
||||
|
||||
@@ -108,11 +113,10 @@ const myAgent = agent({ tools });
|
||||
|
||||
### Ask the agent a question
|
||||
|
||||
We can use the `chat` interface to ask our agent a question, and it will use the tools we've defined to find an answer.
|
||||
We can use the `run` method to ask our agent a question, and it will use the tools we've defined to find an answer.
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Sum 101 and 303");
|
||||
const result = await context;
|
||||
const result = await myAgent.run("Sum 101 and 303");
|
||||
console.log(result.data);
|
||||
```
|
||||
You will see the following output:
|
||||
@@ -123,12 +127,13 @@ You will see the following output:
|
||||
{ result: 'The sum of 101 and 303 is 404.' }
|
||||
```
|
||||
|
||||
To stream the response, you can use the `AgentStream` event which provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
|
||||
To stream the response, you need to call `runStream`, which returns a stream of events.
|
||||
The `agentStreamEvent` provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Add 101 and 303");
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
const events = myAgent.runStream("Add 101 and 303");
|
||||
for await (const event of events) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
process.stdout.write(event.data.delta);
|
||||
}
|
||||
}
|
||||
@@ -140,18 +145,18 @@ for await (const event of context) {
|
||||
The sum of 101 and 303 is 404.
|
||||
```
|
||||
|
||||
Note that we're filtering for `agentStreamEvent` as an agent might return other events - more about that in the following section.
|
||||
|
||||
### Logging workflow events
|
||||
|
||||
To log the workflow events, you can check the event type and log the event data.
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Sum 202 and 404");
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
const events = myAgent.runStream("Sum 202 and 404");
|
||||
for await (const event of events) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
// Stream the response
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
process.stdout.write(event.data.delta);
|
||||
} else {
|
||||
// Log other events
|
||||
console.log("\nWorkflow event:", JSON.stringify(event, null, 2));
|
||||
|
||||
@@ -30,16 +30,16 @@ Settings.llm = ollama({
|
||||
|
||||
### Run local agent
|
||||
|
||||
You can also create local agent by importing `agent` from `llamaindex`.
|
||||
You can also create local agent by importing `agent` from `@llamaindex/workflow`.
|
||||
|
||||
```javascript
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
const workflow = agent({
|
||||
tools: [getWeatherTool],
|
||||
});
|
||||
|
||||
const workflowContext = workflow.run(
|
||||
const resutl = workflow.run(
|
||||
"What's the weather like in San Francisco?",
|
||||
);
|
||||
```
|
||||
|
||||
@@ -25,7 +25,8 @@ We'll be bringing in `SimpleDirectoryReader`, `HuggingFaceEmbedding`, `VectorSto
|
||||
|
||||
```javascript
|
||||
import { QueryEngineTool, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { OpenAI, OpenAIAgent } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
```
|
||||
|
||||
@@ -8,9 +8,10 @@ We have a comprehensive, step-by-step [guide to building agents in LlamaIndex.TS
|
||||
|
||||
In a new folder:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i @llamaindex/openai @llamaindex/workflow llamaindex zod
|
||||
```
|
||||
|
||||
## Run agent
|
||||
@@ -20,15 +21,14 @@ Create the file `example.ts`. This code will:
|
||||
- Create two tools for use by the agent:
|
||||
- A `sumNumbers` tool that adds two numbers
|
||||
- A `divideNumbers` tool that divides numbers
|
||||
-
|
||||
- Give an example of the data structure we wish to generate
|
||||
- Prompt the LLM with instructions and the example, plus a sample transcript
|
||||
|
||||
<include cwd>../../examples/agent/openai.ts</include>
|
||||
<include cwd>../../examples/agents/agent/openai.ts</include>
|
||||
|
||||
To run the code:
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
@@ -36,9 +36,18 @@ You should expect output something like:
|
||||
|
||||
```
|
||||
{
|
||||
content: 'The sum of 5 + 5 is 10. When you divide 10 by 2, you get 5.',
|
||||
role: 'assistant',
|
||||
options: {}
|
||||
result: '5 + 5 is 10. Then, 10 divided by 2 is 5.',
|
||||
state: {
|
||||
memory: ChatMemoryBuffer {
|
||||
chatStore: SimpleChatStore {},
|
||||
chatStoreKey: 'chat_history',
|
||||
tokenLimit: 750000
|
||||
},
|
||||
scratchpad: [],
|
||||
currentAgentName: 'Agent',
|
||||
agents: [ 'Agent' ],
|
||||
nextAgentName: null
|
||||
}
|
||||
}
|
||||
Done
|
||||
```
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"basic_agent",
|
||||
"rag",
|
||||
"agents",
|
||||
"../../llamaflow",
|
||||
"workflows",
|
||||
"local_llm",
|
||||
"chatbot",
|
||||
"structured_data_extraction"
|
||||
|
||||
@@ -16,7 +16,7 @@ LlamaIndex uses a two stage method when using an LLM with your data:
|
||||
1. **indexing stage**: preparing a knowledge base, and
|
||||
2. **querying stage**: retrieving relevant context from the knowledge to assist the LLM in responding to a question
|
||||
|
||||

|
||||

|
||||
|
||||
This process is also known as Retrieval Augmented Generation (RAG).
|
||||
|
||||
@@ -28,7 +28,7 @@ Let's explore each stage in detail.
|
||||
|
||||
LlamaIndex.TS help you prepare the knowledge base with a suite of data connectors and indexes.
|
||||
|
||||

|
||||

|
||||
|
||||
[**Data Loaders**](/docs/llamaindex/modules/data/readers):
|
||||
A data connector (i.e. `Reader`) ingest data from different data sources and data formats into a simple `Document` representation (text and simple metadata).
|
||||
@@ -54,7 +54,7 @@ LlamaIndex provides composable modules that help you build and integrate RAG pip
|
||||
|
||||
These building blocks can be customized to reflect ranking preferences, as well as composed to reason over multiple knowledge bases in a structured way.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Building Blocks
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ One of the most common use-cases for LlamaIndex is Retrieval-Augmented Generatio
|
||||
|
||||
In a new folder, run:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i llamaindex
|
||||
```
|
||||
|
||||
Then, check out the [installation](/docs/llamaindex/getting_started/installation) steps to install LlamaIndex.TS and prepare an OpenAI key.
|
||||
@@ -34,7 +35,7 @@ Create a `tsconfig.json` file in the same folder:
|
||||
|
||||
Now you can run the code with
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
|
||||
@@ -10,9 +10,10 @@ You can use [other LLMs](/docs/llamaindex/modules/models/llms) via their APIs; i
|
||||
|
||||
In a new folder:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i @llamaindex/openai zod
|
||||
```
|
||||
|
||||
## Extract data
|
||||
@@ -27,7 +28,7 @@ Create the file `example.ts`. This code will:
|
||||
|
||||
To run the code:
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Workflows
|
||||
---
|
||||
|
||||
A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to chain together several events. Workflows are made up of `handlers`, with each one responsible for processing specific event types and emitting new events.
|
||||
|
||||
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/workflow @llamaindex/openai
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
Let's explore a simple workflow example where a joke is generated and then critiqued and iterated on:
|
||||
|
||||
<include cwd>../../examples/agents/workflow/joke.ts</include>
|
||||
|
||||
There are a few moving pieces here, so let's go through this step by step.
|
||||
|
||||
### Defining Workflow Events
|
||||
|
||||
```typescript
|
||||
const startEvent = workflowEvent<string>(); // Input topic for joke
|
||||
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
|
||||
const critiqueEvent = workflowEvent<{ joke: string; critique: string }>(); // Intermediate critique
|
||||
const resultEvent = workflowEvent<{ joke: string; critique: string }>(); // Final joke + critique
|
||||
```
|
||||
|
||||
Events are defined using the `workflowEvent` function and contain arbitrary data provided as a generic type. In this example, we have four events:
|
||||
- `startEvent`: Takes a string input (the joke topic)
|
||||
- `jokeEvent`: Contains an object with a joke property
|
||||
- `critiqueEvent`: Contains both the joke and its critique, used for the feedback loop
|
||||
- `resultEvent`: Contains the final joke and critique after any iterations
|
||||
|
||||
### Setting up the Workflow with Stateful Middleware
|
||||
|
||||
```typescript
|
||||
const { withState, getContext } = createStatefulMiddleware(() => ({
|
||||
numIterations: 0,
|
||||
maxIterations: 3,
|
||||
}));
|
||||
const jokeFlow = withState(createWorkflow());
|
||||
```
|
||||
|
||||
Our workflow is implemented using the `createWorkflow()` function, enhanced with the `withState` middleware. This middleware provides shared state across all handlers, which in this case tracks:
|
||||
- `numIterations`: Counts how many iterations of joke improvement we've done
|
||||
- `maxIterations`: Sets a limit to prevent infinite loops
|
||||
|
||||
This state will be accessible within workflows by using the `getContext().state` function.
|
||||
|
||||
### Adding Handlers with Loops
|
||||
|
||||
We have three key handlers in our workflow:
|
||||
|
||||
1. The first handler processes the `startEvent`, generates an initial joke, and emits a `jokeEvent`:
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([startEvent], async (event) => {
|
||||
// Prompt the LLM to write a joke
|
||||
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
return jokeEvent.with({ joke: joke });
|
||||
});
|
||||
```
|
||||
|
||||
2. The second handler handles the `jokeEvent`, critiques the joke, and either:
|
||||
- Emits a `critiqueEvent` if the joke needs improvement
|
||||
- Emits a `resultEvent` if the joke is good enough
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([jokeEvent], async (event) => {
|
||||
// Prompt the LLM to critique the joke
|
||||
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// If the critique includes "IMPROVE", keep iterating, else, return the result
|
||||
if (response.text.includes("IMPROVE")) {
|
||||
return critiqueEvent.with({
|
||||
joke: event.data.joke,
|
||||
critique: response.text,
|
||||
});
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
});
|
||||
```
|
||||
|
||||
3. The third handler processes the `critiqueEvent`, generates an improved joke based on the critique, and either:
|
||||
- Loops back to the joke evaluation (if under the iteration limit)
|
||||
- Emits the final `resultEvent` (if iteration limit reached)
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([critiqueEvent], async (event) => {
|
||||
// Keep track of the number of iterations
|
||||
const state = getContext().state;
|
||||
state.numIterations++;
|
||||
|
||||
// Write a new joke based on the previous joke and critique
|
||||
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
|
||||
// If we've done less than the max number of iterations, keep iterating
|
||||
// else, return the result
|
||||
if (state.numIterations < state.maxIterations) {
|
||||
return jokeEvent.with({ joke: joke });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: joke, critique: event.data.critique });
|
||||
});
|
||||
```
|
||||
|
||||
### Running the Workflow
|
||||
|
||||
```typescript
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
let result: { joke: string, critique: string } | undefined;
|
||||
|
||||
for await (const event of stream) {
|
||||
// console.log(event.data); optionally log the event data
|
||||
if (resultEvent.include(event)) {
|
||||
result = event.data;
|
||||
break; // Stop when we get the final result
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
```
|
||||
|
||||
To run the workflow, we:
|
||||
1. Create a workflow context with `createContext()`
|
||||
2. Trigger the initial event with `sendEvent()`
|
||||
3. Listen to the event stream and process events as they arrive
|
||||
4. Use `include()` to check if an event is of a specific type
|
||||
5. Break the loop when we receive our final result
|
||||
|
||||
### Using Stream Utilities
|
||||
|
||||
The `stream` returned by `createContext` contains utility functions to make working with event streams easier:
|
||||
|
||||
```typescript
|
||||
// Create a workflow context and send the initial event
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
// Collect all events until we get a resultEvent
|
||||
const allEvents = await stream.until(resultEvent).toArray();
|
||||
|
||||
// The last event will be the resultEvent
|
||||
const finalEvent = allEvents.at(-1);
|
||||
console.log(finalEvent.data); // Output the joke and critique
|
||||
```
|
||||
|
||||
The stream utilities make it easier to work with the asynchronous event flow. In this example, we use:
|
||||
- `toArray`: Aggregates all events into an array
|
||||
- `until`: Creates a stream that emits events until a condition is met (in this case, until a resultEvent is received)
|
||||
|
||||
You can combine these utilities with other stream operators like `filter` and `map` to create powerful processing pipelines.
|
||||
|
||||
## Next Steps
|
||||
|
||||
To learn more about workflows, check out [the Workflows documentation](/docs/llamaindex/modules/agents/workflows).
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"pages": ["llamaindex", "api"]
|
||||
"pages": ["llamaindex", "api", "llamaflow"]
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export type {
|
||||
HandlerContext,
|
||||
Workflow,
|
||||
WorkflowContext,
|
||||
} from "@llamaindex/workflow";
|
||||
@@ -1,5 +1,27 @@
|
||||
# @llamaindex/cloudflare-worker-agent-test
|
||||
|
||||
## 0.0.159
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 0.0.158
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.0.157
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 0.0.156
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloudflare-worker-agent-test",
|
||||
"version": "0.0.156",
|
||||
"version": "0.0.159",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/llama-parse-browser-test
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/cloud@4.0.6
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- @llamaindex/cloud@4.0.5
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/cloud@4.0.4
|
||||
|
||||
## 0.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/llama-parse-browser-test",
|
||||
"private": true,
|
||||
"version": "0.0.58",
|
||||
"version": "0.0.61",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -10,8 +10,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^5.4.16",
|
||||
"vite-plugin-wasm": "^3.3.0"
|
||||
"vite": "^6.3.3",
|
||||
"vite-plugin-wasm": "^3.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/cloud": "workspace:*"
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @llamaindex/next-agent-test
|
||||
|
||||
## 0.1.159
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 0.1.158
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.1.157
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 0.1.156
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-agent-test",
|
||||
"version": "0.1.156",
|
||||
"version": "0.1.159",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# test-edge-runtime
|
||||
|
||||
## 0.1.158
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 0.1.157
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.1.156
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 0.1.155
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/nextjs-edge-runtime-test",
|
||||
"version": "0.1.155",
|
||||
"version": "0.1.158",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @llamaindex/next-node-runtime
|
||||
|
||||
## 0.1.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
- @llamaindex/huggingface@0.1.8
|
||||
- @llamaindex/readers@3.1.2
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
- @llamaindex/huggingface@0.1.7
|
||||
- @llamaindex/readers@3.1.1
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-node-runtime-test",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.26",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# vite-import-llamaindex
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vite-import-llamaindex",
|
||||
"private": true,
|
||||
"version": "0.0.22",
|
||||
"version": "0.0.25",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
@@ -16,7 +16,7 @@
|
||||
"@size-limit/preset-big-lib": "^11.1.6",
|
||||
"size-limit": "^11.1.6",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^5.4.16"
|
||||
"vite": "^6.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"llamaindex": "workspace:*"
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @llamaindex/waku-query-engine-test
|
||||
|
||||
## 0.0.159
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9b2e25a]
|
||||
- @llamaindex/env@0.1.30
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 0.0.158
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.0.157
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 0.0.156
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/waku-query-engine-test",
|
||||
"version": "0.0.156",
|
||||
"version": "0.0.159",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,124 @@
|
||||
# examples
|
||||
|
||||
## 0.3.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9b2e25a: Use Uint8Array instead of Buffer for file type messages (works with non-NodeJS)
|
||||
- 206b491: Add support for google live api
|
||||
- Updated dependencies [9b2e25a]
|
||||
- Updated dependencies [206b491]
|
||||
- @llamaindex/anthropic@0.3.5
|
||||
- @llamaindex/google@0.3.0
|
||||
- @llamaindex/openai@0.3.6
|
||||
- @llamaindex/core@0.6.4
|
||||
- @llamaindex/env@0.1.30
|
||||
- llamaindex@0.10.5
|
||||
- @llamaindex/clip@0.0.54
|
||||
- @llamaindex/deepinfra@0.0.54
|
||||
- @llamaindex/deepseek@0.0.14
|
||||
- @llamaindex/fireworks@0.0.14
|
||||
- @llamaindex/groq@0.0.69
|
||||
- @llamaindex/huggingface@0.1.8
|
||||
- @llamaindex/jinaai@0.0.14
|
||||
- @llamaindex/perplexity@0.0.11
|
||||
- @llamaindex/azure@0.1.14
|
||||
- @llamaindex/elastic-search@0.1.4
|
||||
- @llamaindex/milvus@0.1.13
|
||||
- @llamaindex/qdrant@0.1.13
|
||||
- @llamaindex/supabase@0.1.3
|
||||
- @llamaindex/together@0.0.14
|
||||
- @llamaindex/vllm@0.0.40
|
||||
- @llamaindex/cloud@4.0.6
|
||||
- @llamaindex/node-parser@2.0.4
|
||||
- @llamaindex/assemblyai@0.1.3
|
||||
- @llamaindex/cohere@0.0.18
|
||||
- @llamaindex/discord@0.1.3
|
||||
- @llamaindex/mistral@0.1.4
|
||||
- @llamaindex/mixedbread@0.0.18
|
||||
- @llamaindex/notion@0.1.3
|
||||
- @llamaindex/ollama@0.1.4
|
||||
- @llamaindex/portkey-ai@0.0.46
|
||||
- @llamaindex/replicate@0.0.46
|
||||
- @llamaindex/astra@0.0.18
|
||||
- @llamaindex/chroma@0.0.18
|
||||
- @llamaindex/firestore@1.0.11
|
||||
- @llamaindex/mongodb@0.0.19
|
||||
- @llamaindex/pinecone@0.1.4
|
||||
- @llamaindex/postgres@0.0.47
|
||||
- @llamaindex/upstash@0.0.18
|
||||
- @llamaindex/weaviate@0.0.18
|
||||
- @llamaindex/vercel@0.1.4
|
||||
- @llamaindex/voyage-ai@1.0.10
|
||||
- @llamaindex/readers@3.1.2
|
||||
- @llamaindex/tools@0.0.9
|
||||
- @llamaindex/workflow@1.1.1
|
||||
|
||||
## 0.3.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- @llamaindex/core@0.6.3
|
||||
- llamaindex@0.10.3
|
||||
- @llamaindex/anthropic@0.3.4
|
||||
- @llamaindex/google@0.2.5
|
||||
- @llamaindex/openai@0.3.5
|
||||
- @llamaindex/vercel@0.1.3
|
||||
- @llamaindex/cloud@4.0.4
|
||||
- @llamaindex/node-parser@2.0.3
|
||||
- @llamaindex/assemblyai@0.1.2
|
||||
- @llamaindex/clip@0.0.53
|
||||
- @llamaindex/cohere@0.0.17
|
||||
- @llamaindex/deepinfra@0.0.53
|
||||
- @llamaindex/discord@0.1.2
|
||||
- @llamaindex/huggingface@0.1.7
|
||||
- @llamaindex/jinaai@0.0.13
|
||||
- @llamaindex/mistral@0.1.3
|
||||
- @llamaindex/mixedbread@0.0.17
|
||||
- @llamaindex/notion@0.1.2
|
||||
- @llamaindex/ollama@0.1.3
|
||||
- @llamaindex/perplexity@0.0.10
|
||||
- @llamaindex/portkey-ai@0.0.45
|
||||
- @llamaindex/replicate@0.0.45
|
||||
- @llamaindex/astra@0.0.17
|
||||
- @llamaindex/azure@0.1.13
|
||||
- @llamaindex/chroma@0.0.17
|
||||
- @llamaindex/elastic-search@0.1.3
|
||||
- @llamaindex/firestore@1.0.10
|
||||
- @llamaindex/milvus@0.1.12
|
||||
- @llamaindex/mongodb@0.0.18
|
||||
- @llamaindex/pinecone@0.1.3
|
||||
- @llamaindex/postgres@0.0.46
|
||||
- @llamaindex/qdrant@0.1.12
|
||||
- @llamaindex/supabase@0.1.2
|
||||
- @llamaindex/upstash@0.0.17
|
||||
- @llamaindex/weaviate@0.0.17
|
||||
- @llamaindex/voyage-ai@1.0.9
|
||||
- @llamaindex/readers@3.1.1
|
||||
- @llamaindex/tools@0.0.8
|
||||
- @llamaindex/workflow@1.0.4
|
||||
- @llamaindex/deepseek@0.0.13
|
||||
- @llamaindex/fireworks@0.0.13
|
||||
- @llamaindex/groq@0.0.68
|
||||
- @llamaindex/together@0.0.13
|
||||
- @llamaindex/vllm@0.0.39
|
||||
|
||||
## 0.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [82d4b46]
|
||||
- @llamaindex/server@0.1.6
|
||||
- @llamaindex/tools@0.0.7
|
||||
|
||||
## 0.3.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [294f502]
|
||||
- @llamaindex/tools@0.0.6
|
||||
|
||||
## 0.3.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { tool } from "@llamaindex/core/tools";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import fs from "fs";
|
||||
import {
|
||||
agent,
|
||||
AgentToolCall,
|
||||
AgentToolCallResult,
|
||||
agentToolCallEvent,
|
||||
agentToolCallResultEvent,
|
||||
multiAgent,
|
||||
tool,
|
||||
} from "llamaindex";
|
||||
} from "@llamaindex/workflow";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -56,19 +56,19 @@ async function main() {
|
||||
rootAgent: researchAgent,
|
||||
});
|
||||
|
||||
const context = workflow.run("Write a blog post about history of LLM");
|
||||
const events = workflow.runStream("Write a blog post about history of LLM");
|
||||
|
||||
let finalResult;
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentToolCall) {
|
||||
for await (const event of events) {
|
||||
if (agentToolCallEvent.include(event)) {
|
||||
console.log(
|
||||
`[Agent ${event.displayName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
|
||||
`[Agent ${event.data.agentName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
|
||||
event.data.toolKwargs,
|
||||
)}`,
|
||||
);
|
||||
} else if (event instanceof AgentToolCallResult) {
|
||||
} else if (agentToolCallResultEvent.include(event)) {
|
||||
console.log(
|
||||
`[Agent ${event.displayName}] executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
|
||||
`[Tool ${event.data.toolName}] executed with result ${event.data.toolOutput.result}`,
|
||||
);
|
||||
}
|
||||
finalResult = event;
|
||||
@@ -1,5 +1,6 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { FunctionTool, agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const csvData =
|
||||
@@ -11,24 +12,22 @@ const userQuestion = "which are the best comedies after 2010?";
|
||||
// The agent will succeed if we increase `maxTokens` to 1024
|
||||
const llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 1024 });
|
||||
|
||||
const interpreterTool = FunctionTool.from(
|
||||
({ code }) => {
|
||||
const interpreterTool = tool({
|
||||
name: "interpreter",
|
||||
description:
|
||||
"Execute python code in a Jupyter notebook cell and return any result, stdout, stderr, display_data, and error.",
|
||||
parameters: z.object({
|
||||
code: z.string({
|
||||
description: "The python code to execute in a single cell.",
|
||||
}),
|
||||
}),
|
||||
execute: ({ code }) => {
|
||||
console.log(
|
||||
`To answer the user's question, call the following code:\n${code}`,
|
||||
);
|
||||
return code;
|
||||
},
|
||||
{
|
||||
name: "interpreter",
|
||||
description:
|
||||
"Execute python code in a Jupyter notebook cell and return any result, stdout, stderr, display_data, and error.",
|
||||
parameters: z.object({
|
||||
code: z.string({
|
||||
description: "The python code to execute in a single cell.",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const systemPrompt =
|
||||
"You are a Python interpreter.\n - You are given tasks to complete and you run python code to solve them.\n - The python code runs in a Jupyter notebook. Every time you call $(interpreter) tool, the python code is executed in a separate cell. It's okay to make multiple calls to $(interpreter).\n - Display visualizations using matplotlib or any other visualization library directly in the notebook. Shouldn't save the visualizations to a file, just return the base64 encoded data.\n - You can install any pip package (if it exists) if you need to but the usual packages for data analysis are already preinstalled.\n - You can run any python code you want in a secure environment.";
|
||||
@@ -1,6 +1,6 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { mcp } from "@llamaindex/tools";
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
async function main() {
|
||||
// Create an MCP server for filesystem tools
|
||||
@@ -9,6 +9,12 @@ async function main() {
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
||||
verbose: true,
|
||||
});
|
||||
// You can also connect to the MCP server using SSE
|
||||
// See: https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse
|
||||
// const server = mcp({
|
||||
// url: "http://localhost:8000/mcp",
|
||||
// verbose: true,
|
||||
// });
|
||||
|
||||
try {
|
||||
// Create an agent that uses the MCP tools
|
||||
@@ -21,9 +27,7 @@ async function main() {
|
||||
});
|
||||
|
||||
// Run a task
|
||||
const response = await myAgent.run(
|
||||
"what are the files in the current directory?",
|
||||
);
|
||||
const response = await myAgent.run("What are the available tools?");
|
||||
|
||||
console.log("Agent response:", response.data);
|
||||
} finally {
|
||||
+17
-17
@@ -6,15 +6,15 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import {
|
||||
agent,
|
||||
AgentInput,
|
||||
AgentOutput,
|
||||
AgentStream,
|
||||
AgentToolCall,
|
||||
AgentToolCallResult,
|
||||
agentInputEvent,
|
||||
agentOutputEvent,
|
||||
agentStreamEvent,
|
||||
agentToolCallEvent,
|
||||
agentToolCallResultEvent,
|
||||
multiAgent,
|
||||
StopEvent,
|
||||
tool,
|
||||
} from "llamaindex";
|
||||
stopAgentEvent,
|
||||
} from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const llm = openai({
|
||||
@@ -79,21 +79,21 @@ async function multiWeatherAgent() {
|
||||
});
|
||||
|
||||
// Ask the agent to get the weather in a city
|
||||
const context = workflow.run(
|
||||
const events = workflow.runStream(
|
||||
"What is the weather in San Francisco in Celsius?",
|
||||
);
|
||||
// Stream the events
|
||||
for await (const event of context) {
|
||||
// These events might be useful for UI
|
||||
for await (const event of events) {
|
||||
// These events are useful for reporting the current state to the user in the UI
|
||||
if (
|
||||
event instanceof AgentToolCall ||
|
||||
event instanceof AgentToolCallResult ||
|
||||
event instanceof AgentOutput ||
|
||||
event instanceof AgentInput ||
|
||||
event instanceof StopEvent
|
||||
agentToolCallEvent.include(event) ||
|
||||
agentToolCallResultEvent.include(event) ||
|
||||
agentOutputEvent.include(event) ||
|
||||
agentInputEvent.include(event) ||
|
||||
stopAgentEvent.include(event)
|
||||
) {
|
||||
console.log(event);
|
||||
} else if (event instanceof AgentStream) {
|
||||
} else if (agentStreamEvent.include(event)) {
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const sumNumbers = tool({
|
||||
@@ -25,7 +26,7 @@ const divideNumbers = tool({
|
||||
async function main() {
|
||||
const mathAgent = agent({
|
||||
tools: [sumNumbers, divideNumbers],
|
||||
llm: openai({ model: "gpt-4o-mini" }),
|
||||
llm: openai({ model: "gpt-4.1-mini" }),
|
||||
verbose: false,
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import {
|
||||
AgentStream,
|
||||
AgentToolCallResult,
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
agent,
|
||||
openai,
|
||||
} from "llamaindex";
|
||||
agentStreamEvent,
|
||||
agentToolCallResultEvent,
|
||||
} from "@llamaindex/workflow";
|
||||
import { Document, VectorStoreIndex, openai } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
const index = await VectorStoreIndex.fromDocuments([
|
||||
@@ -30,15 +28,15 @@ async function main() {
|
||||
],
|
||||
});
|
||||
|
||||
const context = myAgent.run("The fact about cats");
|
||||
const events = myAgent.runStream("The fact about cats");
|
||||
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentToolCallResult) {
|
||||
for await (const event of events) {
|
||||
if (agentToolCallResultEvent.include(event)) {
|
||||
console.log(
|
||||
"Using these retrieved information to answer the question:\n",
|
||||
event.data.toolOutput.result,
|
||||
);
|
||||
} else if (event instanceof AgentStream) {
|
||||
} else if (agentStreamEvent.include(event)) {
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
* This example shows how to use a single agent with a tool
|
||||
*/
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "llamaindex";
|
||||
import { getWeatherTool } from "../agent/utils/tools";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { getWeatherTool } from "../deprecated/utils/tools";
|
||||
|
||||
async function main() {
|
||||
const weatherAgent = agent({
|
||||
@@ -14,14 +14,14 @@ async function main() {
|
||||
verbose: false,
|
||||
});
|
||||
|
||||
// Run the agent and keep the context
|
||||
const context = weatherAgent.run("What's the weather like in San Francisco?");
|
||||
const result = await context;
|
||||
const result = await weatherAgent.run(
|
||||
"What's the weather like in San Francisco?",
|
||||
);
|
||||
console.log(`${JSON.stringify(result, null, 2)}`);
|
||||
|
||||
// Reuse the context from the previous run
|
||||
// Reuse the state from the previous run
|
||||
const caResult = await weatherAgent.run("Compare it with California?", {
|
||||
context: context.data,
|
||||
state: result.data.state,
|
||||
});
|
||||
console.log(`${JSON.stringify(caResult, null, 2)}`);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
import { AgentStream, agent } from "llamaindex";
|
||||
import { agent, agentStreamEvent } from "@llamaindex/workflow";
|
||||
|
||||
async function main() {
|
||||
const llm = new OpenAI({ model: "gpt-4-turbo" });
|
||||
@@ -12,10 +12,10 @@ async function main() {
|
||||
});
|
||||
|
||||
// Chat with the agent
|
||||
const context = workflow.run("Who was Goethe?");
|
||||
const events = workflow.runStream("Who was Goethe?");
|
||||
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
for await (const event of events) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
import fs from "fs";
|
||||
import {
|
||||
agent,
|
||||
AgentToolCall,
|
||||
AgentToolCallResult,
|
||||
agentToolCallEvent,
|
||||
agentToolCallResultEvent,
|
||||
multiAgent,
|
||||
tool,
|
||||
} from "llamaindex";
|
||||
} from "@llamaindex/workflow";
|
||||
import fs from "fs";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { anthropic } from "@llamaindex/anthropic";
|
||||
@@ -81,21 +81,21 @@ async function main() {
|
||||
rootAgent: researchAgent,
|
||||
});
|
||||
|
||||
const context = workflow.run(
|
||||
const events = workflow.runStream(
|
||||
"Write a report about New York weather and inflation",
|
||||
);
|
||||
|
||||
let finalResult;
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentToolCall) {
|
||||
for await (const event of events) {
|
||||
if (agentToolCallEvent.include(event)) {
|
||||
console.log(
|
||||
`[Agent ${event.displayName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
|
||||
`[Agent ${event.data.agentName}] executing tool ${event.data.toolName} with parameters ${JSON.stringify(
|
||||
event.data.toolKwargs,
|
||||
)}`,
|
||||
);
|
||||
} else if (event instanceof AgentToolCallResult) {
|
||||
} else if (agentToolCallResultEvent.include(event)) {
|
||||
console.log(
|
||||
`[Agent ${event.displayName}] executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
|
||||
`[Agent executed tool ${event.data.toolName} with result ${event.data.toolOutput.result}`,
|
||||
);
|
||||
}
|
||||
finalResult = event;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ollama } from "@llamaindex/ollama";
|
||||
import { agent } from "llamaindex";
|
||||
import { getWeatherTool } from "../agent/utils/tools";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { getWeatherTool } from "../deprecated/utils/tools";
|
||||
|
||||
async function main() {
|
||||
const myAgent = agent({
|
||||
@@ -0,0 +1,94 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import {
|
||||
createStatefulMiddleware,
|
||||
createWorkflow,
|
||||
workflowEvent,
|
||||
} from "@llamaindex/workflow";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
|
||||
// Define our workflow events
|
||||
const startEvent = workflowEvent<string>(); // Input topic for joke
|
||||
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
|
||||
const critiqueEvent = workflowEvent<{ joke: string; critique: string }>(); // Intermediate critique
|
||||
const resultEvent = workflowEvent<{ joke: string; critique: string }>(); // Final joke + critique
|
||||
|
||||
// Create our workflow
|
||||
const { withState, getContext } = createStatefulMiddleware(() => ({
|
||||
numIterations: 0,
|
||||
maxIterations: 3,
|
||||
}));
|
||||
const jokeFlow = withState(createWorkflow());
|
||||
|
||||
// Define handlers for each step
|
||||
jokeFlow.handle([startEvent], async (event) => {
|
||||
// Prompt the LLM to write a joke
|
||||
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
return jokeEvent.with({ joke: joke });
|
||||
});
|
||||
|
||||
jokeFlow.handle([jokeEvent], async (event) => {
|
||||
// Prompt the LLM to critique the joke
|
||||
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// If the critique includes "IMPROVE", keep iterating, else, return the result
|
||||
if (response.text.includes("IMPROVE")) {
|
||||
return critiqueEvent.with({
|
||||
joke: event.data.joke,
|
||||
critique: response.text,
|
||||
});
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
});
|
||||
|
||||
jokeFlow.handle([critiqueEvent], async (event) => {
|
||||
// Keep track of the number of iterations
|
||||
const state = getContext().state;
|
||||
state.numIterations++;
|
||||
|
||||
// Write a new joke based on the previous joke and critique
|
||||
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
|
||||
// If we've done less than the max number of iterations, keep iterating
|
||||
// else, return the result
|
||||
if (state.numIterations < state.maxIterations) {
|
||||
return jokeEvent.with({ joke: joke });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: joke, critique: event.data.critique });
|
||||
});
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
let result: { joke: string; critique: string } | undefined;
|
||||
|
||||
for await (const event of stream) {
|
||||
// console.log(event.data); optionally log the event data
|
||||
if (resultEvent.include(event)) {
|
||||
result = event.data;
|
||||
break; // Stop when we get the final result
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,6 +1,7 @@
|
||||
import { anthropic } from "@llamaindex/anthropic";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const workflow = agent({
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Anthropic } from "@llamaindex/anthropic";
|
||||
import fs from "fs";
|
||||
|
||||
// Note that: Anthropic only supports PDF files for now with limited models
|
||||
// See: https://docs.anthropic.com/en/docs/build-with-claude/pdf-support?q=pdf#supported-platforms-and-models
|
||||
|
||||
async function main() {
|
||||
if (!process.env.ANTHROPIC_API_KEY) {
|
||||
throw new Error("Please set the ANTHROPIC_API_KEY environment variable.");
|
||||
}
|
||||
|
||||
const llm = new Anthropic({
|
||||
apiKey: process.env.ANTHROPIC_API_KEY,
|
||||
model: "claude-3-7-sonnet",
|
||||
});
|
||||
|
||||
const result = await llm.chat({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What's in this document? Describe it in detail.",
|
||||
},
|
||||
{
|
||||
type: "file",
|
||||
data: Uint8Array.from(fs.readFileSync("./data/manga.pdf")),
|
||||
mimeType: "application/pdf",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
console.log(result.message);
|
||||
}
|
||||
|
||||
void main().catch(console.error);
|
||||
@@ -1,5 +1,6 @@
|
||||
import { gemini, GEMINI_MODEL } from "@llamaindex/google";
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const sumNumbers = tool({
|
||||
|
||||
+24
-1
@@ -1,11 +1,12 @@
|
||||
import { Gemini, GEMINI_MODEL } from "@llamaindex/google";
|
||||
import fs from "fs";
|
||||
|
||||
(async () => {
|
||||
if (!process.env.GOOGLE_API_KEY) {
|
||||
throw new Error("Please set the GOOGLE_API_KEY environment variable.");
|
||||
}
|
||||
const gemini = new Gemini({
|
||||
model: GEMINI_MODEL.GEMINI_PRO,
|
||||
model: GEMINI_MODEL.GEMINI_PRO_1_5,
|
||||
});
|
||||
const result = await gemini.chat({
|
||||
messages: [
|
||||
@@ -18,4 +19,26 @@ import { Gemini, GEMINI_MODEL } from "@llamaindex/google";
|
||||
],
|
||||
});
|
||||
console.log(result);
|
||||
|
||||
// chat with file
|
||||
const resultWithFile = await gemini.chat({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What's in this document? Describe it in detail.",
|
||||
},
|
||||
{
|
||||
type: "file",
|
||||
data: Uint8Array.from(fs.readFileSync("./data/manga.pdf")),
|
||||
mimeType: "application/pdf",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
console.log(resultWithFile);
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import { ModalityType } from "@llamaindex/core/schema";
|
||||
import { tool } from "@llamaindex/core/tools";
|
||||
import { gemini, GEMINI_MODEL } from "@llamaindex/google";
|
||||
|
||||
import { liveEvents } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const weatherTool = tool({
|
||||
name: "weather",
|
||||
description: "Get the weather",
|
||||
parameters: z.object({
|
||||
location: z.string({
|
||||
description: "The location to get the weather for",
|
||||
}),
|
||||
}),
|
||||
execute: ({ location }) => {
|
||||
return `The weather in ${location} is rainy`;
|
||||
},
|
||||
});
|
||||
|
||||
const divideNumbers = tool({
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
parameters: z.object({
|
||||
a: z.number().describe("The dividend a to divide"),
|
||||
b: z.number().describe("The divisor b to divide by"),
|
||||
}),
|
||||
execute: ({ a, b }) => `${a / b}`,
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const apiKey = process.env.GOOGLE_API_KEY;
|
||||
if (!apiKey) {
|
||||
console.error(
|
||||
"Please set GOOGLE_API_KEY in your environment variables or .env file",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("🚀 Initializing Gemini Live API with tools example...");
|
||||
|
||||
const llm = gemini({
|
||||
apiKey: apiKey,
|
||||
model: GEMINI_MODEL.GEMINI_2_0_FLASH_LIVE, // Must use a live-compatible model
|
||||
});
|
||||
|
||||
console.log("📡 Connecting to Gemini Live session...");
|
||||
|
||||
// Connect to a live session with tools
|
||||
const session = await llm.live.connect({
|
||||
// Specify response modalities (text response is required for tools)
|
||||
responseModality: [ModalityType.TEXT],
|
||||
// Register our tools with the session
|
||||
tools: [weatherTool, divideNumbers],
|
||||
// Optional system instruction
|
||||
systemInstruction:
|
||||
"You are a helpful assistant that can use tools. When answering questions about weather or divide numbers, always use the appropriate tool.",
|
||||
});
|
||||
|
||||
(async () => {
|
||||
console.log("🎧 Listening for events...");
|
||||
|
||||
for await (const event of session.streamEvents()) {
|
||||
if (liveEvents.open.include(event)) {
|
||||
console.log("✅ Connected to Gemini Live session");
|
||||
|
||||
console.log(
|
||||
"💬 Sending message: 'What's the weather in San Francisco and what is 100 / 2?'",
|
||||
);
|
||||
session.sendMessage({
|
||||
content: "What's the weather in San Francisco and what is 100 / 2?",
|
||||
role: "user",
|
||||
});
|
||||
} else if (liveEvents.text.include(event)) {
|
||||
process.stdout.write(event.text);
|
||||
} else if (liveEvents.error.include(event)) {
|
||||
console.error("❌ Error:", event.error);
|
||||
} else if (liveEvents.close.include(event)) {
|
||||
console.log("👋 Session closed");
|
||||
process.exit(0);
|
||||
} else if (liveEvents.setupComplete.include(event)) {
|
||||
console.log("🔧 Setup complete");
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
console.log("\n👋 Interrupted by user. Closing session...");
|
||||
await session.disconnect();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// Timeout after 2 minutes if no interaction
|
||||
setTimeout(async () => {
|
||||
console.log("\n⏱️ Session timeout. Closing session...");
|
||||
await session.disconnect();
|
||||
process.exit(0);
|
||||
}, 120000);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("❌ Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,221 @@
|
||||
import { fs } from "@llamaindex/env";
|
||||
import { gemini, GEMINI_MODEL, GeminiLiveSession } from "@llamaindex/google";
|
||||
import { liveEvents } from "llamaindex";
|
||||
|
||||
import path from "path";
|
||||
|
||||
function createWavHeader(
|
||||
sampleRate = 16000,
|
||||
bitsPerSample = 16,
|
||||
channels = 1,
|
||||
dataLength: number,
|
||||
) {
|
||||
const buffer = Buffer.alloc(44);
|
||||
|
||||
// RIFF chunk descriptor
|
||||
buffer.write("RIFF", 0);
|
||||
buffer.writeUInt32LE(36 + dataLength, 4); // File size - 8
|
||||
buffer.write("WAVE", 8);
|
||||
|
||||
// fmt sub-chunk
|
||||
buffer.write("fmt ", 12);
|
||||
buffer.writeUInt32LE(16, 16); // Subchunk1Size (16 for PCM)
|
||||
buffer.writeUInt16LE(1, 20); // AudioFormat (1 for PCM)
|
||||
buffer.writeUInt16LE(channels, 22); // NumChannels
|
||||
buffer.writeUInt32LE(sampleRate, 24); // SampleRate
|
||||
buffer.writeUInt32LE((sampleRate * channels * bitsPerSample) / 8, 28); // ByteRate
|
||||
buffer.writeUInt16LE((channels * bitsPerSample) / 8, 32); // BlockAlign
|
||||
buffer.writeUInt16LE(bitsPerSample, 34); // BitsPerSample
|
||||
|
||||
// data sub-chunk
|
||||
buffer.write("data", 36);
|
||||
buffer.writeUInt32LE(dataLength, 40); // Subchunk2Size
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
async function saveWavFile(
|
||||
audioChunks: Buffer[],
|
||||
filePath: string,
|
||||
sampleRate = 16000,
|
||||
bitsPerSample = 16,
|
||||
channels = 1,
|
||||
): Promise<void> {
|
||||
if (audioChunks.length === 0) {
|
||||
throw new Error("No audio data to save");
|
||||
}
|
||||
|
||||
try {
|
||||
const combinedAudioData = Buffer.concat(audioChunks);
|
||||
console.log(`Total audio data: ${combinedAudioData.length} bytes`);
|
||||
|
||||
const wavHeader = createWavHeader(
|
||||
sampleRate,
|
||||
bitsPerSample,
|
||||
channels,
|
||||
combinedAudioData.length,
|
||||
);
|
||||
const wavFile = Buffer.concat([wavHeader, combinedAudioData]);
|
||||
|
||||
await fs.writeFile(filePath, wavFile);
|
||||
console.log(`💾 Saved audio to ${filePath}`);
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error("❌ Error saving audio file:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const apiKey = process.env.GOOGLE_API_KEY;
|
||||
if (!apiKey) {
|
||||
console.error(
|
||||
"Please set GOOGLE_API_KEY in your environment variables or .env file",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("🚀 Initializing Gemini Live API example...");
|
||||
|
||||
const llm = gemini({
|
||||
model: GEMINI_MODEL.GEMINI_2_0_FLASH_LIVE,
|
||||
voiceName: "Zephyr",
|
||||
});
|
||||
|
||||
console.log("📡 Connecting to Gemini Live session...");
|
||||
|
||||
const session = await llm.live.connect();
|
||||
|
||||
let isRunning = true;
|
||||
|
||||
const audioChunks: Buffer[] = [];
|
||||
let audioResponse = false;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log("🎧 Listening for events...");
|
||||
|
||||
for await (const event of session.streamEvents()) {
|
||||
if (liveEvents.open.include(event)) {
|
||||
console.log("✅ Connected to Gemini Live session");
|
||||
|
||||
console.log(
|
||||
"💬 Sending text message: 'Say something about you for 10 seconds'",
|
||||
);
|
||||
session.sendMessage({
|
||||
content: "Say something about you for 10 seconds",
|
||||
role: "user",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
sendPcmAudioFile(session);
|
||||
}, 3000);
|
||||
} else if (liveEvents.setupComplete.include(event)) {
|
||||
console.log("✅ Setup complete");
|
||||
} else if (liveEvents.text.include(event)) {
|
||||
process.stdout.write(event.text);
|
||||
} else if (liveEvents.audio.include(event)) {
|
||||
console.log("\n🔊 Received audio chunk");
|
||||
audioResponse = true;
|
||||
|
||||
try {
|
||||
const chunk = Buffer.from(event.data as string, "base64");
|
||||
audioChunks.push(chunk);
|
||||
console.log(`Received audio chunk: ${chunk.length} bytes`);
|
||||
} catch (error) {
|
||||
console.error("❌ Error processing audio chunk:", error);
|
||||
}
|
||||
} else if (liveEvents.error.include(event)) {
|
||||
console.error("❌ Error:", event.error);
|
||||
} else if (liveEvents.close.include(event)) {
|
||||
console.log("👋 Session closed");
|
||||
|
||||
if (audioResponse && audioChunks.length > 0) {
|
||||
try {
|
||||
await saveWavFile(audioChunks, "gemini-response.wav");
|
||||
} catch (error) {
|
||||
console.error("❌ Error saving final audio file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
isRunning = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error processing stream:", error);
|
||||
}
|
||||
})();
|
||||
|
||||
async function sendPcmAudioFile(session: GeminiLiveSession) {
|
||||
try {
|
||||
console.log("🎤 Reading PCM audio file...");
|
||||
|
||||
const filePath = path.join(__dirname, "hello_are_you_there.pcm");
|
||||
console.log(`Reading file from: ${filePath}`);
|
||||
|
||||
const audioBuffer = await fs.readFile(filePath);
|
||||
|
||||
const base64Audio = audioBuffer.toString("base64");
|
||||
|
||||
session.sendMessage({
|
||||
content: [
|
||||
{
|
||||
type: "audio",
|
||||
data: base64Audio,
|
||||
mimeType: "audio/pcm;rate=16000",
|
||||
},
|
||||
],
|
||||
role: "user",
|
||||
});
|
||||
|
||||
console.log("🎤 PCM audio file sent! Waiting for response...");
|
||||
} catch (error) {
|
||||
console.error("❌ Error sending audio file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
console.log("\n⏱️ Time's up! Closing session...");
|
||||
|
||||
if (audioResponse && audioChunks.length > 0) {
|
||||
try {
|
||||
await saveWavFile(audioChunks, "gemini-response.wav");
|
||||
} catch (error) {
|
||||
console.error("❌ Error saving final audio file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
await session.disconnect();
|
||||
isRunning = false;
|
||||
}, 60000);
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
console.log("\n👋 Interrupted by user. Closing session...");
|
||||
|
||||
if (audioResponse && audioChunks.length > 0) {
|
||||
try {
|
||||
await saveWavFile(audioChunks, "gemini-response.wav");
|
||||
} catch (error) {
|
||||
console.error("❌ Error saving final audio file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
await session.disconnect();
|
||||
isRunning = false;
|
||||
});
|
||||
|
||||
const waitForClose = () => {
|
||||
if (isRunning) {
|
||||
setTimeout(waitForClose, 1000);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
};
|
||||
waitForClose();
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("❌ Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,6 +1,8 @@
|
||||
import { mistral } from "@llamaindex/mistral";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const workflow = agent({
|
||||
|
||||
@@ -37,8 +37,10 @@ async function main() {
|
||||
const index = await VectorStoreIndex.init({
|
||||
storageContext,
|
||||
});
|
||||
// topK for text is 0 and for image 1 => we only retrieve one image and no text based on the query
|
||||
const retriever = index.asRetriever({ topK: { TEXT: 0, IMAGE: 1 } });
|
||||
// topK for text is 0, for image 1, for audio 0 => we only retrieve one image and no text based on the query
|
||||
const retriever = index.asRetriever({
|
||||
topK: { TEXT: 0, IMAGE: 1, AUDIO: 0 },
|
||||
});
|
||||
// NOTE: we set the contextRole to "user" (default is "system"). The reason is that GPT-4 does not support
|
||||
// images in a system message
|
||||
const chatEngine = new ContextChatEngine({ retriever, contextRole: "user" });
|
||||
|
||||
@@ -30,7 +30,7 @@ async function main() {
|
||||
|
||||
const queryEngine = index.asQueryEngine({
|
||||
responseSynthesizer: getResponseSynthesizer("multi_modal"),
|
||||
retriever: index.asRetriever({ topK: { TEXT: 3, IMAGE: 1 } }),
|
||||
retriever: index.asRetriever({ topK: { TEXT: 3, IMAGE: 1, AUDIO: 0 } }),
|
||||
});
|
||||
const stream = await queryEngine.query({
|
||||
query: "Tell me more about Vincent van Gogh's famous paintings",
|
||||
|
||||
@@ -12,7 +12,9 @@ async function main() {
|
||||
nodes: [],
|
||||
storageContext,
|
||||
});
|
||||
const retriever = index.asRetriever({ topK: { TEXT: 1, IMAGE: 3 } });
|
||||
const retriever = index.asRetriever({
|
||||
topK: { TEXT: 1, IMAGE: 3, AUDIO: 0 },
|
||||
});
|
||||
const results = await retriever.retrieve({
|
||||
query: "what are Vincent van Gogh's famous paintings",
|
||||
});
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { StartEvent, StopEvent, Workflow } from "llamaindex";
|
||||
|
||||
type ContextData = {
|
||||
counter: number;
|
||||
};
|
||||
|
||||
const contextData: ContextData = { counter: 0 };
|
||||
|
||||
const workflow = new Workflow<ContextData, string, string>();
|
||||
|
||||
workflow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
async (context, startEvent) => {
|
||||
const input = startEvent.data;
|
||||
context.data.counter++;
|
||||
return new StopEvent(`Hello, ${input}!`);
|
||||
},
|
||||
);
|
||||
|
||||
{
|
||||
const ret = await workflow.run("Alex", contextData);
|
||||
console.log(ret.data); // Hello, Alex!
|
||||
}
|
||||
|
||||
{
|
||||
const ret = await workflow.run("World", contextData);
|
||||
console.log(ret.data); // Hello, World!
|
||||
}
|
||||
|
||||
console.log(contextData.counter); // 2
|
||||
@@ -1,7 +1,8 @@
|
||||
import { OpenAI, OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import fs from "fs";
|
||||
|
||||
(async () => {
|
||||
const llm = new OpenAI({ model: "gpt-4.5-preview", temperature: 0.1 });
|
||||
const llm = new OpenAI({ model: "gpt-4o" });
|
||||
|
||||
// complete api
|
||||
const response1 = await llm.complete({ prompt: "How are you?" });
|
||||
@@ -13,7 +14,51 @@ import { OpenAI, OpenAIEmbedding } from "@llamaindex/openai";
|
||||
});
|
||||
console.log(response2.message.content);
|
||||
|
||||
// embeddings
|
||||
// chat with file
|
||||
const response3 = await llm.chat({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What's in this document? Describe it in detail.",
|
||||
},
|
||||
{
|
||||
type: "file",
|
||||
data: new Uint8Array(fs.readFileSync("./data/manga.pdf")),
|
||||
mimeType: "application/pdf",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
console.log(response3.message.content);
|
||||
|
||||
// chat with image
|
||||
const response4 = await llm.chat({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What's in this image? Describe it in detail.",
|
||||
},
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: "https://storage.googleapis.com/cloud-samples-data/vision/face/faces.jpeg",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
console.log("Single Image Analysis:", response4.message.content);
|
||||
|
||||
// // embeddings
|
||||
const embedModel = new OpenAIEmbedding();
|
||||
const texts = ["hello", "world"];
|
||||
const embeddings = await embedModel.getTextEmbeddingsBatch(texts);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { openaiResponses } from "@llamaindex/openai";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { tool } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
const workflow = agent({
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { openaiResponses } from "@llamaindex/openai";
|
||||
import fs from "fs";
|
||||
|
||||
async function main() {
|
||||
if (!process.env.OPENAI_API_KEY) {
|
||||
throw new Error("Please set the OPENAI_API_KEY environment variable.");
|
||||
}
|
||||
|
||||
const llm = openaiResponses({
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
});
|
||||
|
||||
const result = await llm.chat({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What's in this document? Describe it in detail.",
|
||||
},
|
||||
{
|
||||
type: "file",
|
||||
data: Uint8Array.from(fs.readFileSync("./data/manga.pdf")),
|
||||
mimeType: "application/pdf",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
void main().catch(console.error);
|
||||
+46
-46
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/examples",
|
||||
"version": "0.3.10",
|
||||
"version": "0.3.14",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
@@ -11,59 +11,59 @@
|
||||
"@azure/cosmos": "^4.1.1",
|
||||
"@azure/identity": "^4.4.1",
|
||||
"@azure/search-documents": "^12.1.0",
|
||||
"@llamaindex/anthropic": "^0.3.3",
|
||||
"@llamaindex/astra": "^0.0.16",
|
||||
"@llamaindex/azure": "^0.1.12",
|
||||
"@llamaindex/chroma": "^0.0.16",
|
||||
"@llamaindex/clip": "^0.0.52",
|
||||
"@llamaindex/cloud": "^4.0.3",
|
||||
"@llamaindex/cohere": "^0.0.16",
|
||||
"@llamaindex/core": "^0.6.2",
|
||||
"@llamaindex/deepinfra": "^0.0.52",
|
||||
"@llamaindex/env": "^0.1.29",
|
||||
"@llamaindex/firestore": "^1.0.9",
|
||||
"@llamaindex/google": "^0.2.4",
|
||||
"@llamaindex/groq": "^0.0.67",
|
||||
"@llamaindex/huggingface": "^0.1.6",
|
||||
"@llamaindex/milvus": "^0.1.11",
|
||||
"@llamaindex/mistral": "^0.1.2",
|
||||
"@llamaindex/mixedbread": "^0.0.16",
|
||||
"@llamaindex/mongodb": "^0.0.17",
|
||||
"@llamaindex/elastic-search": "^0.1.2",
|
||||
"@llamaindex/node-parser": "^2.0.2",
|
||||
"@llamaindex/ollama": "^0.1.2",
|
||||
"@llamaindex/openai": "^0.3.4",
|
||||
"@llamaindex/pinecone": "^0.1.2",
|
||||
"@llamaindex/portkey-ai": "^0.0.44",
|
||||
"@llamaindex/postgres": "^0.0.45",
|
||||
"@llamaindex/qdrant": "^0.1.11",
|
||||
"@llamaindex/readers": "^3.1.0",
|
||||
"@llamaindex/replicate": "^0.0.44",
|
||||
"@llamaindex/upstash": "^0.0.16",
|
||||
"@llamaindex/vercel": "^0.1.2",
|
||||
"@llamaindex/vllm": "^0.0.38",
|
||||
"@llamaindex/voyage-ai": "^1.0.8",
|
||||
"@llamaindex/weaviate": "^0.0.16",
|
||||
"@llamaindex/workflow": "^1.0.3",
|
||||
"@llamaindex/deepseek": "^0.0.12",
|
||||
"@llamaindex/fireworks": "^0.0.12",
|
||||
"@llamaindex/together": "^0.0.12",
|
||||
"@llamaindex/jinaai": "^0.0.12",
|
||||
"@llamaindex/perplexity": "^0.0.9",
|
||||
"@llamaindex/supabase": "^0.1.1",
|
||||
"@llamaindex/tools": "^0.0.5",
|
||||
"@llamaindex/anthropic": "^0.3.5",
|
||||
"@llamaindex/astra": "^0.0.18",
|
||||
"@llamaindex/azure": "^0.1.14",
|
||||
"@llamaindex/chroma": "^0.0.18",
|
||||
"@llamaindex/clip": "^0.0.54",
|
||||
"@llamaindex/cloud": "^4.0.6",
|
||||
"@llamaindex/cohere": "^0.0.18",
|
||||
"@llamaindex/core": "^0.6.4",
|
||||
"@llamaindex/deepinfra": "^0.0.54",
|
||||
"@llamaindex/env": "^0.1.30",
|
||||
"@llamaindex/firestore": "^1.0.11",
|
||||
"@llamaindex/google": "^0.3.0",
|
||||
"@llamaindex/groq": "^0.0.69",
|
||||
"@llamaindex/huggingface": "^0.1.8",
|
||||
"@llamaindex/milvus": "^0.1.13",
|
||||
"@llamaindex/mistral": "^0.1.4",
|
||||
"@llamaindex/mixedbread": "^0.0.18",
|
||||
"@llamaindex/mongodb": "^0.0.19",
|
||||
"@llamaindex/elastic-search": "^0.1.4",
|
||||
"@llamaindex/node-parser": "^2.0.4",
|
||||
"@llamaindex/ollama": "^0.1.4",
|
||||
"@llamaindex/openai": "^0.3.6",
|
||||
"@llamaindex/pinecone": "^0.1.4",
|
||||
"@llamaindex/portkey-ai": "^0.0.46",
|
||||
"@llamaindex/postgres": "^0.0.47",
|
||||
"@llamaindex/qdrant": "^0.1.13",
|
||||
"@llamaindex/readers": "^3.1.2",
|
||||
"@llamaindex/replicate": "^0.0.46",
|
||||
"@llamaindex/upstash": "^0.0.18",
|
||||
"@llamaindex/vercel": "^0.1.4",
|
||||
"@llamaindex/vllm": "^0.0.40",
|
||||
"@llamaindex/voyage-ai": "^1.0.10",
|
||||
"@llamaindex/weaviate": "^0.0.18",
|
||||
"@llamaindex/workflow": "^1.1.1",
|
||||
"@llamaindex/deepseek": "^0.0.14",
|
||||
"@llamaindex/fireworks": "^0.0.14",
|
||||
"@llamaindex/together": "^0.0.14",
|
||||
"@llamaindex/jinaai": "^0.0.14",
|
||||
"@llamaindex/perplexity": "^0.0.11",
|
||||
"@llamaindex/supabase": "^0.1.3",
|
||||
"@llamaindex/tools": "^0.0.9",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^4.0.0",
|
||||
"@llamaindex/assemblyai": "^0.1.1",
|
||||
"@llamaindex/discord": "^0.1.1",
|
||||
"@llamaindex/notion": "^0.1.1",
|
||||
"@llamaindex/assemblyai": "^0.1.3",
|
||||
"@llamaindex/discord": "^0.1.3",
|
||||
"@llamaindex/notion": "^0.1.3",
|
||||
"@vercel/postgres": "^0.10.0",
|
||||
"ai": "^4.0.0",
|
||||
"ajv": "^8.17.1",
|
||||
"commander": "^12.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"js-tiktoken": "^1.0.14",
|
||||
"llamaindex": "^0.10.2",
|
||||
"llamaindex": "^0.10.5",
|
||||
"mongodb": "6.7.0",
|
||||
"postgres": "^3.4.4",
|
||||
"wikipedia": "^2.1.2",
|
||||
|
||||
@@ -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,157 +0,0 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
HandlerContext,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} from "llamaindex";
|
||||
|
||||
const MAX_REVIEWS = 3;
|
||||
|
||||
type Context = {
|
||||
specification: string;
|
||||
numberReviews: number;
|
||||
};
|
||||
|
||||
// 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: HandlerContext<Context>,
|
||||
_: StartEvent<string>,
|
||||
) => {
|
||||
const spec = context.data.specification;
|
||||
// write a message to send an update to the user
|
||||
context.sendEvent(
|
||||
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: HandlerContext<Context>, ev: ReviewEvent) => {
|
||||
// get the specification from the context
|
||||
const spec = context.data.specification;
|
||||
// get the latest review and code
|
||||
const { review, code } = ev.data;
|
||||
// write a message to send an update to the user
|
||||
context.sendEvent(
|
||||
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: HandlerContext<Context>, ev: CodeEvent) => {
|
||||
// get the specification from the context
|
||||
const spec = context.data.specification;
|
||||
// get latest code from the event
|
||||
const { code } = ev.data;
|
||||
// update and check the number of reviews
|
||||
context.data.numberReviews++;
|
||||
if (context.data.numberReviews > MAX_REVIEWS) {
|
||||
// the we've done this too many times - return the code
|
||||
context.sendEvent(
|
||||
new MessageEvent({
|
||||
msg: `Already reviewed ${
|
||||
context.data.numberReviews - 1
|
||||
} times, stopping!`,
|
||||
}),
|
||||
);
|
||||
return new StopEvent({ result: code });
|
||||
}
|
||||
// write a message to send an update to the user
|
||||
context.sendEvent(
|
||||
new MessageEvent({
|
||||
msg: `Review #${context.data.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.sendEvent(
|
||||
new MessageEvent({
|
||||
msg: `Reviewer says: ${review}`,
|
||||
}),
|
||||
);
|
||||
return new StopEvent({ result: code });
|
||||
}
|
||||
|
||||
return new ReviewEvent({ review, code });
|
||||
};
|
||||
|
||||
const codeAgent = new Workflow<Context, string, string>();
|
||||
codeAgent.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [CodeEvent],
|
||||
},
|
||||
architect,
|
||||
);
|
||||
codeAgent.addStep(
|
||||
{
|
||||
inputs: [ReviewEvent],
|
||||
outputs: [CodeEvent],
|
||||
},
|
||||
coder,
|
||||
);
|
||||
codeAgent.addStep(
|
||||
{
|
||||
inputs: [CodeEvent],
|
||||
outputs: [ReviewEvent, StopEvent],
|
||||
},
|
||||
reviewer,
|
||||
);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const run = codeAgent.run(specification).with({
|
||||
specification,
|
||||
numberReviews: 0,
|
||||
});
|
||||
for await (const event of run) {
|
||||
if (event instanceof MessageEvent) {
|
||||
const msg = (event as MessageEvent).data.msg;
|
||||
console.log(`${msg}\n`);
|
||||
} else if (event instanceof StopEvent) {
|
||||
const result = (event as StopEvent<string>).data;
|
||||
console.log("Final code:\n", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,88 +0,0 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
HandlerContext,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} 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 (_: unknown, ev: StartEvent<string>) => {
|
||||
const prompt = `Write your best joke about ${ev.data}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_: unknown, 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 (_: unknown, 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: HandlerContext,
|
||||
ev1: AnalysisEvent,
|
||||
ev2: CritiqueEvent,
|
||||
) => {
|
||||
const subPrompts = [ev1.data.analysis, ev2.data.critique];
|
||||
|
||||
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(response.text);
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow<unknown, string, string>();
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [JokeEvent],
|
||||
},
|
||||
generateJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [CritiqueEvent],
|
||||
},
|
||||
critiqueJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [AnalysisEvent],
|
||||
},
|
||||
analyzeJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [AnalysisEvent, CritiqueEvent],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
reportJoke,
|
||||
);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,44 +0,0 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { StartEvent, StopEvent, Workflow, WorkflowEvent } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create a custom event type
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
|
||||
const generateJoke = async (_: unknown, ev: StartEvent<string>) => {
|
||||
const prompt = `Write your best joke about ${ev.data}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_: unknown, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent(response.text);
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow<unknown, string, string>();
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [JokeEvent],
|
||||
},
|
||||
generateJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
critiqueJoke,
|
||||
);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const result = await jokeFlow.run("pirates");
|
||||
console.log(result.data);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,66 +0,0 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
HandlerContext,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
WorkflowEvent,
|
||||
} 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: HandlerContext, ev: StartEvent) => {
|
||||
context.sendEvent(
|
||||
new MessageEvent({ msg: `Generating a joke about: ${ev.data}` }),
|
||||
);
|
||||
const prompt = `Write your best joke about ${ev.data}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (context: HandlerContext, ev: JokeEvent) => {
|
||||
context.sendEvent(
|
||||
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(response.text);
|
||||
};
|
||||
|
||||
const jokeFlow = new Workflow();
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [JokeEvent],
|
||||
},
|
||||
generateJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
critiqueJoke,
|
||||
);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const run = jokeFlow.run("pirates");
|
||||
for await (const event of run) {
|
||||
if (event instanceof MessageEvent) {
|
||||
console.log("Message:");
|
||||
console.log((event as MessageEvent).data.msg);
|
||||
} else if (event instanceof StopEvent) {
|
||||
console.log("Result:");
|
||||
console.log((event as StopEvent<string>).data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,48 +0,0 @@
|
||||
import { StartEvent, StopEvent, Workflow } from "llamaindex";
|
||||
|
||||
const longRunning = async (_: unknown, ev: StartEvent<string>) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait for 2 seconds
|
||||
return new StopEvent("We waited 2 seconds");
|
||||
};
|
||||
|
||||
async function timeout() {
|
||||
const workflow = new Workflow<unknown, string, string>({
|
||||
timeout: 1,
|
||||
});
|
||||
workflow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
longRunning,
|
||||
);
|
||||
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<unknown, string, string>({
|
||||
timeout: 3,
|
||||
});
|
||||
workflow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
longRunning,
|
||||
);
|
||||
const result = await workflow.run("Let's start");
|
||||
console.log(result.data);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await timeout();
|
||||
console.log("---");
|
||||
await notimeout();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,73 +0,0 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { StartEvent, StopEvent, Workflow, WorkflowEvent } from "llamaindex";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI();
|
||||
|
||||
// Create a custom event type
|
||||
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
|
||||
|
||||
const generateJoke = async (_: unknown, ev: StartEvent<string>) => {
|
||||
const prompt = `Write your best joke about ${ev.data}.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new JokeEvent({ joke: response.text });
|
||||
};
|
||||
|
||||
const critiqueJoke = async (_: unknown, ev: JokeEvent) => {
|
||||
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
return new StopEvent(response.text);
|
||||
};
|
||||
|
||||
async function validateFails() {
|
||||
try {
|
||||
const jokeFlow = new Workflow();
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
// @ts-expect-error outputs should be JokeEvent
|
||||
generateJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [StopEvent],
|
||||
},
|
||||
critiqueJoke,
|
||||
);
|
||||
await jokeFlow.run("pirates").strict();
|
||||
} catch (e) {
|
||||
console.error("Validation failed:", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function validate() {
|
||||
const jokeFlow = new Workflow();
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [StartEvent<string>],
|
||||
outputs: [JokeEvent],
|
||||
},
|
||||
generateJoke,
|
||||
);
|
||||
jokeFlow.addStep(
|
||||
{
|
||||
inputs: [JokeEvent],
|
||||
outputs: [StopEvent<string>],
|
||||
},
|
||||
critiqueJoke,
|
||||
);
|
||||
const result = await jokeFlow.run("pirates").strict();
|
||||
console.log(result.data);
|
||||
}
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
await validateFails();
|
||||
console.log("---");
|
||||
await validate();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
+3
-2
@@ -15,9 +15,10 @@
|
||||
"circular-check": "madge --circular ./packages/**/**/dist/index.js",
|
||||
"release": "pnpm run build && changeset publish",
|
||||
"release-snapshot": "pnpm run build && changeset publish --tag snapshot",
|
||||
"new-version": "changeset version && pnpm format:write && pnpm run build",
|
||||
"new-version": "changeset version && pnpm postversion && pnpm format:write && pnpm run build",
|
||||
"new-snapshot": "pnpm run build && changeset version --snapshot",
|
||||
"lint-staged": "lint-staged"
|
||||
"lint-staged": "lint-staged",
|
||||
"postversion": "node scripts/repin-workflow.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.27.5",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @llamaindex/autotool
|
||||
|
||||
## 7.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
|
||||
## 7.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 7.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
|
||||
## 7.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @llamaindex/autotool-01-node-example
|
||||
|
||||
## 0.0.106
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.10.5
|
||||
- @llamaindex/autotool@7.0.5
|
||||
|
||||
## 0.0.105
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [41953a3]
|
||||
- llamaindex@0.10.4
|
||||
- @llamaindex/autotool@7.0.4
|
||||
|
||||
## 0.0.104
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- llamaindex@0.10.3
|
||||
- @llamaindex/autotool@7.0.3
|
||||
|
||||
## 0.0.103
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"scripts": {
|
||||
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
|
||||
},
|
||||
"version": "0.0.103"
|
||||
"version": "0.0.106"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"url": "git+https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/autotool"
|
||||
},
|
||||
"version": "7.0.2",
|
||||
"version": "7.0.5",
|
||||
"description": "auto transpile your JS function to LLM Agent compatible",
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
## 4.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9b2e25a]
|
||||
- @llamaindex/core@0.6.4
|
||||
- @llamaindex/env@0.1.30
|
||||
|
||||
## 4.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2225ffd: feat: bump llama cloud sdk
|
||||
|
||||
## 4.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- @llamaindex/core@0.6.3
|
||||
|
||||
## 4.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,15 +2,6 @@
|
||||
|
||||
> LlamaCloud is a new generation of managed parsing, ingestion, and retrieval services, designed to bring production-grade context-augmentation to your LLM and RAG applications.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { OpenAPI } from "@llamaindex/cloud/api";
|
||||
OpenAPI.TOKEN = "YOUR_API_KEY";
|
||||
OpenAPI.BASE = "https://api.cloud.llamaindex.ai/";
|
||||
// ...
|
||||
```
|
||||
|
||||
For more information, see the [API documentation](https://docs.cloud.llamaindex.ai/).
|
||||
|
||||
## License
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import { defineConfig } from "@hey-api/openapi-ts";
|
||||
import { defaultPlugins, defineConfig } from "@hey-api/openapi-ts";
|
||||
|
||||
export default defineConfig({
|
||||
// you can download this file to get the latest version of the OpenAPI document
|
||||
// @link https://api.cloud.llamaindex.ai/api/openapi.json
|
||||
input: "./openapi.json",
|
||||
client: "@hey-api/client-fetch",
|
||||
output: {
|
||||
path: "./src/client",
|
||||
format: "prettier",
|
||||
lint: "eslint",
|
||||
},
|
||||
plugins: [
|
||||
"@hey-api/schemas",
|
||||
"@hey-api/sdk",
|
||||
...defaultPlugins,
|
||||
"@hey-api/client-fetch",
|
||||
{
|
||||
enums: "javascript",
|
||||
identifierCase: "preserve",
|
||||
name: "@hey-api/typescript",
|
||||
name: "@hey-api/sdk",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
+2975
-4384
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloud",
|
||||
"version": "4.0.3",
|
||||
"version": "4.0.6",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -55,8 +55,8 @@
|
||||
"directory": "packages/cloud"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hey-api/client-fetch": "^0.6.0",
|
||||
"@hey-api/openapi-ts": "^0.61.0",
|
||||
"@hey-api/client-fetch": "^0.10.0",
|
||||
"@hey-api/openapi-ts": "^0.66.7",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -1 +1,11 @@
|
||||
import { client } from "./client/client.gen";
|
||||
|
||||
client.setConfig({
|
||||
baseUrl: "https://api.cloud.llamaindex.ai/",
|
||||
headers: {
|
||||
"X-SDK-Name": "llamaindex-ts",
|
||||
},
|
||||
});
|
||||
|
||||
export * from "./client";
|
||||
export { client };
|
||||
|
||||
@@ -4,7 +4,8 @@ import { Document, FileReader } from "@llamaindex/core/schema";
|
||||
import { fs, getEnv, path } from "@llamaindex/env";
|
||||
import pRetry from "p-retry";
|
||||
import {
|
||||
type Body_upload_file_api_v1_parsing_upload_post,
|
||||
type BodyUploadFileApiParsingUploadPost,
|
||||
type FailPageMode,
|
||||
type ParserLanguages,
|
||||
type ParsingMode,
|
||||
getJobApiV1ParsingJobJobIdGet,
|
||||
@@ -162,6 +163,15 @@ export class LlamaParseReader extends FileReader {
|
||||
content_guideline_instruction?: string | undefined;
|
||||
adaptive_long_table?: boolean | undefined;
|
||||
model?: string | undefined;
|
||||
auto_mode_configuration_json?: string | undefined;
|
||||
compact_markdown_table?: boolean | undefined;
|
||||
markdown_table_multiline_header_separator?: string | undefined;
|
||||
page_error_tolerance?: number | undefined;
|
||||
replace_failed_page_mode?: FailPageMode | undefined;
|
||||
replace_failed_page_with_error_message_prefix?: string | undefined;
|
||||
replace_failed_page_with_error_message_suffix?: string | undefined;
|
||||
save_images?: boolean | undefined;
|
||||
preset?: string | undefined;
|
||||
|
||||
constructor(
|
||||
params: Partial<Omit<LlamaParseReader, "language" | "apiKey">> & {
|
||||
@@ -331,11 +341,23 @@ export class LlamaParseReader extends FileReader {
|
||||
content_guideline_instruction: this.content_guideline_instruction,
|
||||
adaptive_long_table: this.adaptive_long_table,
|
||||
model: this.model,
|
||||
auto_mode_configuration_json: this.auto_mode_configuration_json,
|
||||
compact_markdown_table: this.compact_markdown_table,
|
||||
markdown_table_multiline_header_separator:
|
||||
this.markdown_table_multiline_header_separator,
|
||||
page_error_tolerance: this.page_error_tolerance,
|
||||
replace_failed_page_mode: this.replace_failed_page_mode,
|
||||
replace_failed_page_with_error_message_prefix:
|
||||
this.replace_failed_page_with_error_message_prefix,
|
||||
replace_failed_page_with_error_message_suffix:
|
||||
this.replace_failed_page_with_error_message_suffix,
|
||||
save_images: this.save_images,
|
||||
preset: this.preset,
|
||||
} satisfies {
|
||||
[Key in keyof Body_upload_file_api_v1_parsing_upload_post]-?:
|
||||
| Body_upload_file_api_v1_parsing_upload_post[Key]
|
||||
[Key in keyof BodyUploadFileApiParsingUploadPost]-?:
|
||||
| BodyUploadFileApiParsingUploadPost[Key]
|
||||
| undefined;
|
||||
} as unknown as Body_upload_file_api_v1_parsing_upload_post;
|
||||
} as unknown as BodyUploadFileApiParsingUploadPost;
|
||||
|
||||
const response = await uploadFileApiV1ParsingUploadPost({
|
||||
client: this.#client,
|
||||
@@ -382,10 +404,6 @@ export class LlamaParseReader extends FileReader {
|
||||
client: this.#client,
|
||||
throwOnError: true,
|
||||
path: { job_id: jobId },
|
||||
query: {
|
||||
project_id: this.project_id ?? null,
|
||||
organization_id: this.organization_id ?? null,
|
||||
},
|
||||
signal: AbortSignal.timeout(this.maxTimeout * 1000),
|
||||
}),
|
||||
{
|
||||
@@ -431,7 +449,6 @@ export class LlamaParseReader extends FileReader {
|
||||
throwOnError: true,
|
||||
path: { job_id: jobId },
|
||||
query: {
|
||||
project_id: this.project_id ?? null,
|
||||
organization_id: this.organization_id ?? null,
|
||||
},
|
||||
signal: AbortSignal.timeout(this.maxTimeout * 1000),
|
||||
@@ -445,7 +462,6 @@ export class LlamaParseReader extends FileReader {
|
||||
throwOnError: true,
|
||||
path: { job_id: jobId },
|
||||
query: {
|
||||
project_id: this.project_id ?? null,
|
||||
organization_id: this.organization_id ?? null,
|
||||
},
|
||||
signal: AbortSignal.timeout(this.maxTimeout * 1000),
|
||||
@@ -459,7 +475,6 @@ export class LlamaParseReader extends FileReader {
|
||||
throwOnError: true,
|
||||
path: { job_id: jobId },
|
||||
query: {
|
||||
project_id: this.project_id ?? null,
|
||||
organization_id: this.organization_id ?? null,
|
||||
},
|
||||
signal: AbortSignal.timeout(this.maxTimeout * 1000),
|
||||
@@ -689,10 +704,6 @@ export class LlamaParseReader extends FileReader {
|
||||
job_id: jobId,
|
||||
name: imageName,
|
||||
},
|
||||
query: {
|
||||
project_id: this.project_id ?? null,
|
||||
organization_id: this.organization_id ?? null,
|
||||
},
|
||||
});
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to download image: ${response.error.detail}`);
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/community
|
||||
|
||||
## 0.0.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9b2e25a]
|
||||
- @llamaindex/core@0.6.4
|
||||
- @llamaindex/env@0.1.30
|
||||
|
||||
## 0.0.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3ee8c83]
|
||||
- @llamaindex/core@0.6.3
|
||||
|
||||
## 0.0.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/community",
|
||||
"description": "Community package for LlamaIndexTS",
|
||||
"version": "0.0.96",
|
||||
"version": "0.0.98",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user